[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Support tasklets in Xen as a more dynamic alternative to softirqs.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1207924668 -3600 # Node ID 96b099ad04973e26944b8ef8196be0fd2ffdabfa # Parent 80ba1b4270321baa58b0e8064fb472f2c2462b8d Support tasklets in Xen as a more dynamic alternative to softirqs. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- xen/arch/ia64/xen/xensetup.c | 2 + xen/arch/x86/setup.c | 2 + xen/common/softirq.c | 74 +++++++++++++++++++++++++++++++++++++++++++ xen/include/xen/softirq.h | 61 +++++++++++++++++++++++------------ 4 files changed, 118 insertions(+), 21 deletions(-) diff -r 80ba1b427032 -r 96b099ad0497 xen/arch/ia64/xen/xensetup.c --- a/xen/arch/ia64/xen/xensetup.c Fri Apr 11 13:19:55 2008 +0100 +++ b/xen/arch/ia64/xen/xensetup.c Fri Apr 11 15:37:48 2008 +0100 @@ -576,6 +576,8 @@ skip_move: end_boot_allocator(); + softirq_init(); + late_setup_arch(&cmdline); scheduler_init(); diff -r 80ba1b427032 -r 96b099ad0497 xen/arch/x86/setup.c --- a/xen/arch/x86/setup.c Fri Apr 11 13:19:55 2008 +0100 +++ b/xen/arch/x86/setup.c Fri Apr 11 15:37:48 2008 +0100 @@ -861,6 +861,8 @@ void __init __start_xen(unsigned long mb early_boot = 0; + softirq_init(); + early_cpu_init(); paging_init(); diff -r 80ba1b427032 -r 96b099ad0497 xen/common/softirq.c --- a/xen/common/softirq.c Fri Apr 11 13:19:55 2008 +0100 +++ b/xen/common/softirq.c Fri Apr 11 15:37:48 2008 +0100 @@ -52,6 +52,80 @@ void open_softirq(int nr, softirq_handle softirq_handlers[nr] = handler; } +static DEFINE_PER_CPU(struct tasklet *, tasklet_list); + +void tasklet_schedule(struct tasklet *t) +{ + unsigned long flags; + + if ( test_and_set_bool(t->is_scheduled) ) + return; + + local_irq_save(flags); + t->next = this_cpu(tasklet_list); + this_cpu(tasklet_list) = t; + local_irq_restore(flags); + + raise_softirq(TASKLET_SOFTIRQ); +} + +static void tasklet_action(void) +{ + struct tasklet *list, *t; + + local_irq_disable(); + list = this_cpu(tasklet_list); + this_cpu(tasklet_list) = NULL; + local_irq_enable(); + + while ( (t = list) != NULL ) + { + list = list->next; + + BUG_ON(t->is_running); + t->is_running = 1; + smp_wmb(); + + BUG_ON(!t->is_scheduled); + t->is_scheduled = 0; + + smp_mb(); + t->func(t->data); + smp_mb(); + + t->is_running = 0; + } +} + +void tasklet_kill(struct tasklet *t) +{ + /* Prevent tasklet from re-scheduling itself. */ + while ( t->is_scheduled || test_and_set_bool(t->is_scheduled) ) + cpu_relax(); + smp_mb(); + + /* Wait for tasklet to complete. */ + while ( t->is_running ) + cpu_relax(); + smp_mb(); + + /* Clean up and we're done. */ + t->is_scheduled = 0; +} + +void tasklet_init( + struct tasklet *t, void (*func)(unsigned long), unsigned long data) +{ + memset(t, 0, sizeof(*t)); + t->func = func; + t->data = data; +} + +void __init softirq_init(void) +{ + open_softirq(TASKLET_SOFTIRQ, tasklet_action); +} + /* * Local variables: * mode: C diff -r 80ba1b427032 -r 96b099ad0497 xen/include/xen/softirq.h --- a/xen/include/xen/softirq.h Fri Apr 11 13:19:55 2008 +0100 +++ b/xen/include/xen/softirq.h Fri Apr 11 15:37:48 2008 +0100 @@ -1,24 +1,20 @@ -#ifndef __XEN_SOFTIRQ_H__ +#if !defined(__XEN_SOFTIRQ_H__) && !defined(__ASSEMBLY__) #define __XEN_SOFTIRQ_H__ -/* Common softirqs come first in the following list. */ -#define TIMER_SOFTIRQ 0 -#define SCHEDULE_SOFTIRQ 1 -#define NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ 2 -#define KEYPRESS_SOFTIRQ 3 -#define NMI_SOFTIRQ 4 -#define PAGE_SCRUB_SOFTIRQ 5 -#define TRACE_SOFTIRQ 6 -#define RCU_SOFTIRQ 7 -#define STOPMACHINE_SOFTIRQ 8 - -#define NR_COMMON_SOFTIRQS 9 - -#include <asm/softirq.h> - -#define NR_SOFTIRQS (NR_COMMON_SOFTIRQS + NR_ARCH_SOFTIRQS) - -#ifndef __ASSEMBLY__ +/* Low-latency softirqs come first in the following list. */ +enum { + TIMER_SOFTIRQ = 0, + SCHEDULE_SOFTIRQ, + NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, + KEYPRESS_SOFTIRQ, + NMI_SOFTIRQ, + PAGE_SCRUB_SOFTIRQ, + TRACE_SOFTIRQ, + RCU_SOFTIRQ, + STOPMACHINE_SOFTIRQ, + TASKLET_SOFTIRQ, + NR_COMMON_SOFTIRQS +}; #include <xen/config.h> #include <xen/lib.h> @@ -26,11 +22,15 @@ #include <asm/bitops.h> #include <asm/current.h> #include <asm/hardirq.h> +#include <asm/softirq.h> + +#define NR_SOFTIRQS (NR_COMMON_SOFTIRQS + NR_ARCH_SOFTIRQS) typedef void (*softirq_handler)(void); asmlinkage void do_softirq(void); -extern void open_softirq(int nr, softirq_handler handler); +void open_softirq(int nr, softirq_handler handler); +void softirq_init(void); static inline void cpumask_raise_softirq(cpumask_t mask, unsigned int nr) { @@ -56,6 +56,25 @@ static inline void raise_softirq(unsigne set_bit(nr, &softirq_pending(smp_processor_id())); } -#endif /* __ASSEMBLY__ */ +/* + * TASKLETS -- dynamically-allocatable tasks run in softirq context + * on at most one CPU at a time. + */ +struct tasklet +{ + struct tasklet *next; + bool_t is_scheduled; + bool_t is_running; + void (*func)(unsigned long); + unsigned long data; +}; + +#define DECLARE_TASKLET(name, func, data) \ + struct tasklet name = { NULL, 0, 0, func, data } + +void tasklet_schedule(struct tasklet *t); +void tasklet_kill(struct tasklet *t); +void tasklet_init( + struct tasklet *t, void (*func)(unsigned long), unsigned long data); #endif /* __XEN_SOFTIRQ_H__ */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |