linux/drivers/base/cpu.c
<<
>>
Prefs
   1/*
   2 * CPU subsystem support
   3 */
   4
   5#include <linux/kernel.h>
   6#include <linux/module.h>
   7#include <linux/init.h>
   8#include <linux/sched.h>
   9#include <linux/cpu.h>
  10#include <linux/topology.h>
  11#include <linux/device.h>
  12#include <linux/node.h>
  13#include <linux/gfp.h>
  14#include <linux/slab.h>
  15#include <linux/percpu.h>
  16#include <linux/acpi.h>
  17#include <linux/of.h>
  18
  19#include "base.h"
  20
  21static DEFINE_PER_CPU(struct device *, cpu_sys_devices);
  22
  23static int cpu_subsys_match(struct device *dev, struct device_driver *drv)
  24{
  25        /* ACPI style match is the only one that may succeed. */
  26        if (acpi_driver_match_device(dev, drv))
  27                return 1;
  28
  29        return 0;
  30}
  31
  32#ifdef CONFIG_HOTPLUG_CPU
  33static void change_cpu_under_node(struct cpu *cpu,
  34                        unsigned int from_nid, unsigned int to_nid)
  35{
  36        int cpuid = cpu->dev.id;
  37        unregister_cpu_under_node(cpuid, from_nid);
  38        register_cpu_under_node(cpuid, to_nid);
  39        cpu->node_id = to_nid;
  40}
  41
  42static int __ref cpu_subsys_online(struct device *dev)
  43{
  44        struct cpu *cpu = container_of(dev, struct cpu, dev);
  45        int cpuid = dev->id;
  46        int from_nid, to_nid;
  47        int ret;
  48
  49        from_nid = cpu_to_node(cpuid);
  50        if (from_nid == NUMA_NO_NODE)
  51                return -ENODEV;
  52
  53        ret = cpu_up(cpuid);
  54        /*
  55         * When hot adding memory to memoryless node and enabling a cpu
  56         * on the node, node number of the cpu may internally change.
  57         */
  58        to_nid = cpu_to_node(cpuid);
  59        if (from_nid != to_nid)
  60                change_cpu_under_node(cpu, from_nid, to_nid);
  61
  62        return ret;
  63}
  64
  65static int cpu_subsys_offline(struct device *dev)
  66{
  67        return cpu_down(dev->id);
  68}
  69
  70void unregister_cpu(struct cpu *cpu)
  71{
  72        int logical_cpu = cpu->dev.id;
  73
  74        unregister_cpu_under_node(logical_cpu, cpu_to_node(logical_cpu));
  75
  76        device_unregister(&cpu->dev);
  77        per_cpu(cpu_sys_devices, logical_cpu) = NULL;
  78        return;
  79}
  80
  81#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
  82static ssize_t cpu_probe_store(struct device *dev,
  83                               struct device_attribute *attr,
  84                               const char *buf,
  85                               size_t count)
  86{
  87        ssize_t cnt;
  88        int ret;
  89
  90        ret = lock_device_hotplug_sysfs();
  91        if (ret)
  92                return ret;
  93
  94        cnt = arch_cpu_probe(buf, count);
  95
  96        unlock_device_hotplug();
  97        return cnt;
  98}
  99
 100static ssize_t cpu_release_store(struct device *dev,
 101                                 struct device_attribute *attr,
 102                                 const char *buf,
 103                                 size_t count)
 104{
 105        ssize_t cnt;
 106        int ret;
 107
 108        ret = lock_device_hotplug_sysfs();
 109        if (ret)
 110                return ret;
 111
 112        cnt = arch_cpu_release(buf, count);
 113
 114        unlock_device_hotplug();
 115        return cnt;
 116}
 117
 118static DEVICE_ATTR(probe, S_IWUSR, NULL, cpu_probe_store);
 119static DEVICE_ATTR(release, S_IWUSR, NULL, cpu_release_store);
 120#endif /* CONFIG_ARCH_CPU_PROBE_RELEASE */
 121#endif /* CONFIG_HOTPLUG_CPU */
 122
 123struct bus_type cpu_subsys = {
 124        .name = "cpu",
 125        .dev_name = "cpu",
 126        .match = cpu_subsys_match,
 127#ifdef CONFIG_HOTPLUG_CPU
 128        .online = cpu_subsys_online,
 129        .offline = cpu_subsys_offline,
 130#endif
 131};
 132EXPORT_SYMBOL_GPL(cpu_subsys);
 133
 134#ifdef CONFIG_KEXEC
 135#include <linux/kexec.h>
 136
 137static ssize_t show_crash_notes(struct device *dev, struct device_attribute *attr,
 138                                char *buf)
 139{
 140        struct cpu *cpu = container_of(dev, struct cpu, dev);
 141        ssize_t rc;
 142        unsigned long long addr;
 143        int cpunum;
 144
 145        cpunum = cpu->dev.id;
 146
 147        /*
 148         * Might be reading other cpu's data based on which cpu read thread
 149         * has been scheduled. But cpu data (memory) is allocated once during
 150         * boot up and this data does not change there after. Hence this
 151         * operation should be safe. No locking required.
 152         */
 153        addr = per_cpu_ptr_to_phys(per_cpu_ptr(crash_notes, cpunum));
 154        rc = sprintf(buf, "%Lx\n", addr);
 155        return rc;
 156}
 157static DEVICE_ATTR(crash_notes, 0400, show_crash_notes, NULL);
 158
 159static ssize_t show_crash_notes_size(struct device *dev,
 160                                     struct device_attribute *attr,
 161                                     char *buf)
 162{
 163        ssize_t rc;
 164
 165        rc = sprintf(buf, "%zu\n", sizeof(note_buf_t));
 166        return rc;
 167}
 168static DEVICE_ATTR(crash_notes_size, 0400, show_crash_notes_size, NULL);
 169
 170static struct attribute *crash_note_cpu_attrs[] = {
 171        &dev_attr_crash_notes.attr,
 172        &dev_attr_crash_notes_size.attr,
 173        NULL
 174};
 175
 176static struct attribute_group crash_note_cpu_attr_group = {
 177        .attrs = crash_note_cpu_attrs,
 178};
 179#endif
 180
 181static const struct attribute_group *common_cpu_attr_groups[] = {
 182#ifdef CONFIG_KEXEC
 183        &crash_note_cpu_attr_group,
 184#endif
 185        NULL
 186};
 187
 188static const struct attribute_group *hotplugable_cpu_attr_groups[] = {
 189#ifdef CONFIG_KEXEC
 190        &crash_note_cpu_attr_group,
 191#endif
 192        NULL
 193};
 194
 195/*
 196 * Print cpu online, possible, present, and system maps
 197 */
 198
 199struct cpu_attr {
 200        struct device_attribute attr;
 201        const struct cpumask *const * const map;
 202};
 203
 204static ssize_t show_cpus_attr(struct device *dev,
 205                              struct device_attribute *attr,
 206                              char *buf)
 207{
 208        struct cpu_attr *ca = container_of(attr, struct cpu_attr, attr);
 209        int n = cpulist_scnprintf(buf, PAGE_SIZE-2, *(ca->map));
 210
 211        buf[n++] = '\n';
 212        buf[n] = '\0';
 213        return n;
 214}
 215
 216#define _CPU_ATTR(name, map) \
 217        { __ATTR(name, 0444, show_cpus_attr, NULL), map }
 218
 219/* Keep in sync with cpu_subsys_attrs */
 220static struct cpu_attr cpu_attrs[] = {
 221        _CPU_ATTR(online, &cpu_online_mask),
 222        _CPU_ATTR(possible, &cpu_possible_mask),
 223        _CPU_ATTR(present, &cpu_present_mask),
 224};
 225
 226/*
 227 * Print values for NR_CPUS and offlined cpus
 228 */
 229static ssize_t print_cpus_kernel_max(struct device *dev,
 230                                     struct device_attribute *attr, char *buf)
 231{
 232        int n = snprintf(buf, PAGE_SIZE-2, "%d\n", NR_CPUS - 1);
 233        return n;
 234}
 235static DEVICE_ATTR(kernel_max, 0444, print_cpus_kernel_max, NULL);
 236
 237/* arch-optional setting to enable display of offline cpus >= nr_cpu_ids */
 238unsigned int total_cpus;
 239
 240static ssize_t print_cpus_offline(struct device *dev,
 241                                  struct device_attribute *attr, char *buf)
 242{
 243        int n = 0, len = PAGE_SIZE-2;
 244        cpumask_var_t offline;
 245
 246        /* display offline cpus < nr_cpu_ids */
 247        if (!alloc_cpumask_var(&offline, GFP_KERNEL))
 248                return -ENOMEM;
 249        cpumask_andnot(offline, cpu_possible_mask, cpu_online_mask);
 250        n = cpulist_scnprintf(buf, len, offline);
 251        free_cpumask_var(offline);
 252
 253        /* display offline cpus >= nr_cpu_ids */
 254        if (total_cpus && nr_cpu_ids < total_cpus) {
 255                if (n && n < len)
 256                        buf[n++] = ',';
 257
 258                if (nr_cpu_ids == total_cpus-1)
 259                        n += snprintf(&buf[n], len - n, "%d", nr_cpu_ids);
 260                else
 261                        n += snprintf(&buf[n], len - n, "%d-%d",
 262                                                      nr_cpu_ids, total_cpus-1);
 263        }
 264
 265        n += snprintf(&buf[n], len - n, "\n");
 266        return n;
 267}
 268static DEVICE_ATTR(offline, 0444, print_cpus_offline, NULL);
 269
 270static void cpu_device_release(struct device *dev)
 271{
 272        /*
 273         * This is an empty function to prevent the driver core from spitting a
 274         * warning at us.  Yes, I know this is directly opposite of what the
 275         * documentation for the driver core and kobjects say, and the author
 276         * of this code has already been publically ridiculed for doing
 277         * something as foolish as this.  However, at this point in time, it is
 278         * the only way to handle the issue of statically allocated cpu
 279         * devices.  The different architectures will have their cpu device
 280         * code reworked to properly handle this in the near future, so this
 281         * function will then be changed to correctly free up the memory held
 282         * by the cpu device.
 283         *
 284         * Never copy this way of doing things, or you too will be made fun of
 285         * on the linux-kernel list, you have been warned.
 286         */
 287}
 288
 289/*
 290 * register_cpu - Setup a sysfs device for a CPU.
 291 * @cpu - cpu->hotpluggable field set to 1 will generate a control file in
 292 *        sysfs for this CPU.
 293 * @num - CPU number to use when creating the device.
 294 *
 295 * Initialize and register the CPU device.
 296 */
 297int register_cpu(struct cpu *cpu, int num)
 298{
 299        int error;
 300
 301        cpu->node_id = cpu_to_node(num);
 302        memset(&cpu->dev, 0x00, sizeof(struct device));
 303        cpu->dev.id = num;
 304        cpu->dev.bus = &cpu_subsys;
 305        cpu->dev.release = cpu_device_release;
 306        cpu->dev.offline_disabled = !cpu->hotpluggable;
 307        cpu->dev.offline = !cpu_online(num);
 308        cpu->dev.of_node = of_get_cpu_node(num, NULL);
 309#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
 310        cpu->dev.bus->uevent = arch_cpu_uevent;
 311#endif
 312        cpu->dev.groups = common_cpu_attr_groups;
 313        if (cpu->hotpluggable)
 314                cpu->dev.groups = hotplugable_cpu_attr_groups;
 315        error = device_register(&cpu->dev);
 316        if (!error)
 317                per_cpu(cpu_sys_devices, num) = &cpu->dev;
 318        if (!error)
 319                register_cpu_under_node(num, cpu_to_node(num));
 320
 321        return error;
 322}
 323
 324struct device *get_cpu_device(unsigned cpu)
 325{
 326        if (cpu < nr_cpu_ids && cpu_possible(cpu))
 327                return per_cpu(cpu_sys_devices, cpu);
 328        else
 329                return NULL;
 330}
 331EXPORT_SYMBOL_GPL(get_cpu_device);
 332
 333#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
 334static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL);
 335#endif
 336
 337static struct attribute *cpu_root_attrs[] = {
 338#ifdef CONFIG_ARCH_CPU_PROBE_RELEASE
 339        &dev_attr_probe.attr,
 340        &dev_attr_release.attr,
 341#endif
 342        &cpu_attrs[0].attr.attr,
 343        &cpu_attrs[1].attr.attr,
 344        &cpu_attrs[2].attr.attr,
 345        &dev_attr_kernel_max.attr,
 346        &dev_attr_offline.attr,
 347#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE
 348        &dev_attr_modalias.attr,
 349#endif
 350        NULL
 351};
 352
 353static struct attribute_group cpu_root_attr_group = {
 354        .attrs = cpu_root_attrs,
 355};
 356
 357static const struct attribute_group *cpu_root_attr_groups[] = {
 358        &cpu_root_attr_group,
 359        NULL,
 360};
 361
 362bool cpu_is_hotpluggable(unsigned cpu)
 363{
 364        struct device *dev = get_cpu_device(cpu);
 365        return dev && container_of(dev, struct cpu, dev)->hotpluggable;
 366}
 367EXPORT_SYMBOL_GPL(cpu_is_hotpluggable);
 368
 369#ifdef CONFIG_GENERIC_CPU_DEVICES
 370static DEFINE_PER_CPU(struct cpu, cpu_devices);
 371#endif
 372
 373static void __init cpu_dev_register_generic(void)
 374{
 375#ifdef CONFIG_GENERIC_CPU_DEVICES
 376        int i;
 377
 378        for_each_possible_cpu(i) {
 379                if (register_cpu(&per_cpu(cpu_devices, i), i))
 380                        panic("Failed to register CPU device");
 381        }
 382#endif
 383}
 384
 385void __init cpu_dev_init(void)
 386{
 387        if (subsys_system_register(&cpu_subsys, cpu_root_attr_groups))
 388                panic("Failed to register CPU subsystem");
 389
 390        cpu_dev_register_generic();
 391}
 392