Verify that sleeping is allowed in chain contexts where Broadcom will need to.
authorBen Pfaff <blp@nicira.com>
Mon, 21 Jul 2008 20:39:26 +0000 (13:39 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 21 Jul 2008 20:59:55 +0000 (13:59 -0700)
datapath/chain.c
datapath/linux-2.4/compat-2.4/include/linux/kernel.h
datapath/linux-2.4/compat-2.4/kernel.c

index f7ea1dc656a17b29fb0e7d77a937dfd78485da99..71e00ee6fca7bbcbac6ae839ee9ff520553328cb 100644 (file)
@@ -89,6 +89,7 @@ int chain_insert(struct sw_chain *chain, struct sw_flow *flow)
 {
        int i;
 
+       might_sleep();
        for (i = 0; i < chain->n_tables; i++) {
                struct sw_table *t = chain->tables[i];
                if (t->insert(t, flow))
@@ -112,6 +113,7 @@ int chain_delete(struct sw_chain *chain, const struct sw_flow_key *key,
        int count = 0;
        int i;
 
+       might_sleep();
        for (i = 0; i < chain->n_tables; i++) {
                struct sw_table *t = chain->tables[i];
                count += t->delete(t, key, priority, strict);
@@ -133,6 +135,7 @@ int chain_timeout(struct sw_chain *chain)
        int count = 0;
        int i;
 
+       might_sleep();
        for (i = 0; i < chain->n_tables; i++) {
                struct sw_table *t = chain->tables[i];
                count += t->timeout(chain->dp, t);
index 329dab533dc3198bdbe1d6a4a36a787546de8a4b..543ba9b63dc83fea0f3ba4c0f28f6afb2291f794 100644 (file)
@@ -2,6 +2,7 @@
 #define __LINUX_KERNEL_WRAPPER_H 1
 
 #include_next <linux/kernel.h>
+#include <linux/config.h>
 
 /**
  * container_of - cast a member of a structure out to the containing structure
@@ -40,4 +41,26 @@ int vprintk(const char *msg, ...)
 /* Force a compilation error if condition is true */
 #define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
 
+/**
+ * might_sleep - annotation for functions that can sleep
+ *
+ * this macro will print a stack trace if it is executed in an atomic
+ * context (spinlock, irq-handler, ...).
+ *
+ * This is a useful debugging help to be able to catch problems early and not
+ * be bitten later when the calling function happens to sleep when it is not
+ * supposed to.
+ */
+#define might_resched() do { } while (0)
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+  void __might_sleep(char *file, int line);
+# define might_sleep() \
+       do { __might_sleep(__FILE__, __LINE__); might_resched(); } while (0)
+#else
+# define might_sleep() do { might_resched(); } while (0)
+#endif
+
+#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
+
 #endif
index a08bb2d8133f19b5a2896ddee91331f0697ea313..36d2d8aeabe7fef96a229117854599fe4045d4e4 100644 (file)
@@ -2,9 +2,11 @@
  * Distributed under the terms of the GNU GPL version 2.
  */
 
+#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <asm/hardirq.h>
 
 int vprintk(const char *msg, ...)
 {
@@ -25,3 +27,20 @@ int vprintk(const char *msg, ...)
 }
 
 EXPORT_SYMBOL(vprintk);
+
+#ifdef CONFIG_DEBUG_SPINLOCK
+void __might_sleep(char *file, int line)
+{
+       static unsigned long prev_jiffy;        /* ratelimiting */
+
+       if ((in_interrupt()) && !oops_in_progress) {
+               if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
+                       return;
+               prev_jiffy = jiffies;
+               printk(KERN_ERR "BUG: sleeping function called from invalid"
+                               " context at %s:%d\n", file, line);
+               dump_stack();
+       }
+}
+EXPORT_SYMBOL(__might_sleep);
+#endif