Re: init scripts problems ?
"Peter T. Breuer" <[email protected]> Wed, 7 Dec 2005 02:08:22 +0100 (MET)
| Newsgroups | gmane.linux.enbd.general |
|---|---|
| Message-ID | <[email protected]> |
"Also sprach Peter T. Breuer:"
> In a separate patch here I moved the array notifications into a
> tasklet, since I was worried about racing or deadlock in a circle. I
> could give you that patch to see if it helps. If it doesn't, it at least
> eliminates the array communication as a problem.
It's late, and I promised, but the patch is spread, so I'll give a
mixture of patch and directions.
First add an extra field to the enbd_device struct defn in
include/linux/enbd.h (in kernel/linux-2.6.x):
int md_notify_cmd; /* PTB will send to md devices */
+ struct tasklet_struct notify_md_tasklet;
/* PTB for notifying devices */
};
Then patch enbd_base.c as follows:
--- kernel/linux-2.6.x/drivers/block/enbd/enbd_base.c.oboe Sun Dec 4 21:27:35 2005
+++ kernel/linux-2.6.x/drivers/block/enbd/enbd_base.c Wed Dec 7 00:54:46 2005
@@ -241,6 +241,7 @@
#if defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE)
#include <linux/supermount_media.h>
#endif /* defined(CONFIG_SUPERMOUNT) || defined(CONFIG_SUPERMOUNT_MODULE) */
+#include <linux/interrupt.h> // PTB for tasklets
/* *
* PTB --------------- compatibility ------------------- *
@@ -2562,19 +2563,29 @@
if (slot->md_count <= 0)
continue;
}
md->notify(&enbd_md, enbd_dev, cmd);
}
return 0;
}
+static void
+enbd_notify_tasklet_fn(unsigned long data) {
+
+ struct enbd_device *lo = (struct enbd_device *)data;
+ int cmd = lo->md_notify_cmd;
+
+ enbd_notify_md_devices(lo, cmd);
+}
/*
* PTB - set the enabled flag on a device (call without the spinlock held)
+ * and notify md devices
*
* @lo the nbd device being treated
*/
static void
enbd_enable (struct enbd_device *lo) {
+
unsigned long flags;
int did_enabled = 0;
@@ -2589,9 +2600,10 @@
write_unlock_irqrestore (&lo->meta_lock, flags);
if (did_enabled) {
- ENBD_ALERT("set VALID on nd%s\n", lo->devnam);
+ ENBD_ALERT("set ENABLED on nd%s\n", lo->devnam);
//__invalidate_device(lo->inode->i_bdev, 0);
- enbd_notify(lo, HOT_ADD_DISK);
+ lo->md_notify_cmd = HOT_ADD_DISK;
+ tasklet_schedule(&lo->notify_md_tasklet);
}
}
@@ -3191,7 +3218,8 @@
ENBD_ALERT ("disabled device nd%s\n", lo->devnam);
}
- enbd_notify(lo, SET_DISK_FAULTY);
+ lo->md_notify_cmd = SET_DISK_FAULTY;
+ tasklet_schedule(&lo->notify_md_tasklet);
// PTB have to recheck partitions on next open
if (atomic_test_and_clear_mask (&lo->flags, ENBD_VALIDATED)) {
@@ -5087,6 +5164,9 @@
enbd_init_speed(&lo->wspeed);
enbd_init_speed(&lo->tspeed);
+ tasklet_init(&lo->notify_md_tasklet,
+ enbd_notify_tasklet_fn, (unsigned long)lo);
+
// PTB queuue has alreay been initialized, or will be
lo->q = lo->disk ? lo->disk->queue : NULL;
Thirdly, go through all the .c files in the (linux-2.6.x)
drivers/block/enbd/ subdir, and put the include in the first hunk above
somewhere above that of enbd.h in them too, something like this:
#include <linux/blkdev.h>
#include <linux/sysctl.h>
+#include <linux/interrupt.h> // PTB for tasklets
#include <linux/enbd.h>
This takes MD array definition "out of line" so it can't really
ever be involved in any deadlock.
Peter