SCHED_RR can context-switch many times without having changed the run-queue. Therefore trying to push on each context switch can just be wasted effort since if it failed the first time, it will likely fail any subsequent times as well. Instead, set a flag when we have successfully pushed as many tasks away as possible, and only clear it when the runqueue adds new tasks (effectively becoming a run-queue "dirty bit"). If new tasks are added we should try again. If any remote run-queues downgrade their priority in the meantime, they will try to pull from us (as they always do). This attempts to address a regression reported by Suresh Siddha, et. al. in the 2.6.25 series. It applies to 2.6.25. Signed-off-by: Gregory Haskins <ghaskins@novell.com> CC: suresh.b.siddha@intel.com CC: mingo@elte.hu CC: rostedt@goodmis.org CC: chinang.ma@intel.com CC: arjan@linux.intel.com CC: willy@linux.intel.com --- kernel/sched.c | 2 ++ kernel/sched_rt.c | 6 +++++- 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/kernel/sched.c b/kernel/sched.c index 8dcdec6..806881b 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -331,6 +331,7 @@ struct rt_rq { #ifdef CONFIG_SMP unsigned long rt_nr_migratory; int overloaded; + int pushed; #endif int rt_throttled; u64 rt_time; @@ -7142,6 +7143,7 @@ static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) #ifdef CONFIG_SMP rt_rq->rt_nr_migratory = 0; rt_rq->overloaded = 0; + rt_rq->pushed = 0; #endif rt_rq->rt_time = 0; diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 0a6d2e5..3828aa7 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c @@ -393,6 +393,8 @@ static void enqueue_task_rt(struct rq *rq, struct task_struct *p, int wakeup) */ for_each_sched_rt_entity(rt_se) enqueue_rt_entity(rt_se); + + rq->rt.pushed = 0; } static void dequeue_task_rt(struct rq *rq, struct task_struct *p, int sleep) @@ -789,7 +791,7 @@ static int push_rt_task(struct rq *rq) int ret = 0; int paranoid = RT_MAX_TRIES; - if (!rq->rt.overloaded) + if (!rq->rt.overloaded || rq->rt.pushed) return 0; next_task = pick_next_highest_task_rt(rq, -1); @@ -863,6 +865,8 @@ static void push_rt_tasks(struct rq *rq) /* push_rt_task will return true if it moved an RT */ while (push_rt_task(rq)) ; + + rq->rt.pushed = 1; } static int pull_rt_task(struct rq *this_rq) --
| Tomasz Kłoczko | Is it time for remove (crap) ALSA from kernel tree ? |
| Aubrey | O_DIRECT question |
| David Miller | Slow DOWN, please!!! |
| Linus Torvalds | Linux 2.6.27-rc8 |
git: | |
| Francis Moreau | emacs and git... |
| Linus Torvalds | I'm a total push-over.. |
| Keith Packard | Re: parsecvs tool now creates git repositories |
| Andreas Hildebrandt | CVS-$Id:$ replacement in git? |
| Jason Dixon | Wasting our Freedom |
| Richard Stallman | Real men don't attack straw men |
| Edwin Eyan Moragas | poll(2) vs kqueue(2) performance |
| James Hartley | scp batch mode? |
| Chris Peterson | [PATCH] drivers/net: remove network drivers' last few uses of IRQF_SAMPLE_RANDOM |
| Karen Xie | [RFC][PATCH 1/1] cxgb3i: cxgb3 iSCSI initiator |
| Lennert Buytenhek | [PATCH 14/39] mv643xx_eth: remove port serial status register bit defines |
| Andrew Morton | Re: [Bugme-new] [Bug 11036] New: atl1 tx busy and hw csum wrong |
| high memory | 2 hours ago | Linux kernel |
| semaphore access speed | 5 hours ago | Applications and Utilities |
| the kernel how to power off the machine | 6 hours ago | Linux kernel |
| Easter Eggs in windows XP | 8 hours ago | Windows |
| Shared swap partition | 9 hours ago | Linux general |
| Root password | 10 hours ago | Linux general |
| Where/when DNOTIFY is used? | 11 hours ago | Linux kernel |
| How to convert Linux Kernel built-in module into a loadable module | 14 hours ago | Linux kernel |
| Linux 2.6.24 and I/O schedulers | 14 hours ago | Linux kernel |
| USB Driver -- Interrupt Polling -- A Little Help Please | 20 hours ago | Linux general |
