[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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.