I am running 2.6.0-test9-udm5. When I do a rmmod of dm-mirror and dm-mod
I get the following oops:
Nov 24 02:35:14 minna kernel: device-mapper: 4.0.0-ioctl (2003-06-04)
initialised: dm@xxxxxxxxxxxxxx
Nov 24 02:35:59 minna kernel: device-mapper: cleaned up
Nov 24 02:35:59 minna kernel: Unable to handle kernel paging request at
virtual address d09bdca6
Nov 24 02:35:59 minna kernel: printing eip:
Nov 24 02:35:59 minna kernel: d09bdca6
Nov 24 02:35:59 minna kernel: *pde = 013e0067
Nov 24 02:35:59 minna kernel: *pte = 00000000
Nov 24 02:35:59 minna kernel: Oops: 0000 [#1]
Nov 24 02:35:59 minna kernel: CPU: 0
Nov 24 02:35:59 minna kernel: EIP: 0060:[<d09bdca6>] Not tainted
Nov 24 02:35:59 minna kernel: EFLAGS: 00010246
Nov 24 02:35:59 minna kernel: EIP is at 0xd09bdca6
Nov 24 02:35:59 minna kernel: eax: 00000000 ebx: c72fa000 ecx:
d09c2810 edx: d09c2834
Nov 24 02:35:59 minna kernel: esi: d09c27e0 edi: ffffe000 ebp:
c72fbfc0 esp: c72fbf98
Nov 24 02:35:59 minna kernel: ds: 007b es: 007b ss: 0068
Nov 24 02:35:59 minna kernel: Process kcopyd (pid: 1675,
threadinfo=c72fa000 task=c80e3330)
Nov 24 02:35:59 minna kernel: Stack: d09be011 00000077 00000000 c80e3330
c0121070 00000000 00000000 00000001
Nov 24 02:35:59 minna kernel: c7bcfeec c0109a42 00000000 c80e3330
c0121070 00100100 00200200 00000000
Nov 24 02:35:59 minna kernel: 00000000 00000000 d09bd9d0 00000000
00000000 00000000 c0107349 d09c27e0
Nov 24 02:35:59 minna kernel: Call Trace:
Nov 24 02:35:59 minna kernel: [<c0121070>] default_wake_function+0x0/0x30
Nov 24 02:35:59 minna kernel: [<c0109a42>] ret_from_fork+0x6/0x14
Nov 24 02:35:59 minna kernel: [<c0121070>] default_wake_function+0x0/0x30
Nov 24 02:35:59 minna kernel: [<c0107349>] kernel_thread_helper+0x5/0xc
Nov 24 02:35:59 minna kernel:
Nov 24 02:35:59 minna kernel: Code: Bad EIP value.
The attached patch (rmmod_daemon.patch) fixes this by replacing the
semaphores with completions, and uses complete_and_exit() to make
sure the daemon thread is completely broken down before exiting the
module (complete() passes 1 for the sync variable to __wake_up_common()
where up() passes zero).
The patch was built and tested against 2.6.0-test9-udm5.
Mike Christie
mikenc@xxxxxxxxxx
diff -aup linux-2.6.0-test9/drivers/md/dm-daemon.c linux-2.6.0-test9-dm/drivers/md/dm-daemon.c
--- linux-2.6.0-test9/drivers/md/dm-daemon.c 2003-11-24 03:23:32.367176348 -0800
+++ linux-2.6.0-test9-dm/drivers/md/dm-daemon.c 2003-11-24 03:25:12.573082455 -0800
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/suspend.h>
+#include <linux/completion.h>
static int daemon(void *arg)
{
@@ -22,8 +23,7 @@ static int daemon(void *arg)
add_wait_queue(&dd->job_queue, &wq);
- down(&dd->run_lock);
- up(&dd->start_lock);
+ complete(&dd->start);
/*
* dd->fn() could do anything, very likely it will
@@ -55,8 +55,7 @@ static int daemon(void *arg)
out:
remove_wait_queue(&dd->job_queue, &wq);
- up(&dd->run_lock);
- return 0;
+ complete_and_exit(&dd->run, 0);
}
int dm_daemon_start(struct dm_daemon *dd, const char *name, void (*fn)(void))
@@ -68,14 +67,13 @@ int dm_daemon_start(struct dm_daemon *dd
*/
dd->fn = fn;
strncpy(dd->name, name, sizeof(dd->name) - 1);
- sema_init(&dd->start_lock, 1);
- sema_init(&dd->run_lock, 1);
+ init_completion(&dd->start);
+ init_completion(&dd->run);
init_waitqueue_head(&dd->job_queue);
/*
* Start the new thread.
*/
- down(&dd->start_lock);
pid = kernel_thread(daemon, dd, CLONE_KERNEL);
if (pid <= 0) {
DMERR("Failed to start %s thread", name);
@@ -85,8 +83,7 @@ int dm_daemon_start(struct dm_daemon *dd
/*
* wait for the daemon to up this mutex.
*/
- down(&dd->start_lock);
- up(&dd->start_lock);
+ wait_for_completion(&dd->start);
return 0;
}
@@ -95,8 +92,7 @@ void dm_daemon_stop(struct dm_daemon *dd
{
atomic_set(&dd->please_die, 1);
dm_daemon_wake(dd);
- down(&dd->run_lock);
- up(&dd->run_lock);
+ wait_for_completion(&dd->run);
}
void dm_daemon_wake(struct dm_daemon *dd)
diff -aup linux-2.6.0-test9/drivers/md/dm-daemon.h linux-2.6.0-test9-dm/drivers/md/dm-daemon.h
--- linux-2.6.0-test9/drivers/md/dm-daemon.h 2003-11-24 03:23:32.367176348 -0800
+++ linux-2.6.0-test9-dm/drivers/md/dm-daemon.h 2003-11-24 03:20:10.641776035 -0800
@@ -8,14 +8,14 @@
#define DM_DAEMON_H
#include <asm/atomic.h>
-#include <asm/semaphore.h>
+#include <linux/completion.h>
struct dm_daemon {
void (*fn)(void);
char name[16];
atomic_t please_die;
- struct semaphore start_lock;
- struct semaphore run_lock;
+ struct completion start;
+ struct completion run;
atomic_t woken;
wait_queue_head_t job_queue;