Bug 19065 - insmod fails to return after installing loop.o
insmod fails to return after installing loop.o
Status: CLOSED ERRATA
Product: Red Hat Linux
Classification: Retired
Component: kernel (Show other bugs)
7.0
i386 Linux
medium Severity medium
: ---
: ---
Assigned To: Michael K. Johnson
Brock Organ
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2000-10-13 13:33 EDT by tjfalcone
Modified: 2007-04-18 12:29 EDT (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2000-10-14 15:24:24 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description tjfalcone 2000-10-13 13:33:23 EDT
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 15:21:50 EDT
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 15:24:21 EDT
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 15:17:11 EST
Fixed in errata kernel

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