lkml.org 
[lkml]   [2004]   [Feb]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: [BUG] AIC7*** SMP deadlock in ahc_linux_free_device
Herbert Xu <herbert@gondor.apana.org.au> wrote:
>
> The del_timer_sync call in ahc_linux_free_device added in 2.5.67
> leads to an SMP deadlock when the function is called from the timer
> itself in ahc_linux_dev_timed_unfreeze.

Yup, that will deadlock every time on SMP. The below should fix it.

> I haven't dug too deeply but it seems that there are also possible
> races where ahc_linux_free_device can be called twice on the same
> dev. Once from the timer and then again from a non-timer location.

Possibly, although it might be the case that external locking and
refcounting prevent this from happening (hopes).



diff -puN drivers/scsi/aic7xxx/aic7xxx_osm.c~aic7xxx-deadlock-fix drivers/scsi/aic7xxx/aic7xxx_osm.c
--- 25/drivers/scsi/aic7xxx/aic7xxx_osm.c~aic7xxx-deadlock-fix Tue Feb 17 17:21:44 2004
+++ 25-akpm/drivers/scsi/aic7xxx/aic7xxx_osm.c Tue Feb 17 17:21:44 2004
@@ -3969,11 +3969,10 @@ ahc_linux_alloc_device(struct ahc_softc
}

static void
-ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+__ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
{
struct ahc_linux_target *targ;

- del_timer_sync(&dev->timer);
targ = dev->target;
targ->devices[dev->lun] = NULL;
free(dev, M_DEVBUF);
@@ -3983,6 +3982,13 @@ ahc_linux_free_device(struct ahc_softc *
ahc_linux_free_target(ahc, targ);
}

+static void
+ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev)
+{
+ del_timer_sync(&dev->timer);
+ __ahc_linux_free_device(ahc, dev);
+}
+
void
ahc_send_async(struct ahc_softc *ahc, char channel,
u_int target, u_int lun, ac_code code, void *arg)
@@ -4693,7 +4699,7 @@ ahc_linux_dev_timed_unfreeze(u_long arg)
ahc_linux_run_device_queue(ahc, dev);
if (TAILQ_EMPTY(&dev->busyq)
&& dev->active == 0)
- ahc_linux_free_device(ahc, dev);
+ __ahc_linux_free_device(ahc, dev);
ahc_unlock(ahc, &s);
}

_

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 14:01    [from the cache]
©2003-2011 Jasper Spaans