[PATCH] cpu hotplug: fix CPU_UP_CANCEL handling
If a cpu hotplug callback fails on CPU_UP_PREPARE, all callbacks will be called with CPU_UP_CANCELED. A few of these callbacks assume that on CPU_UP_PREPARE a pointer to task has been stored in a percpu array. This assumption is not true if CPU_UP_PREPARE fails and the following calls to kthread_bind() in CPU_UP_CANCELED will cause an addressing exception because of passing a NULL pointer. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Ashok Raj <ashok.raj@intel.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
		
				
					committed by
					
						
						Linus Torvalds
					
				
			
			
				
	
			
			
			
						parent
						
							04a3446c90
						
					
				
				
					commit
					fc75cdfa5b
				
			@@ -4756,6 +4756,8 @@ static int migration_call(struct notifier_block *nfb, unsigned long action,
 | 
			
		||||
		break;
 | 
			
		||||
#ifdef CONFIG_HOTPLUG_CPU
 | 
			
		||||
	case CPU_UP_CANCELED:
 | 
			
		||||
		if (!cpu_rq(cpu)->migration_thread)
 | 
			
		||||
			break;
 | 
			
		||||
		/* Unbind it from offline cpu so it can run.  Fall thru. */
 | 
			
		||||
		kthread_bind(cpu_rq(cpu)->migration_thread,
 | 
			
		||||
			     any_online_cpu(cpu_online_map));
 | 
			
		||||
 
 | 
			
		||||
@@ -470,6 +470,8 @@ static int cpu_callback(struct notifier_block *nfb,
 | 
			
		||||
		break;
 | 
			
		||||
#ifdef CONFIG_HOTPLUG_CPU
 | 
			
		||||
	case CPU_UP_CANCELED:
 | 
			
		||||
		if (!per_cpu(ksoftirqd, hotcpu))
 | 
			
		||||
			break;
 | 
			
		||||
		/* Unbind so it can run.  Fall thru. */
 | 
			
		||||
		kthread_bind(per_cpu(ksoftirqd, hotcpu),
 | 
			
		||||
			     any_online_cpu(cpu_online_map));
 | 
			
		||||
 
 | 
			
		||||
@@ -127,6 +127,8 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 | 
			
		||||
		break;
 | 
			
		||||
#ifdef CONFIG_HOTPLUG_CPU
 | 
			
		||||
	case CPU_UP_CANCELED:
 | 
			
		||||
		if (!per_cpu(watchdog_task, hotcpu))
 | 
			
		||||
			break;
 | 
			
		||||
		/* Unbind so it can run.  Fall thru. */
 | 
			
		||||
		kthread_bind(per_cpu(watchdog_task, hotcpu),
 | 
			
		||||
			     any_online_cpu(cpu_online_map));
 | 
			
		||||
 
 | 
			
		||||
@@ -590,6 +590,8 @@ static int workqueue_cpu_callback(struct notifier_block *nfb,
 | 
			
		||||
 | 
			
		||||
	case CPU_UP_CANCELED:
 | 
			
		||||
		list_for_each_entry(wq, &workqueues, list) {
 | 
			
		||||
			if (!per_cpu_ptr(wq->cpu_wq, hotcpu)->thread)
 | 
			
		||||
				continue;
 | 
			
		||||
			/* Unbind so it can run. */
 | 
			
		||||
			kthread_bind(per_cpu_ptr(wq->cpu_wq, hotcpu)->thread,
 | 
			
		||||
				     any_online_cpu(cpu_online_map));
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user