Name: Driverfs CPU Controls Author: Rusty Russell Status: Experimental Depends: Depends: Depends: D: This adds an online element into the cpu driverfs entries, which D: allows them to be brought on and offline. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .3214-linux-2.5.46/drivers/base/cpu.c .3214-linux-2.5.46.updated/drivers/base/cpu.c --- .3214-linux-2.5.46/drivers/base/cpu.c 2002-11-05 10:54:25.000000000 +1100 +++ .3214-linux-2.5.46.updated/drivers/base/cpu.c 2002-11-05 16:34:11.000000000 +1100 @@ -26,6 +26,50 @@ struct device_driver cpu_driver = { .devclass = &cpu_devclass, }; +static ssize_t show_online(struct device *dev, + char *buf, + size_t count, + loff_t off) +{ + char out[3]; + struct cpu *cpu = container_of(container_of(dev,struct sys_device,dev), + struct cpu, sysdev); + + sprintf(out, "%i\n", !!cpu_online(cpu->sysdev.id)); + if (off >= strlen(out)) return 0; + if (off + count > strlen(out)) count = strlen(out) - off; + memcpy(buf, out+off, count); + return (ssize_t)count; +} + +static ssize_t store_online(struct device *dev, + const char *buf, + size_t count, + loff_t off) +{ + struct cpu *cpu = container_of(container_of(dev,struct sys_device,dev), + struct cpu, sysdev); + ssize_t ret; + + if (off != 0) + return -EINVAL; + switch (buf[0]) { + case '0': + ret = cpu_down(cpu->sysdev.id); + break; + case '1': + ret = cpu_up(cpu->sysdev.id); + break; + default: + ret = -EINVAL; + } + + if (ret == 0) + ret = count; + return ret; +} + +static DEVICE_ATTR(online, 0600, show_online, store_online); /* * register_cpu - Setup a driverfs device for a CPU. @@ -35,6 +79,8 @@ struct device_driver cpu_driver = { */ int __init register_cpu(struct cpu *cpu, int num, struct node *root) { + int ret; + cpu->node_id = __cpu_to_node(num); cpu->sysdev.name = "cpu"; cpu->sysdev.id = num; @@ -42,7 +88,13 @@ int __init register_cpu(struct cpu *cpu, cpu->sysdev.root = &root->sysroot; snprintf(cpu->sysdev.dev.name, DEVICE_NAME_SIZE, "CPU %u", num); cpu->sysdev.dev.driver = &cpu_driver; - return sys_device_register(&cpu->sysdev); + ret = sys_device_register(&cpu->sysdev); + if (ret < 0) + return ret; + ret = device_create_file(&cpu->sysdev.dev, &dev_attr_online); + if (ret < 0) + sys_device_unregister(&cpu->sysdev); + return ret; } diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .3214-linux-2.5.46/include/linux/cpu.h .3214-linux-2.5.46.updated/include/linux/cpu.h --- .3214-linux-2.5.46/include/linux/cpu.h 2002-11-05 10:54:28.000000000 +1100 +++ .3214-linux-2.5.46.updated/include/linux/cpu.h 2002-11-05 16:32:32.000000000 +1100 @@ -21,6 +21,7 @@ #include #include +#include struct cpu { int node_id; /* The node which contains the CPU */ @@ -29,4 +30,9 @@ struct cpu { extern int register_cpu(struct cpu *, int, struct node *); +/* Bring a CPU up and take it down: grab semaphore to stop it. */ +extern struct semaphore cpucontrol; +int cpu_up(unsigned int cpu); +int cpu_down(unsigned int cpu); + #endif /* _LINUX_CPU_H_ */ diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .3214-linux-2.5.46/include/linux/smp.h .3214-linux-2.5.46.updated/include/linux/smp.h --- .3214-linux-2.5.46/include/linux/smp.h 2002-10-15 15:19:44.000000000 +1000 +++ .3214-linux-2.5.46.updated/include/linux/smp.h 2002-11-05 16:32:32.000000000 +1100 @@ -76,8 +76,6 @@ struct notifier_block; /* Need to know about CPUs going up/down? */ extern int register_cpu_notifier(struct notifier_block *nb); extern void unregister_cpu_notifier(struct notifier_block *nb); - -int cpu_up(unsigned int cpu); #else /* !SMP */ /* diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .3214-linux-2.5.46/init/main.c .3214-linux-2.5.46.updated/init/main.c --- .3214-linux-2.5.46/init/main.c 2002-11-05 10:54:28.000000000 +1100 +++ .3214-linux-2.5.46.updated/init/main.c 2002-11-05 16:32:32.000000000 +1100 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .3214-linux-2.5.46/kernel/cpu.c .3214-linux-2.5.46.updated/kernel/cpu.c --- .3214-linux-2.5.46/kernel/cpu.c 2002-10-31 12:37:04.000000000 +1100 +++ .3214-linux-2.5.46.updated/kernel/cpu.c 2002-11-05 16:32:32.000000000 +1100 @@ -8,7 +8,7 @@ #include #include #include -#include +#include /* This protects CPUs going up and down... */ DECLARE_MUTEX(cpucontrol); @@ -26,7 +26,7 @@ void unregister_cpu_notifier(struct noti notifier_chain_unregister(&cpu_chain,nb); } -int __devinit cpu_up(unsigned int cpu) +int cpu_up(unsigned int cpu) { int ret; void *hcpu = (void *)(long)cpu; @@ -64,3 +64,9 @@ out: up(&cpucontrol); return ret; } + +int cpu_down(unsigned int cpu) +{ + /* Not Yet Implemented. */ + return -ENOSYS; +}