Bug 19065 - insmod fails to return after installing loop.o
Summary: insmod fails to return after installing loop.o
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Linux
Classification: Retired
Component: kernel
Version: 7.0
Hardware: i386
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Michael K. Johnson
QA Contact: Brock Organ
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2000-10-13 17:33 UTC by tjfalcone
Modified: 2007-04-18 16:29 UTC (History)
3 users (show)

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2000-10-14 19:24:24 UTC
Embargoed:


Attachments (Terms of Use)

Description tjfalcone 2000-10-13 17:33:23 UTC
Whenever the loop.o module is installed, either "manually" via a call to
insmod, or automagically via modprobe (which will in turn call insmod), the
module is installed, but the insmod process does not terminate.  Instead,
insmod enters the "uninterruptable sleep" state (denoted by D in a ps aux
listing).  This drives up the load average by one.  Moreover, since the
module is autocleaned by default, every subsequent call of insmod by
modprobe results in a new instance of insmod, which continues to drive the
load average ever higher.

Anyone know why insmod stays asleep forever after installing loop.o?  Even
when loop.o is removed, it continues to do this...

Comment 1 Arjan van de Ven 2000-10-14 19:21:50 UTC
I have made a patch that fixes this for me. I'll attach it to this bug; if you
want to/can test it,
I'd appreciate feedback.

Comment 2 Arjan van de Ven 2000-10-14 19:24:21 UTC
I can't attach a file to this bug, it seems. Patch at
http://www.fenrus.demon.nl/loop.diff 
and copy-n-pasted below (spaces vs tabs, so it might not apply, use the one in
the url)
--- linux/drivers/block/loop.c.org      Sat Oct 14 21:01:32 2000
+++ linux//drivers/block/loop.c Sat Oct 14 21:22:15 2000
@@ -883,13 +883,18 @@
 EXPORT_SYMBOL(loop_register_transfer);
 EXPORT_SYMBOL(loop_unregister_transfer);

+static volatile int loopd_running = 0; /* Ugly/hackish refcount hack */
+static volatile int stop_loopd = 0; /* Ugly/hackish internal signal */
+
 static int loopd (void *unused)
 {
        struct wait_queue wait = { current, NULL };

        lock_kernel();
+       loopd_running = 1;
        /* printk("loopback system thread started ...\n"); */
        strcpy(current->comm, "loopd");
+       exit_mm(current);
        init_waitqueue(&loopd_wait);
        init_waitqueue(&loopd_done_wait);

@@ -903,6 +908,7 @@
        if (!async_queue) {
                spin_unlock_irq(&io_request_lock);
                wake_up(&loopd_done_wait);
+               current->state = TASK_INTERRUPTIBLE;
                schedule();
                spin_lock_irq(&io_request_lock);
        }
@@ -910,7 +916,10 @@
        remove_wait_queue(&loopd_wait, &wait);
        current->state = TASK_RUNNING;

-       goto repeat;
+       if (!stop_loopd)
+               goto repeat;
+       spin_unlock_irq(&io_request_lock);
+       loopd_running = 0;

        return 0;
 }
@@ -949,7 +958,18 @@
 #ifdef MODULE
 void cleanup_module (void)
 {
+       int count=0;
        if (unregister_blkdev(MAJOR_NR, "loop"))
                printk(KERN_WARNING "loop: cannot unregister blkdev\n");
+       stop_loopd = 1;
+       while (loopd_running) {
+               count++;
+               wake_up(&loopd_wait);
+               current->state = TASK_RUNNING;
+               schedule();
+               if (count>50)
+                       break; /* uh oh. but prevent an infinite loop */
+       }
+
 }
 #endif



Comment 3 Arjan van de Ven 2001-02-09 20:17:11 UTC
Fixed in errata kernel


Note You need to log in before you can comment on or make changes to this bug.