Messages in this thread Patch in this message | | | Subject | Subject:[ PATCH 001:003] OFFSCHED CORE | From | raz ben yehuda <> | Date | Sun, 23 Aug 2009 02:29:46 +0300 |
| |
OFFSCHED support.
. A callback invoked just before halting the processor. . SMP alternative work-around. we do not run smp alternatives if we are left with a single processor. . A set of utilities used by the offsched driver.
process.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ smpboot.c | 13 +++++-- 2 files changed, 118 insertions(+), 4 deletions(-)
Signed-off-by: raziebe@gmail.com --- diff -X 2.6.30-offsched/Documentation/dontdiff -urN tmp/linux-2.6.30/arch/x86/kernel/process.c 2.6.30-offsched/arch/x86/kernel/process.c --- tmp/linux-2.6.30/arch/x86/kernel/process.c 2009-06-10 06:05:27.000000000 +0300 +++ 2.6.30-offsched/arch/x86/kernel/process.c 2009-08-21 22:02:44.000000000 +0300 @@ -613,3 +613,112 @@ } early_param("idle", idle_setup); +#ifdef CONFIG_HOTPLUG_CPU +struct hotplug_cpu{ + long flags; + void (*hotplug_cpu_dead)(void); +}; + +static long offsched_services; + +#define CPU_OFFSCHED 31 +#define CPU_OFFSCHED_KMEM 30 +#define SERVICE_TIMER 01 +#define SERVICE_NAPI 02 + +DEFINE_PER_CPU(struct hotplug_cpu, offschedcpu); + +void unregister_offsched(int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + cpu->hotplug_cpu_dead = NULL; + clear_bit(CPU_OFFSCHED, &cpu->flags); +} +EXPORT_SYMBOL_GPL(unregister_offsched); + +int is_offsched(int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + return test_bit(CPU_OFFSCHED, &cpu->flags); +} +EXPORT_SYMBOL_GPL(is_offsched); + +int is_offsched_kmem(int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + return test_bit(CPU_OFFSCHED_KMEM, &cpu->flags); +} +EXPORT_SYMBOL_GPL(is_offsched_kmem); + +void set_offsched_kmem(int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + set_bit(CPU_OFFSCHED_KMEM, &cpu->flags); +} +EXPORT_SYMBOL_GPL(set_offsched_kmem); + +void unset_offsched_kmem(int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + clear_bit(CPU_OFFSCHED_KMEM, &cpu->flags); +} +EXPORT_SYMBOL_GPL(unset_offsched_kmem); + +int register_offsched(void (*offsched_callback)(void), int cpuid) +{ + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + if (is_offsched(cpuid)) + return -1; + cpu->hotplug_cpu_dead = offsched_callback; + set_bit(CPU_OFFSCHED, &cpu->flags); + return 0; +} +EXPORT_SYMBOL_GPL(register_offsched); + +void run_offsched(void) +{ + int cpuid = raw_smp_processor_id(); + struct hotplug_cpu *cpu = &per_cpu(offschedcpu, cpuid); + cpu->hotplug_cpu_dead(); +} + +int offsched_is_napi_avail(void) +{ + return SERVICE_NAPI & offsched_services; +} + +int (*offsched_rule)(void *); +EXPORT_SYMBOL(offsched_rule); +/* +* if we a have filter than apply filter. +* return 0 if packet should go to kernel +* return 1 if packet should go to offsched. +*/ +int offsched_pkt(void *s) +{ + if (offsched_rule) + return offsched_rule(s); + return 0; +} + +void offsched_register_napi(void) +{ + offsched_services |= SERVICE_NAPI; +} +EXPORT_SYMBOL_GPL(offsched_register_napi); + +void offsched_unregister_napi(void) +{ + offsched_services &= ~SERVICE_NAPI; +} +EXPORT_SYMBOL_GPL(offsched_unregister_napi); + +/* + * napi scheudule is called in offsched context. +*/ +void offsched_napi_schedule(void *n) +{ + +} + +#endif diff -X 2.6.30-offsched/Documentation/dontdiff -urN tmp/linux-2.6.30/arch/x86/kernel/smpboot.c 2.6.30-offsched/arch/x86/kernel/smpboot.c --- tmp/linux-2.6.30/arch/x86/kernel/smpboot.c 2009-06-10 06:05:27.000000000 +0300 +++ 2.6.30-offsched/arch/x86/kernel/smpboot.c 2009-07-25 13:59:19.000000000 +0300 @@ -39,6 +39,8 @@ * Glauber Costa : i386 and x86_64 integration */ +#define DEBUG + #include <linux/init.h> #include <linux/smp.h> #include <linux/module.h> @@ -686,8 +688,8 @@ }; INIT_WORK(&c_idle.work, do_fork_idle); - - alternatives_smp_switch(1); + if (!is_offsched(cpu)) + alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -1283,8 +1285,9 @@ for (i = 0; i < 10; i++) { /* They ack this in play_dead by setting CPU_DEAD */ if (per_cpu(cpu_state, cpu) == CPU_DEAD) { - printk(KERN_INFO "CPU %d is now offline\n", cpu); - if (1 == num_online_cpus()) + printk(KERN_INFO "CPU %d is now offline %s\n", cpu, + is_offsched(cpu) ? "and OFFSCHED" : ""); + if (1 == num_online_cpus() && !is_offsched(cpu)) alternatives_smp_switch(0); return; } @@ -1313,6 +1316,8 @@ void native_play_dead(void) { play_dead_common(); + if (is_offsched(raw_smp_processor_id())) + run_offsched(); wbinvd_halt(); }
| |