All of lore.kernel.org
 help / color / mirror / Atom feed
From: Johannes Berg <johannes@sipsolutions.net>
To: Linux Kernel list <linux-kernel@vger.kernel.org>
Cc: netdev@vger.kernel.org, Michael Buesch <mbuesch@freenet.de>,
	bcm43xx-dev@lists.berlios.de
Subject: Re: bcm43xx for d80211 softirq loop
Date: Mon, 14 Aug 2006 10:21:14 +0200	[thread overview]
Message-ID: <44E0327A.1080300@sipsolutions.net> (raw)
In-Reply-To: <44E0300D.1000402@sipsolutions.net>

Here's the patch I used to find out which tasklet was giving me a hard 
time with bcm43xx and d80211. I don't really expect this to be applied 
anywhere but didn't want to sit on it either.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>

--- wireless-dev.orig/include/linux/interrupt.h    2006-08-13 
00:49:46.346865273 +0200
+++ wireless-dev/include/linux/interrupt.h    2006-08-13 
16:23:39.449545098 +0200
@@ -14,6 +14,7 @@
 #include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
+#include <linux/stringify.h>
 
 /*
  * These correspond to the IORESOURCE_IRQ_* defines in
@@ -267,6 +268,10 @@ struct tasklet_struct
     atomic_t count;
     void (*func)(unsigned long);
     unsigned long data;
+#ifdef CONFIG_DEBUG_TASKLETS
+    char *name;
+    unsigned int reschedule_count;
+#endif
 };
 
 #define DECLARE_TASKLET(name, func, data) \
@@ -348,8 +353,25 @@ static inline void tasklet_hi_enable(str
 
 extern void tasklet_kill(struct tasklet_struct *t);
 extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned 
int cpu);
-extern void tasklet_init(struct tasklet_struct *t,
-             void (*func)(unsigned long), unsigned long data);
+extern void _tasklet_init(struct tasklet_struct *t,
+              void (*func)(unsigned long), unsigned long data);
+#ifndef CONFIG_DEBUG_TASKLETS
+#define tasklet_init    _tasklet_init
+/* ignore name in the non-debug version, use a macro so the
+ * compiler can discard the string... */
+#define tasklet_init_named(t, func, data, name)    \
+    _tasklet_init(t, func, data)
+#else
+#define tasklet_init(t, func, data)    do {        \
+    _tasklet_init(t, func, data);            \
+    (t)->name = __FILE__ ":" __stringify(__LINE__);    \
+    } while (0)
+#define tasklet_init_named(t, func, data, name)    \
+    do {                    \
+    _tasklet_init(t, func, data);        \
+    (t)->name = (name);            \
+    } while (0)
+#endif
 
 /*
  * Autoprobing for irqs:
--- wireless-dev.orig/kernel/softirq.c    2006-08-13 00:56:37.206865273 
+0200
+++ wireless-dev/kernel/softirq.c    2006-08-13 16:34:31.079545098 +0200
@@ -385,9 +385,22 @@ static void tasklet_action(struct softir
                 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
                     BUG();
                 t->func(t->data);
+#ifdef CONFIG_DEBUG_TASKLETS
+                t->reschedule_count = 0;
+#endif
                 tasklet_unlock(t);
                 continue;
             }
+#ifdef CONFIG_DEBUG_TASKLETS
+            /* 10000 is arbitrary... how much should it be?
+             * on my system, 10000 is quite a long time... */
+            if (t->reschedule_count++ > 10000) {
+                printk(KERN_ERR "tasklet %s is scheduled but hasn't been"
+                    " enabled for too long!\n", t->name);
+                tasklet_unlock(t);
+                continue;
+            }
+#endif
             tasklet_unlock(t);
         }
 
@@ -433,7 +446,7 @@ static void tasklet_hi_action(struct sof
 }
 
 
-void tasklet_init(struct tasklet_struct *t,
+void _tasklet_init(struct tasklet_struct *t,
           void (*func)(unsigned long), unsigned long data)
 {
     t->next = NULL;
@@ -443,7 +456,7 @@ void tasklet_init(struct tasklet_struct
     t->data = data;
 }
 
-EXPORT_SYMBOL(tasklet_init);
+EXPORT_SYMBOL(_tasklet_init);
 
 void tasklet_kill(struct tasklet_struct *t)
 {
--- wireless-dev.orig/lib/Kconfig.debug    2006-08-13 01:00:56.016865273 
+0200
+++ wireless-dev/lib/Kconfig.debug    2006-08-13 16:00:15.419545098 +0200
@@ -93,6 +93,16 @@ config SCHEDSTATS
       application, you can say N to avoid the very slight overhead
       this adds.
 
+config DEBUG_TASKLETS
+    bool "Debug runaway tasklets"
+    depends on DEBUG_KERNEL
+    help
+      If you say Y here, additional code will be inserted into the
+      lowlevel tasklet code in order to debug tasklets that are
+      scheduled but not enabled. If such a tasklet is found and
+      not enabled within a number of iterations, it is un-scheduled
+      and the kernel reports it.
+
 config DEBUG_SLAB
     bool "Debug slab memory allocations"
     depends on DEBUG_KERNEL && SLAB


WARNING: multiple messages have this Message-ID (diff)
From: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>
To: Linux Kernel list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Michael Buesch <mbuesch-KuiJ5kEpwI6ELgA04lAiVw@public.gmane.org>,
	bcm43xx-dev-0fE9KPoRgkgATYTw5x5z8w@public.gmane.org
Subject: Re: bcm43xx for d80211 softirq loop
Date: Mon, 14 Aug 2006 10:21:14 +0200	[thread overview]
Message-ID: <44E0327A.1080300@sipsolutions.net> (raw)
In-Reply-To: <44E0300D.1000402-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>

Here's the patch I used to find out which tasklet was giving me a hard 
time with bcm43xx and d80211. I don't really expect this to be applied 
anywhere but didn't want to sit on it either.

Signed-off-by: Johannes Berg <johannes-cdvu00un1VgdHxzADdlk8Q@public.gmane.org>

--- wireless-dev.orig/include/linux/interrupt.h    2006-08-13 
00:49:46.346865273 +0200
+++ wireless-dev/include/linux/interrupt.h    2006-08-13 
16:23:39.449545098 +0200
@@ -14,6 +14,7 @@
 #include <asm/atomic.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
+#include <linux/stringify.h>
 
 /*
  * These correspond to the IORESOURCE_IRQ_* defines in
@@ -267,6 +268,10 @@ struct tasklet_struct
     atomic_t count;
     void (*func)(unsigned long);
     unsigned long data;
+#ifdef CONFIG_DEBUG_TASKLETS
+    char *name;
+    unsigned int reschedule_count;
+#endif
 };
 
 #define DECLARE_TASKLET(name, func, data) \
@@ -348,8 +353,25 @@ static inline void tasklet_hi_enable(str
 
 extern void tasklet_kill(struct tasklet_struct *t);
 extern void tasklet_kill_immediate(struct tasklet_struct *t, unsigned 
int cpu);
-extern void tasklet_init(struct tasklet_struct *t,
-             void (*func)(unsigned long), unsigned long data);
+extern void _tasklet_init(struct tasklet_struct *t,
+              void (*func)(unsigned long), unsigned long data);
+#ifndef CONFIG_DEBUG_TASKLETS
+#define tasklet_init    _tasklet_init
+/* ignore name in the non-debug version, use a macro so the
+ * compiler can discard the string... */
+#define tasklet_init_named(t, func, data, name)    \
+    _tasklet_init(t, func, data)
+#else
+#define tasklet_init(t, func, data)    do {        \
+    _tasklet_init(t, func, data);            \
+    (t)->name = __FILE__ ":" __stringify(__LINE__);    \
+    } while (0)
+#define tasklet_init_named(t, func, data, name)    \
+    do {                    \
+    _tasklet_init(t, func, data);        \
+    (t)->name = (name);            \
+    } while (0)
+#endif
 
 /*
  * Autoprobing for irqs:
--- wireless-dev.orig/kernel/softirq.c    2006-08-13 00:56:37.206865273 
+0200
+++ wireless-dev/kernel/softirq.c    2006-08-13 16:34:31.079545098 +0200
@@ -385,9 +385,22 @@ static void tasklet_action(struct softir
                 if (!test_and_clear_bit(TASKLET_STATE_SCHED, &t->state))
                     BUG();
                 t->func(t->data);
+#ifdef CONFIG_DEBUG_TASKLETS
+                t->reschedule_count = 0;
+#endif
                 tasklet_unlock(t);
                 continue;
             }
+#ifdef CONFIG_DEBUG_TASKLETS
+            /* 10000 is arbitrary... how much should it be?
+             * on my system, 10000 is quite a long time... */
+            if (t->reschedule_count++ > 10000) {
+                printk(KERN_ERR "tasklet %s is scheduled but hasn't been"
+                    " enabled for too long!\n", t->name);
+                tasklet_unlock(t);
+                continue;
+            }
+#endif
             tasklet_unlock(t);
         }
 
@@ -433,7 +446,7 @@ static void tasklet_hi_action(struct sof
 }
 
 
-void tasklet_init(struct tasklet_struct *t,
+void _tasklet_init(struct tasklet_struct *t,
           void (*func)(unsigned long), unsigned long data)
 {
     t->next = NULL;
@@ -443,7 +456,7 @@ void tasklet_init(struct tasklet_struct
     t->data = data;
 }
 
-EXPORT_SYMBOL(tasklet_init);
+EXPORT_SYMBOL(_tasklet_init);
 
 void tasklet_kill(struct tasklet_struct *t)
 {
--- wireless-dev.orig/lib/Kconfig.debug    2006-08-13 01:00:56.016865273 
+0200
+++ wireless-dev/lib/Kconfig.debug    2006-08-13 16:00:15.419545098 +0200
@@ -93,6 +93,16 @@ config SCHEDSTATS
       application, you can say N to avoid the very slight overhead
       this adds.
 
+config DEBUG_TASKLETS
+    bool "Debug runaway tasklets"
+    depends on DEBUG_KERNEL
+    help
+      If you say Y here, additional code will be inserted into the
+      lowlevel tasklet code in order to debug tasklets that are
+      scheduled but not enabled. If such a tasklet is found and
+      not enabled within a number of iterations, it is un-scheduled
+      and the kernel reports it.
+
 config DEBUG_SLAB
     bool "Debug slab memory allocations"
     depends on DEBUG_KERNEL && SLAB

  reply	other threads:[~2006-08-14  8:21 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-14  8:07 [wireless] bunch of questions and notes on d80211 Johannes Berg
2006-08-14  8:10 ` bcm43xx for d80211 softirq loop Johannes Berg
2006-08-14  8:21   ` Johannes Berg [this message]
2006-08-14  8:21     ` Johannes Berg
2006-08-14 13:27   ` Michael Buesch
2006-08-14  8:12 ` [d80211 rfc] link master interface from wiphy Johannes Berg
2006-08-14 12:01   ` Dan Williams
2006-08-16 17:05   ` Jiri Benc
2006-08-17  7:18     ` Johannes Berg
2006-08-14  8:13 ` [PATCH] d80211: fix some 0 vs. NULL comparisons Johannes Berg
2006-08-14 13:20   ` Johannes Berg
2006-08-14 15:48     ` Jouni Malinen
2006-08-14  8:15 ` [PATCH] d80211: get rid of the WME bitfield Johannes Berg
2006-08-14 16:12   ` Jouni Malinen
2006-08-15  7:11     ` Johannes Berg
2006-08-14  8:16 ` ieee80211_japan_5ghz / firmware etc.?? Johannes Berg
2006-08-14  8:16 ` ieee80211_set_encryption Johannes Berg
2006-08-14 15:53   ` ieee80211_set_encryption Jouni Malinen
2006-08-14  8:18 ` network manager confused with bcm43xx-d80211? Johannes Berg
2006-08-14 11:46   ` Dan Williams
2006-08-14 12:28     ` Johannes Berg
2006-08-14 12:48       ` Larry Finger
2006-08-14 12:54         ` Johannes Berg
2006-08-14  8:19 ` d80211 and sta_aid for AP functionality Johannes Berg
2006-08-17 18:21   ` Jiri Benc
2006-08-14  8:22 ` wlan#ap seems bogus Johannes Berg
2006-08-14 14:04   ` Johannes Berg
2006-08-14 18:53     ` Simon Barber
2006-08-15  7:22       ` Johannes Berg
2006-08-14 15:58   ` Jouni Malinen
2006-08-14 16:04     ` Johannes Berg

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=44E0327A.1080300@sipsolutions.net \
    --to=johannes@sipsolutions.net \
    --cc=bcm43xx-dev@lists.berlios.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mbuesch@freenet.de \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.