diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/cpu.c | 34 | ||||
| -rw-r--r-- | kernel/hrtimer.c | 2 | ||||
| -rw-r--r-- | kernel/profile.c | 4 | ||||
| -rw-r--r-- | kernel/rcupdate.c | 2 | ||||
| -rw-r--r-- | kernel/relay.c | 2 | ||||
| -rw-r--r-- | kernel/sched.c | 10 | ||||
| -rw-r--r-- | kernel/softirq.c | 4 | ||||
| -rw-r--r-- | kernel/softlockup.c | 4 | ||||
| -rw-r--r-- | kernel/timer.c | 2 | ||||
| -rw-r--r-- | kernel/workqueue.c | 2 | 
10 files changed, 50 insertions, 16 deletions
diff --git a/kernel/cpu.c b/kernel/cpu.c index 28cb6c71a47..369d2892687 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -120,12 +120,13 @@ static int take_cpu_down(void *unused)  }  /* Requires cpu_add_remove_lock to be held */ -static int _cpu_down(unsigned int cpu) +static int _cpu_down(unsigned int cpu, int tasks_frozen)  {  	int err, nr_calls = 0;  	struct task_struct *p;  	cpumask_t old_allowed, tmp;  	void *hcpu = (void *)(long)cpu; +	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;  	if (num_online_cpus() == 1)  		return -EBUSY; @@ -134,11 +135,11 @@ static int _cpu_down(unsigned int cpu)  		return -EINVAL;  	raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); -	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE, +	err = __raw_notifier_call_chain(&cpu_chain, CPU_DOWN_PREPARE | mod,  					hcpu, -1, &nr_calls);  	if (err == NOTIFY_BAD) { -		__raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, hcpu, -					  nr_calls, NULL); +		__raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod, +					  hcpu, nr_calls, NULL);  		printk("%s: attempt to take down CPU %u failed\n",  				__FUNCTION__, cpu);  		err = -EINVAL; @@ -157,7 +158,7 @@ static int _cpu_down(unsigned int cpu)  	if (IS_ERR(p) || cpu_online(cpu)) {  		/* CPU didn't die: tell everyone.  Can't complain. */ -		if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED, +		if (raw_notifier_call_chain(&cpu_chain, CPU_DOWN_FAILED | mod,  					    hcpu) == NOTIFY_BAD)  			BUG(); @@ -176,7 +177,8 @@ static int _cpu_down(unsigned int cpu)  	__cpu_die(cpu);  	/* CPU is completely dead: tell everyone.  Too late to complain. */ -	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD, hcpu) == NOTIFY_BAD) +	if (raw_notifier_call_chain(&cpu_chain, CPU_DEAD | mod, +				    hcpu) == NOTIFY_BAD)  		BUG();  	check_for_tasks(cpu); @@ -186,8 +188,7 @@ out_thread:  out_allowed:  	set_cpus_allowed(current, old_allowed);  out_release: -	raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, -						(void *)(long)cpu); +	raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu);  	return err;  } @@ -199,7 +200,7 @@ int cpu_down(unsigned int cpu)  	if (cpu_hotplug_disabled)  		err = -EBUSY;  	else -		err = _cpu_down(cpu); +		err = _cpu_down(cpu, 0);  	mutex_unlock(&cpu_add_remove_lock);  	return err; @@ -207,16 +208,17 @@ int cpu_down(unsigned int cpu)  #endif /*CONFIG_HOTPLUG_CPU*/  /* Requires cpu_add_remove_lock to be held */ -static int __cpuinit _cpu_up(unsigned int cpu) +static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen)  {  	int ret, nr_calls = 0;  	void *hcpu = (void *)(long)cpu; +	unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0;  	if (cpu_online(cpu) || !cpu_present(cpu))  		return -EINVAL;  	raw_notifier_call_chain(&cpu_chain, CPU_LOCK_ACQUIRE, hcpu); -	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE, hcpu, +	ret = __raw_notifier_call_chain(&cpu_chain, CPU_UP_PREPARE | mod, hcpu,  							-1, &nr_calls);  	if (ret == NOTIFY_BAD) {  		printk("%s: attempt to bring up CPU %u failed\n", @@ -234,12 +236,12 @@ static int __cpuinit _cpu_up(unsigned int cpu)  	BUG_ON(!cpu_online(cpu));  	/* Now call notifier in preparation. */ -	raw_notifier_call_chain(&cpu_chain, CPU_ONLINE, hcpu); +	raw_notifier_call_chain(&cpu_chain, CPU_ONLINE | mod, hcpu);  out_notify:  	if (ret != 0)  		__raw_notifier_call_chain(&cpu_chain, -				CPU_UP_CANCELED, hcpu, nr_calls, NULL); +				CPU_UP_CANCELED | mod, hcpu, nr_calls, NULL);  	raw_notifier_call_chain(&cpu_chain, CPU_LOCK_RELEASE, hcpu);  	return ret; @@ -253,7 +255,7 @@ int __cpuinit cpu_up(unsigned int cpu)  	if (cpu_hotplug_disabled)  		err = -EBUSY;  	else -		err = _cpu_up(cpu); +		err = _cpu_up(cpu, 0);  	mutex_unlock(&cpu_add_remove_lock);  	return err; @@ -283,7 +285,7 @@ int disable_nonboot_cpus(void)  	for_each_online_cpu(cpu) {  		if (cpu == first_cpu)  			continue; -		error = _cpu_down(cpu); +		error = _cpu_down(cpu, 1);  		if (!error) {  			cpu_set(cpu, frozen_cpus);  			printk("CPU%d is down\n", cpu); @@ -318,7 +320,7 @@ void enable_nonboot_cpus(void)  	suspend_cpu_hotplug = 1;  	printk("Enabling non-boot CPUs ...\n");  	for_each_cpu_mask(cpu, frozen_cpus) { -		error = _cpu_up(cpu); +		error = _cpu_up(cpu, 1);  		if (!error) {  			printk("CPU%d is up\n", cpu);  			continue; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index c9f4f044a8a..23c03f43e19 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1411,11 +1411,13 @@ static int __cpuinit hrtimer_cpu_notify(struct notifier_block *self,  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		init_hrtimers_cpu(cpu);  		break;  #ifdef CONFIG_HOTPLUG_CPU  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		clockevents_notify(CLOCK_EVT_NOTIFY_CPU_DEAD, &cpu);  		migrate_hrtimers(cpu);  		break; diff --git a/kernel/profile.c b/kernel/profile.c index 9bfadb248dd..cc91b9bf759 100644 --- a/kernel/profile.c +++ b/kernel/profile.c @@ -340,6 +340,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		node = cpu_to_node(cpu);  		per_cpu(cpu_profile_flip, cpu) = 0;  		if (!per_cpu(cpu_profile_hits, cpu)[1]) { @@ -365,10 +366,13 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,  		__free_page(page);  		return NOTIFY_BAD;  	case CPU_ONLINE: +	case CPU_ONLINE_FROZEN:  		cpu_set(cpu, prof_cpu_mask);  		break;  	case CPU_UP_CANCELED: +	case CPU_UP_CANCELED_FROZEN:  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		cpu_clear(cpu, prof_cpu_mask);  		if (per_cpu(cpu_profile_hits, cpu)[0]) {  			page = virt_to_page(per_cpu(cpu_profile_hits, cpu)[0]); diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 3554b76da84..2c2dd8410dc 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c @@ -558,9 +558,11 @@ static int __cpuinit rcu_cpu_notify(struct notifier_block *self,  	long cpu = (long)hcpu;  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		rcu_online_cpu(cpu);  		break;  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		rcu_offline_cpu(cpu);  		break;  	default: diff --git a/kernel/relay.c b/kernel/relay.c index e804589c863..61a504900ea 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -484,6 +484,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,  	switch(action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		mutex_lock(&relay_channels_mutex);  		list_for_each_entry(chan, &relay_channels, list) {  			if (chan->buf[hotcpu]) @@ -500,6 +501,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,  		mutex_unlock(&relay_channels_mutex);  		break;  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		/* No need to flush the cpu : will be flushed upon  		 * final relay_flush() call. */  		break; diff --git a/kernel/sched.c b/kernel/sched.c index fe1a9c2b855..799d23b4e35 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -5394,6 +5394,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)  		break;  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		p = kthread_create(migration_thread, hcpu, "migration/%d",cpu);  		if (IS_ERR(p))  			return NOTIFY_BAD; @@ -5407,12 +5408,14 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)  		break;  	case CPU_ONLINE: +	case CPU_ONLINE_FROZEN:  		/* Strictly unneccessary, as first user will wake it. */  		wake_up_process(cpu_rq(cpu)->migration_thread);  		break;  #ifdef CONFIG_HOTPLUG_CPU  	case CPU_UP_CANCELED: +	case CPU_UP_CANCELED_FROZEN:  		if (!cpu_rq(cpu)->migration_thread)  			break;  		/* Unbind it from offline cpu so it can run.  Fall thru. */ @@ -5423,6 +5426,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)  		break;  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		migrate_live_tasks(cpu);  		rq = cpu_rq(cpu);  		kthread_stop(rq->migration_thread); @@ -6912,14 +6916,20 @@ static int update_sched_domains(struct notifier_block *nfb,  {  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  	case CPU_DOWN_PREPARE: +	case CPU_DOWN_PREPARE_FROZEN:  		detach_destroy_domains(&cpu_online_map);  		return NOTIFY_OK;  	case CPU_UP_CANCELED: +	case CPU_UP_CANCELED_FROZEN:  	case CPU_DOWN_FAILED: +	case CPU_DOWN_FAILED_FROZEN:  	case CPU_ONLINE: +	case CPU_ONLINE_FROZEN:  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		/*  		 * Fall through and re-initialise the domains.  		 */ diff --git a/kernel/softirq.c b/kernel/softirq.c index 8b75008e2bd..0b9886a00e7 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -593,6 +593,7 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb,  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu);  		if (IS_ERR(p)) {  			printk("ksoftirqd for %i failed\n", hotcpu); @@ -602,16 +603,19 @@ static int __cpuinit cpu_callback(struct notifier_block *nfb,    		per_cpu(ksoftirqd, hotcpu) = p;   		break;  	case CPU_ONLINE: +	case CPU_ONLINE_FROZEN:  		wake_up_process(per_cpu(ksoftirqd, hotcpu));  		break;  #ifdef CONFIG_HOTPLUG_CPU  	case CPU_UP_CANCELED: +	case CPU_UP_CANCELED_FROZEN:  		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));  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		p = per_cpu(ksoftirqd, hotcpu);  		per_cpu(ksoftirqd, hotcpu) = NULL;  		kthread_stop(p); diff --git a/kernel/softlockup.c b/kernel/softlockup.c index 8fa7040247a..0131e296ffb 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c @@ -146,6 +146,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)  	switch (action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		BUG_ON(per_cpu(watchdog_task, hotcpu));  		p = kthread_create(watchdog, hcpu, "watchdog/%d", hotcpu);  		if (IS_ERR(p)) { @@ -157,16 +158,19 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)  		kthread_bind(p, hotcpu);   		break;  	case CPU_ONLINE: +	case CPU_ONLINE_FROZEN:  		wake_up_process(per_cpu(watchdog_task, hotcpu));  		break;  #ifdef CONFIG_HOTPLUG_CPU  	case CPU_UP_CANCELED: +	case CPU_UP_CANCELED_FROZEN:  		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));  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		p = per_cpu(watchdog_task, hotcpu);  		per_cpu(watchdog_task, hotcpu) = NULL;  		kthread_stop(p); diff --git a/kernel/timer.c b/kernel/timer.c index 58f6dd07c80..de85f8491c1 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -1293,11 +1293,13 @@ static int __cpuinit timer_cpu_notify(struct notifier_block *self,  	long cpu = (long)hcpu;  	switch(action) {  	case CPU_UP_PREPARE: +	case CPU_UP_PREPARE_FROZEN:  		if (init_timers_cpu(cpu) < 0)  			return NOTIFY_BAD;  		break;  #ifdef CONFIG_HOTPLUG_CPU  	case CPU_DEAD: +	case CPU_DEAD_FROZEN:  		migrate_timers(cpu);  		break;  #endif diff --git a/kernel/workqueue.c b/kernel/workqueue.c index b976ed87dd3..fb56fedd5c0 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -799,6 +799,8 @@ static int __devinit workqueue_cpu_callback(struct notifier_block *nfb,  	struct cpu_workqueue_struct *cwq;  	struct workqueue_struct *wq; +	action &= ~CPU_TASKS_FROZEN; +  	switch (action) {  	case CPU_LOCK_ACQUIRE:  		mutex_lock(&workqueue_mutex);  |