lkml.org 
[lkml]   [2000]   [Sep]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: DAC960 SMP deadlock fix
On Thu, 7 Sep 2000, Leonard N. Zubkoff wrote:

>I tried retrieving that file but was unsuccessful; is that the correct URL?

I guess I cut and pasted too much directories, sorry. I attached the file
since it's small.

>Is the fix simply moving the spin_unlock right before the call to
>add_wait_queue?

A little more, we also have to make sure not to miss events and the
__wait_event interfaces addersses that second issue.

>I should be able to release a new driver very shortly with such a fix; I
>just have one or two other minor nits I'm finishing up.

Good, thanks!

Andrea
After reading the two NMI dumps and the assembler of the .text.lock
section of the vmlinux ELF image I think I found it.

It seems a regular SMP lock inversion in the DAC960 driver that is
acquiring the waitqueue_lock with the io_request_lock still acquired. Here
the trace that I deducted:

CPU0 CPU1
------------------ ---------------
spin_lock_irqsave(&io_request_lock)
DAC9xx_request_fn()
wake_up(something...)
read_lock(&waitqueue_lock)
aic7xxx_irq_handler()
DAC9xx_WaitForCommand()
add_to_wait_queue(something....)
write_lock_irqsave(&waitqueue_lock)
/* hanging because of the read_lock
on the other side */
spin_lock_irqsave(&io_request_lock)
/* hanging because it's
acquired from the other
side */

/* DEADLOCK */

Here the fix (uncompiled and untested):

--- 2.2.18pre2aa2/drivers/block/DAC960.c Wed Aug 30 03:42:29 2000
+++ /tmp/DAC960.c Thu Sep 7 02:10:39 2000
@@ -310,13 +310,8 @@

static void DAC960_WaitForCommand(DAC960_Controller_T *Controller)
{
- WaitQueue_T WaitQueueEntry = { current, NULL };
- add_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
- current->state = TASK_UNINTERRUPTIBLE;
spin_unlock(&io_request_lock);
- schedule();
- current->state = TASK_RUNNING;
- remove_wait_queue(&Controller->CommandWaitQueue, &WaitQueueEntry);
+ __wait_event(Controller->CommandWaitQueue, Controller->FreeCommands);
spin_lock_irq(&io_request_lock);
}
\
 
 \ /
  Last update: 2005-03-22 12:38    [W:0.044 / U:0.132 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site