[PARPORT] [patch] parport waitlist oops

From: Tim Waugh (twaugh@redhat.com)
Date: Wed Aug 08 2001 - 09:53:20 EDT

  • Next message: Kurt Roeckx: "[PARPORT] ECP+EPP mode"

    Hey, take a look at this patch. The bad news is that we can't just
    wander along the wait list without a lock. I don't know if the
    supplied wakeup function is allowed to call parport_release or
    parport_unregister_device: if so then it's awkward since we might
    deadlock.

    Tim.
    */

    --- linux/drivers/scsi/imm.c.oops Wed Aug 8 13:54:51 2001
    +++ linux/drivers/scsi/imm.c Wed Aug 8 13:55:15 2001
    @@ -162,6 +162,7 @@
                         printk(KERN_ERR "imm%d: failed to claim parport because a "
                           "pardevice is owning the port for too longtime!\n",
                                i);
    + parport_unregister_device (imm_hosts[i].dev);
                         spin_lock_irq(&io_request_lock);
                         return 0;
                     }
    --- linux/drivers/scsi/ppa.c.oops Wed Aug 8 14:41:32 2001
    +++ linux/drivers/scsi/ppa.c Wed Aug 8 14:41:54 2001
    @@ -153,6 +153,7 @@
                         printk(KERN_ERR "ppa%d: failed to claim parport because a "
                           "pardevice is owning the port for too longtime!\n",
                                i);
    + parport_unregister_device(ppa_hosts[i].dev);
                         spin_lock_irq(&io_request_lock);
                         return 0;
                     }
    --- linux/drivers/parport/share.c.oops Wed Aug 8 14:11:49 2001
    +++ linux/drivers/parport/share.c Wed Aug 8 14:41:03 2001
    @@ -782,6 +782,21 @@
     
             spin_unlock(&port->pardevice_lock);
     
    + /* Make sure we haven't left any pointers around in the wait
    + * list. */
    + spin_lock (&port->waitlist_lock);
    + if (dev->waitprev || dev->waitnext || port->waithead == dev) {
    + if (dev->waitprev)
    + dev->waitprev->waitnext = dev->waitnext;
    + else
    + port->waithead = dev->waitnext;
    + if (dev->waitnext)
    + dev->waitnext->waitprev = dev->waitprev;
    + else
    + port->waittail = dev->waitprev;
    + }
    + spin_unlock (&port->waitlist_lock);
    +
             kfree(dev->state);
             kfree(dev);
     
    @@ -1063,6 +1078,7 @@
     
             /* If anybody is waiting, find out who's been there longest and
                then wake them up. (Note: no locking required) */
    + /* !!! LOCKING IS NEEDED HERE */
             for (pd = port->waithead; pd; pd = pd->waitnext) {
                     if (pd->waiting & 2) { /* sleeping in claim_or_block */
                             parport_claim(pd);
    @@ -1080,6 +1096,7 @@
     
             /* Nobody was waiting, so walk the list to see if anyone is
                interested in being woken up. (Note: no locking required) */
    + /* !!! LOCKING IS NEEDED HERE */
             for (pd = port->devices; (port->cad == NULL) && pd; pd = pd->next) {
                     if (pd->wakeup && pd != dev)
                             pd->wakeup(pd->private);
    --- linux/drivers/parport/ChangeLog.oops Wed Aug 8 14:43:38 2001
    +++ linux/drivers/parport/ChangeLog Wed Aug 8 14:44:37 2001
    @@ -0,0 +1,5 @@
    +2001-08-08 Tim Waugh <twaugh@redhat.com>
    +
    + * share.c (parport_unregister_device): Remove device from wait list
    + too.
    +

    -- To unsubscribe, send mail to: linux-parport-request@torque.net --
    -- with the single word "unsubscribe" in the body of the message. --



    This archive was generated by hypermail 2b29 : Wed Aug 08 2001 - 10:08:18 EDT