On Mon, Dec 10, 2007 at 10:10:52AM +0100, Ingo Molnar wrote:In this particular case, we are trying to see if any task on a particular cpu has not been scheduled for a really long time. If we do this check on a cpu which has gone offline, then a) If the tasks have not been migrated on to another cpu yet, we will still perform that check and yell if something has been holding any task for a sufficiently long time. b) If the tasks have been migrated off, then we have nothing to check. However, if we still want that particular cpu to not go offline during the check, then could we use the following patch commit a49736844717e00f7a37c96368cea8fec7eb31cf Author: Gautham R Shenoy <ego@in.ibm.com> Date: Mon Dec 10 15:43:32 2007 +0530 CPU-Hotplug: Add try_get_online_cpus() Add the fastpath code, try_get_online_cpus() which will return 1 once it has managed to hold the reference to the cpu_online_map if there are no threads trying to perform a cpu-hotplug. Use the primitive in the softlockup code. Signed-off-by: Gautham R Shenoy <ego@in.ibm.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Thomas Gleixner <tglx@linuxtronix.de> Cc: Jiri Slaby <jirislaby@gmail.com> diff --git a/include/linux/cpu.h b/include/linux/cpu.h index e0132cb..d236e21 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -107,6 +107,7 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) } extern void get_online_cpus(void); +extern int try_get_online_cpus(void); extern void put_online_cpus(void); #define hotcpu_notifier(fn, pri) { \ static struct notifier_block fn##_nb = \ @@ -127,6 +128,9 @@ static inline void cpuhotplug_mutex_unlock(struct mutex *cpu_hp_mutex) #define get_online_cpus() do { } while (0) #define put_online_cpus() do { } while (0) +static inline int try_get_online_cpus(void) +{ return 1;} + #define hotcpu_notifier(fn, pri) do { (void)(fn); } while (0) /* These aren't inline functions due to a GCC bug. */ #define register_hotcpu_notifier(nb) ({ (void)(nb); 0; }) diff --git a/kernel/cpu.c b/kernel/cpu.c index e0d3a4f..38537c9 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -48,11 +48,35 @@ void __init cpu_hotplug_init(void) #ifdef CONFIG_HOTPLUG_CPU +/* + * try_get_online_cpus(): Tries to hold a reference + * to the cpu_online_map if no one is trying to perform + * a cpu-hotplug operation. This is the fastpath code for + * get_online_cpus. + * + * Returns 1 if there is no cpu-hotplug operation + * currently in progress. + */ +int try_get_online_cpus(void) +{ + if(!cpu_hotplug.active_writer) { + cpu_hotplug.refcount++; + return 1; + } + + return 0; +} +EXPORT_SYMBOL_GPL(try_get_online_cpus); + void get_online_cpus(void) { might_sleep(); if (cpu_hotplug.active_writer == current) return; + if (try_get_online_cpus()) + return; + + /* The writer exists, hence the slowpath */ mutex_lock(&cpu_hotplug.lock); cpu_hotplug.refcount++; mutex_unlock(&cpu_hotplug.lock); @@ -120,6 +144,11 @@ static void cpu_hotplug_begin(void) mutex_lock(&cpu_hotplug.lock); cpu_hotplug.active_writer = current; + synchronize_sched(); + /* New users of get_online_cpus() will see a non-NULL value + * for cpu_hotplug.active_writer here and will take the slowpath + */ + add_wait_queue_exclusive(&cpu_hotplug.writer_queue, &wait); while (cpu_hotplug.refcount) { set_current_state(TASK_UNINTERRUPTIBLE); diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 576eb9c..cb0616d 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -150,8 +150,8 @@ static void check_hung_task(struct task_struct *t, unsigned long now) sysctl_hung_task_warnings--; /* - * Ok, the task did not get scheduled for more than 2 minutes, - * complain: + * Ok, the task did not get scheduled for more than + * sysctl_hung_task_timeout_secs, complain: */ printk(KERN_ERR "INFO: task %s:%d blocked for more than " "%ld seconds.\n", t->comm, t->pid, @@ -216,16 +216,21 @@ static int watchdog(void *__bind_cpu) touch_softlockup_watchdog(); msleep_interruptible(10000); + /* + * If a cpu-hotplug operation is in progress + * we can come back later + */ + if (!try_get_online_cpus()) + continue; /* * Only do the hung-tasks check on one CPU: */ check_cpu = any_online_cpu(cpu_online_map); - if (this_cpu != check_cpu) - continue; - - if (sysctl_hung_task_timeout_secs) + if ((this_cpu == check_cpu) && sysctl_hung_task_timeout_secs) check_hung_uninterruptible_tasks(this_cpu); + + put_online_cpus(); } return 0; -- Gautham R Shenoy Linux Technology Center IBM India. "Freedom comes with a price tag of responsibility, which is still a bargain, because Freedom is priceless!" --
| Alan | Re: [RFC] Heads up on sys_fallocate() |
| Rafael J. Wysocki | [Bug #11215] INFO: possible recursive locking detected ps2_command |
| Con Kolivas | Re: -mm merge plans for 2.6.23 |
| Mike Galbraith | Re: regression: CD burning (k3b) went broke |
git: | |
| Andy Parkins | svn:externals using git submodules |
| Jeff King | Re: Terminology question about remote branches. |
| Jon Smirl | ! [rejected] master -> master (non-fast forward) |
| Miles Bader | "git pull REMOTE" question |
| Richard Stallman | Real men don't attack straw men |
| Ari Constancio | Re: Squid/authpf with lookups on Active Directory |
| GVG GVG | ssh_exchange_identification: Connection closed by remote host |
| Michael | Performance: OpenVPN vs IPsec |
| Gerrit Renker | [PATCH 0/37] dccp: Feature negotiation - last call for comments |
| David Miller | Re: [PATCH] pkt_sched: Destroy gen estimators under rtnl_lock(). |
| Andrew Morton | Re: [Bugme-new] [Bug 11144] New: dhcp doesn't work with iwl4965 |
| David Miller | Re: xfrm_state locking regression... |
