2005-04-16 22:20:36 +00:00
|
|
|
/*
|
2007-10-13 01:10:53 +00:00
|
|
|
* Populate sysfs with topology information
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
|
|
|
* Written by: Matthew Dobson, IBM Corporation
|
|
|
|
* Original Code: Paul Dorwin, IBM Corporation, Patrick Mochel, OSDL
|
|
|
|
*
|
|
|
|
* Copyright (C) 2002, IBM Corp.
|
|
|
|
*
|
2006-02-24 21:04:27 +00:00
|
|
|
* All rights reserved.
|
2005-04-16 22:20:36 +00:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
|
|
|
|
* NON INFRINGEMENT. See the GNU General Public License for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*
|
|
|
|
* Send feedback to <colpatch@us.ibm.com>
|
|
|
|
*/
|
|
|
|
#include <linux/nodemask.h>
|
2011-05-26 16:22:53 +00:00
|
|
|
#include <linux/export.h>
|
2006-09-26 08:52:35 +00:00
|
|
|
#include <linux/mmzone.h>
|
2009-03-21 11:25:24 +00:00
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/smp.h>
|
2012-11-13 19:32:40 +00:00
|
|
|
#include <linux/irq.h>
|
2005-04-16 22:20:36 +00:00
|
|
|
#include <asm/cpu.h>
|
|
|
|
|
2008-01-30 12:33:11 +00:00
|
|
|
static DEFINE_PER_CPU(struct x86_cpu, cpu_devices);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2008-01-30 12:33:37 +00:00
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
2012-11-13 19:32:40 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_BOOTPARAM_HOTPLUG_CPU0
|
|
|
|
static int cpu0_hotpluggable = 1;
|
|
|
|
#else
|
|
|
|
static int cpu0_hotpluggable;
|
|
|
|
static int __init enable_cpu0_hotplug(char *str)
|
|
|
|
{
|
|
|
|
cpu0_hotpluggable = 1;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
__setup("cpu0_hotplug", enable_cpu0_hotplug);
|
|
|
|
#endif
|
|
|
|
|
2012-11-13 19:32:51 +00:00
|
|
|
#ifdef CONFIG_DEBUG_HOTPLUG_CPU0
|
|
|
|
/*
|
|
|
|
* This function offlines a CPU as early as possible and allows userspace to
|
|
|
|
* boot up without the CPU. The CPU can be onlined back by user after boot.
|
|
|
|
*
|
|
|
|
* This is only called for debugging CPU offline/online feature.
|
|
|
|
*/
|
|
|
|
int __ref _debug_hotplug_cpu(int cpu, int action)
|
|
|
|
{
|
|
|
|
struct device *dev = get_cpu_device(cpu);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!cpu_is_hotpluggable(cpu))
|
|
|
|
return -EINVAL;
|
|
|
|
|
2013-08-30 00:22:07 +00:00
|
|
|
lock_device_hotplug();
|
2012-11-13 19:32:51 +00:00
|
|
|
cpu_hotplug_driver_lock();
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
case 0:
|
|
|
|
ret = cpu_down(cpu);
|
|
|
|
if (!ret) {
|
|
|
|
pr_info("CPU %u is now offline\n", cpu);
|
2013-08-30 00:22:06 +00:00
|
|
|
dev->offline = true;
|
2012-11-13 19:32:51 +00:00
|
|
|
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
|
|
|
|
} else
|
|
|
|
pr_debug("Can't offline CPU%d.\n", cpu);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
ret = cpu_up(cpu);
|
2013-08-30 00:22:06 +00:00
|
|
|
if (!ret) {
|
|
|
|
dev->offline = false;
|
2012-11-13 19:32:51 +00:00
|
|
|
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
|
2013-08-30 00:22:06 +00:00
|
|
|
} else {
|
2012-11-13 19:32:51 +00:00
|
|
|
pr_debug("Can't online CPU%d.\n", cpu);
|
2013-08-30 00:22:06 +00:00
|
|
|
}
|
2012-11-13 19:32:51 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ret = -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu_hotplug_driver_unlock();
|
2013-08-30 00:22:07 +00:00
|
|
|
unlock_device_hotplug();
|
2012-11-13 19:32:51 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __init debug_hotplug_cpu(void)
|
|
|
|
{
|
|
|
|
_debug_hotplug_cpu(0, 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
late_initcall_sync(debug_hotplug_cpu);
|
|
|
|
#endif /* CONFIG_DEBUG_HOTPLUG_CPU0 */
|
|
|
|
|
2008-02-17 12:22:49 +00:00
|
|
|
int __ref arch_register_cpu(int num)
|
[PATCH] node hotplug: register cpu: remove node struct
With Goto-san's patch, we can add new pgdat/node at runtime. I'm now
considering node-hot-add with cpu + memory on ACPI.
I found acpi container, which describes node, could evaluate cpu before
memory. This means cpu-hot-add occurs before memory hot add.
In most part, cpu-hot-add doesn't depend on node hot add. But register_cpu(),
which creates symbolic link from node to cpu, requires that node should be
onlined before register_cpu(). When a node is onlined, its pgdat should be
there.
This patch-set holds off creating symbolic link from node to cpu
until node is onlined.
This removes node arguments from register_cpu().
Now, register_cpu() requires 'struct node' as its argument. But the array of
struct node is now unified in driver/base/node.c now (By Goto's node hotplug
patch). We can get struct node in generic way. So, this argument is not
necessary now.
This patch also guarantees add cpu under node only when node is onlined. It
is necessary for node-hot-add vs. cpu-hot-add patch following this.
Moreover, register_cpu calculates cpu->node_id by cpu_to_node() without regard
to its 'struct node *root' argument. This patch removes it.
Also modify callers of register_cpu()/unregister_cpu, whose args are changed
by register-cpu-remove-node-struct patch.
[Brice.Goglin@ens-lyon.org: fix it]
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Yasunori Goto <y-goto@jp.fujitsu.com>
Cc: Ashok Raj <ashok.raj@intel.com>
Cc: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Brice Goglin <Brice.Goglin@ens-lyon.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2006-06-27 09:53:41 +00:00
|
|
|
{
|
2012-11-13 19:32:40 +00:00
|
|
|
struct cpuinfo_x86 *c = &cpu_data(num);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Currently CPU0 is only hotpluggable on Intel platforms. Other
|
|
|
|
* vendors can add hotplug support later.
|
|
|
|
*/
|
|
|
|
if (c->x86_vendor != X86_VENDOR_INTEL)
|
|
|
|
cpu0_hotpluggable = 0;
|
|
|
|
|
2006-03-23 10:59:57 +00:00
|
|
|
/*
|
2012-11-13 19:32:40 +00:00
|
|
|
* Two known BSP/CPU0 dependencies: Resume from suspend/hibernate
|
|
|
|
* depends on BSP. PIC interrupts depend on BSP.
|
2006-12-07 01:14:10 +00:00
|
|
|
*
|
2012-11-13 19:32:40 +00:00
|
|
|
* If the BSP depencies are under control, one can tell kernel to
|
|
|
|
* enable BSP hotplug. This basically adds a control file and
|
|
|
|
* one can attempt to offline BSP.
|
2006-03-23 10:59:57 +00:00
|
|
|
*/
|
2012-11-13 19:32:40 +00:00
|
|
|
if (num == 0 && cpu0_hotpluggable) {
|
|
|
|
unsigned int irq;
|
|
|
|
/*
|
|
|
|
* We won't take down the boot processor on i386 if some
|
|
|
|
* interrupts only are able to be serviced by the BSP in PIC.
|
|
|
|
*/
|
|
|
|
for_each_active_irq(irq) {
|
|
|
|
if (!IO_APIC_IRQ(irq) && irq_has_action(irq)) {
|
|
|
|
cpu0_hotpluggable = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (num || cpu0_hotpluggable)
|
2008-01-30 12:33:11 +00:00
|
|
|
per_cpu(cpu_devices, num).cpu.hotpluggable = 1;
|
2009-03-21 11:25:24 +00:00
|
|
|
|
2008-01-30 12:33:11 +00:00
|
|
|
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
2008-01-30 12:33:37 +00:00
|
|
|
EXPORT_SYMBOL(arch_register_cpu);
|
2005-04-16 22:20:36 +00:00
|
|
|
|
2007-12-04 16:19:07 +00:00
|
|
|
void arch_unregister_cpu(int num)
|
|
|
|
{
|
2008-02-09 22:24:08 +00:00
|
|
|
unregister_cpu(&per_cpu(cpu_devices, num).cpu);
|
2005-04-16 22:20:36 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(arch_unregister_cpu);
|
2009-03-21 11:25:24 +00:00
|
|
|
#else /* CONFIG_HOTPLUG_CPU */
|
|
|
|
|
2008-02-01 16:49:43 +00:00
|
|
|
static int __init arch_register_cpu(int num)
|
2008-01-30 12:33:37 +00:00
|
|
|
{
|
|
|
|
return register_cpu(&per_cpu(cpu_devices, num).cpu, num);
|
|
|
|
}
|
2009-03-21 11:25:24 +00:00
|
|
|
#endif /* CONFIG_HOTPLUG_CPU */
|
2005-04-16 22:20:36 +00:00
|
|
|
|
|
|
|
static int __init topology_init(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2006-09-26 08:52:35 +00:00
|
|
|
#ifdef CONFIG_NUMA
|
2005-06-25 21:55:00 +00:00
|
|
|
for_each_online_node(i)
|
2006-06-27 09:53:38 +00:00
|
|
|
register_one_node(i);
|
2009-03-21 11:25:24 +00:00
|
|
|
#endif
|
2005-06-25 21:55:00 +00:00
|
|
|
|
2005-09-06 22:16:19 +00:00
|
|
|
for_each_present_cpu(i)
|
2005-06-25 21:55:00 +00:00
|
|
|
arch_register_cpu(i);
|
2009-03-21 11:25:24 +00:00
|
|
|
|
2005-04-16 22:20:36 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
subsys_initcall(topology_init);
|