diff options
Diffstat (limited to 'drivers/base/cpu.c')
| -rw-r--r-- | drivers/base/cpu.c | 39 | 
1 files changed, 37 insertions, 2 deletions
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index fb10728f637..3d48fc887ef 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -25,6 +25,15 @@ EXPORT_SYMBOL_GPL(cpu_subsys);  static DEFINE_PER_CPU(struct device *, cpu_sys_devices);  #ifdef CONFIG_HOTPLUG_CPU +static void change_cpu_under_node(struct cpu *cpu, +			unsigned int from_nid, unsigned int to_nid) +{ +	int cpuid = cpu->dev.id; +	unregister_cpu_under_node(cpuid, from_nid); +	register_cpu_under_node(cpuid, to_nid); +	cpu->node_id = to_nid; +} +  static ssize_t show_online(struct device *dev,  			   struct device_attribute *attr,  			   char *buf) @@ -39,17 +48,29 @@ static ssize_t __ref store_online(struct device *dev,  				  const char *buf, size_t count)  {  	struct cpu *cpu = container_of(dev, struct cpu, dev); +	int cpuid = cpu->dev.id; +	int from_nid, to_nid;  	ssize_t ret;  	cpu_hotplug_driver_lock();  	switch (buf[0]) {  	case '0': -		ret = cpu_down(cpu->dev.id); +		ret = cpu_down(cpuid);  		if (!ret)  			kobject_uevent(&dev->kobj, KOBJ_OFFLINE);  		break;  	case '1': -		ret = cpu_up(cpu->dev.id); +		from_nid = cpu_to_node(cpuid); +		ret = cpu_up(cpuid); + +		/* +		 * When hot adding memory to memoryless node and enabling a cpu +		 * on the node, node number of the cpu may internally change. +		 */ +		to_nid = cpu_to_node(cpuid); +		if (from_nid != to_nid) +			change_cpu_under_node(cpu, from_nid, to_nid); +  		if (!ret)  			kobject_uevent(&dev->kobj, KOBJ_ONLINE);  		break; @@ -132,6 +153,17 @@ static ssize_t show_crash_notes(struct device *dev, struct device_attribute *att  	return rc;  }  static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL); + +static ssize_t show_crash_notes_size(struct device *dev, +				     struct device_attribute *attr, +				     char *buf) +{ +	ssize_t rc; + +	rc = sprintf(buf, "%zu\n", sizeof(note_buf_t)); +	return rc; +} +static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);  #endif  /* @@ -259,6 +291,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num)  #ifdef CONFIG_KEXEC  	if (!error)  		error = device_create_file(&cpu->dev, &dev_attr_crash_notes); +	if (!error) +		error = device_create_file(&cpu->dev, +					   &dev_attr_crash_notes_size);  #endif  	return error;  }  |