Message ID | 4AAABDF5.4090604@austin.ibm.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
On 254, 09 11, 2009 at 04:15:33PM -0500, Nathan Fontenot wrote: > This adds the capability to DLPAR add and remove CPUs from the kernel. The > creates two new files /sys/devices/system/cpu/probe and > /sys/devices/system/cpu/release to handle the DLPAR addition and > removal of > CPUs respectively. > > CPU DLPAR add is accomplished by writing the drc-index of the CPU to the > probe file, and removal is done by writing the device-tree path of the cpu > to the release file. > > Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> > +static ssize_t cpu_probe_store(struct class *class, const char *buf, > + size_t count) > +{ > + struct device_node *dn; > + u32 drc_index; > + char *cpu_name; > + int rc; > + > + drc_index = simple_strtoull(buf, NULL, 0); > + if (!drc_index) > + return -EINVAL; > + > + rc = acquire_drc(drc_index); > + if (rc) > + return rc; > + > + dn = configure_connector(drc_index); > + if (!dn) { > + release_drc(drc_index); > + return rc; > + } > + > + /* fixup dn name */ > + cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus/") + 1, > + GFP_KERNEL); Unchecked memory allocation with immediate crash in case of failure. > + sprintf(cpu_name, "/cpus/%s", dn->full_name); > + kfree(dn->full_name); > + dn->full_name = cpu_name; > + > + rc = add_device_tree_nodes(dn); > + if (rc) > + release_drc(drc_index); > + > + return rc ? rc : count; > +} > + > +static ssize_t cpu_release_store(struct class *class, const char *buf, > + size_t count) > +{ > + struct device_node *dn; > + u32 *drc_index; > + int rc; > + > + dn = of_find_node_by_path(buf); > + if (!dn) > + return -EINVAL; > + > + drc_index = (u32 *)of_get_property(dn, "ibm,my-drc-index", NULL); > + if (!drc_index) { > + of_node_put(dn); > + return -EINVAL; > + } > + > + rc = release_drc(*drc_index); > + if (rc) { > + of_node_put(dn); > + return rc; > + } > + > + rc = remove_device_tree_nodes(dn); > + if (rc) > + acquire_drc(*drc_index); > + > + of_node_put(dn); > + return rc? rc : count; > +} > + > static struct class_attribute class_attr_mem_release = > __ATTR(release, S_IWUSR, NULL, memory_release_store); > +static struct class_attribute class_attr_cpu_probe = > + __ATTR(probe, S_IWUSR, NULL, cpu_probe_store); > +static struct class_attribute class_attr_cpu_release = > + __ATTR(release, S_IWUSR, NULL, cpu_release_store); > > static int pseries_dlpar_init(void) > { > @@ -576,6 +648,18 @@ > printk(KERN_INFO "DLPAR: Could not create sysfs memory " > "release file\n"); > > + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, > + &class_attr_cpu_probe.attr); > + if (rc) > + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " > + "probe file\n"); > + > + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, > + &class_attr_cpu_release.attr); > + if (rc) > + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " > + "release file\n"); > + > return 0; > } > __initcall(pseries_dlpar_init); > -- > To unsubscribe from this list: send the line "unsubscribe linux-kernel" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ >
Andrey Panin wrote: > On 254, 09 11, 2009 at 04:15:33PM -0500, Nathan Fontenot wrote: >> This adds the capability to DLPAR add and remove CPUs from the kernel. The >> creates two new files /sys/devices/system/cpu/probe and >> /sys/devices/system/cpu/release to handle the DLPAR addition and >> removal of >> CPUs respectively. >> >> CPU DLPAR add is accomplished by writing the drc-index of the CPU to the >> probe file, and removal is done by writing the device-tree path of the cpu >> to the release file. >> >> Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com> > >> +static ssize_t cpu_probe_store(struct class *class, const char *buf, >> + size_t count) >> +{ >> + struct device_node *dn; >> + u32 drc_index; >> + char *cpu_name; >> + int rc; >> + >> + drc_index = simple_strtoull(buf, NULL, 0); >> + if (!drc_index) >> + return -EINVAL; >> + >> + rc = acquire_drc(drc_index); >> + if (rc) >> + return rc; >> + >> + dn = configure_connector(drc_index); >> + if (!dn) { >> + release_drc(drc_index); >> + return rc; >> + } >> + >> + /* fixup dn name */ >> + cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus/") + 1, >> + GFP_KERNEL); > > Unchecked memory allocation with immediate crash in case of failure. Yep, thats a bad thing. I'll fix this in an updated patch. thanks. -Nathan > >> + sprintf(cpu_name, "/cpus/%s", dn->full_name); >> + kfree(dn->full_name); >> + dn->full_name = cpu_name; >> + >> + rc = add_device_tree_nodes(dn); >> + if (rc) >> + release_drc(drc_index); >> + >> + return rc ? rc : count; >> +} >> + >> +static ssize_t cpu_release_store(struct class *class, const char *buf, >> + size_t count) >> +{ >> + struct device_node *dn; >> + u32 *drc_index; >> + int rc; >> + >> + dn = of_find_node_by_path(buf); >> + if (!dn) >> + return -EINVAL; >> + >> + drc_index = (u32 *)of_get_property(dn, "ibm,my-drc-index", NULL); >> + if (!drc_index) { >> + of_node_put(dn); >> + return -EINVAL; >> + } >> + >> + rc = release_drc(*drc_index); >> + if (rc) { >> + of_node_put(dn); >> + return rc; >> + } >> + >> + rc = remove_device_tree_nodes(dn); >> + if (rc) >> + acquire_drc(*drc_index); >> + >> + of_node_put(dn); >> + return rc? rc : count; >> +} >> + >> static struct class_attribute class_attr_mem_release = >> __ATTR(release, S_IWUSR, NULL, memory_release_store); >> +static struct class_attribute class_attr_cpu_probe = >> + __ATTR(probe, S_IWUSR, NULL, cpu_probe_store); >> +static struct class_attribute class_attr_cpu_release = >> + __ATTR(release, S_IWUSR, NULL, cpu_release_store); >> >> static int pseries_dlpar_init(void) >> { >> @@ -576,6 +648,18 @@ >> printk(KERN_INFO "DLPAR: Could not create sysfs memory " >> "release file\n"); >> >> + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, >> + &class_attr_cpu_probe.attr); >> + if (rc) >> + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " >> + "probe file\n"); >> + >> + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, >> + &class_attr_cpu_release.attr); >> + if (rc) >> + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " >> + "release file\n"); >> + >> return 0; >> } >> __initcall(pseries_dlpar_init); >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html >> Please read the FAQ at http://www.tux.org/lkml/ >>
Nathan Fontenot wrote: > +static ssize_t cpu_probe_store(struct class *class, const char *buf, > + size_t count) > +{ > + struct device_node *dn; > + u32 drc_index; > + char *cpu_name; > + int rc; > + > + drc_index = simple_strtoull(buf, NULL, 0); Can just use simple_strtoul here instead. > + if (!drc_index) > + return -EINVAL; > + > + rc = acquire_drc(drc_index); > + if (rc) > + return rc; > + > + dn = configure_connector(drc_index); > + if (!dn) { > + release_drc(drc_index); > + return rc; > + } > + > + /* fixup dn name */ > + cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus/") + 1, > + GFP_KERNEL); > + sprintf(cpu_name, "/cpus/%s", dn->full_name); > + kfree(dn->full_name); > + dn->full_name = cpu_name; > + > + rc = add_device_tree_nodes(dn); > + if (rc) > + release_drc(drc_index); > + > + return rc ? rc : count; > +} > +
Index: powerpc/arch/powerpc/platforms/pseries/dlpar.c =================================================================== --- powerpc.orig/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 13:05:23.000000000 -0500 +++ powerpc/arch/powerpc/platforms/pseries/dlpar.c 2009-09-11 14:10:28.000000000 -0500 @@ -1,11 +1,11 @@ /* - * dlpar.c - support for dynamic reconfiguration (including PCI - * Hotplug and Dynamic Logical Partitioning on RPA platforms). + * dlpar.c - support for dynamic reconfiguration (including PCI, + * Memory, and CPU Hotplug and Dynamic Logical Partitioning on + * PAPR platforms). * * Copyright (C) 2009 Nathan Fontenot * Copyright (C) 2009 IBM Corporation * - * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. @@ -19,6 +19,7 @@ #include <linux/memory_hotplug.h> #include <linux/sysdev.h> #include <linux/sysfs.h> +#include <linux/cpu.h> #include <asm/prom.h> @@ -558,8 +559,79 @@ return rc ? -1 : count; } +static ssize_t cpu_probe_store(struct class *class, const char *buf, + size_t count) +{ + struct device_node *dn; + u32 drc_index; + char *cpu_name; + int rc; + + drc_index = simple_strtoull(buf, NULL, 0); + if (!drc_index) + return -EINVAL; + + rc = acquire_drc(drc_index); + if (rc) + return rc; + + dn = configure_connector(drc_index); + if (!dn) { + release_drc(drc_index); + return rc; + } + + /* fixup dn name */ + cpu_name = kzalloc(strlen(dn->full_name) + strlen("/cpus/") + 1, + GFP_KERNEL); + sprintf(cpu_name, "/cpus/%s", dn->full_name); + kfree(dn->full_name); + dn->full_name = cpu_name; + + rc = add_device_tree_nodes(dn); + if (rc) + release_drc(drc_index); + + return rc ? rc : count; +} + +static ssize_t cpu_release_store(struct class *class, const char *buf, + size_t count) +{ + struct device_node *dn; + u32 *drc_index; + int rc; + + dn = of_find_node_by_path(buf); + if (!dn) + return -EINVAL; + + drc_index = (u32 *)of_get_property(dn, "ibm,my-drc-index", NULL); + if (!drc_index) { + of_node_put(dn); + return -EINVAL; + } + + rc = release_drc(*drc_index); + if (rc) { + of_node_put(dn); + return rc; + } + + rc = remove_device_tree_nodes(dn); + if (rc) + acquire_drc(*drc_index); + + of_node_put(dn); + return rc? rc : count; +} + static struct class_attribute class_attr_mem_release = __ATTR(release, S_IWUSR, NULL, memory_release_store); +static struct class_attribute class_attr_cpu_probe = + __ATTR(probe, S_IWUSR, NULL, cpu_probe_store); +static struct class_attribute class_attr_cpu_release = + __ATTR(release, S_IWUSR, NULL, cpu_release_store); static int pseries_dlpar_init(void) { @@ -576,6 +648,18 @@ printk(KERN_INFO "DLPAR: Could not create sysfs memory " "release file\n"); + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, + &class_attr_cpu_probe.attr); + if (rc) + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " + "probe file\n"); + + rc = sysfs_create_file(&cpu_sysdev_class.kset.kobj, + &class_attr_cpu_release.attr); + if (rc) + printk(KERN_INFO "DLPAR: Could not create sysfs cpu " + "release file\n"); + return 0; } __initcall(pseries_dlpar_init);
This adds the capability to DLPAR add and remove CPUs from the kernel. The creates two new files /sys/devices/system/cpu/probe and /sys/devices/system/cpu/release to handle the DLPAR addition and removal of CPUs respectively. CPU DLPAR add is accomplished by writing the drc-index of the CPU to the probe file, and removal is done by writing the device-tree path of the cpu to the release file. Signed-off-by: Nathan Fontenot <nfont@austin.ibm.com>