]> git.hungrycats.org Git - linux/commitdiff
[PATCH] dm: dm_table_event() sleep on spinlock bug
authorAndrew Morton <akpm@osdl.org>
Mon, 29 Dec 2003 13:56:04 +0000 (05:56 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Mon, 29 Dec 2003 13:56:04 +0000 (05:56 -0800)
From: Joe Thornber <thornber@sistina.com>

You can no longer call dm_table_event() from interrupt context.

drivers/md/dm-table.c

index f10c4489a48b1464ea834eba9913d2f0a512e4d5..d0a3ec05caec81d4be2b69a43c02c9e1820284ff 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/namei.h>
 #include <linux/ctype.h>
 #include <linux/slab.h>
+#include <linux/interrupt.h>
 #include <asm/atomic.h>
 
 #define MAX_DEPTH 16
@@ -746,22 +747,28 @@ int dm_table_complete(struct dm_table *t)
        return r;
 }
 
-static spinlock_t _event_lock = SPIN_LOCK_UNLOCKED;
+static DECLARE_MUTEX(_event_lock);
 void dm_table_event_callback(struct dm_table *t,
                             void (*fn)(void *), void *context)
 {
-       spin_lock_irq(&_event_lock);
+       down(&_event_lock);
        t->event_fn = fn;
        t->event_context = context;
-       spin_unlock_irq(&_event_lock);
+       up(&_event_lock);
 }
 
 void dm_table_event(struct dm_table *t)
 {
-       spin_lock(&_event_lock);
+       /*
+        * You can no longer call dm_table_event() from interrupt
+        * context, use a bottom half instead.
+        */
+       BUG_ON(in_interrupt());
+
+       down(&_event_lock);
        if (t->event_fn)
                t->event_fn(t->event_context);
-       spin_unlock(&_event_lock);
+       up(&_event_lock);
 }
 
 sector_t dm_table_get_size(struct dm_table *t)