Author: will
Date: Wed Jan 21 20:02:16 2015
New Revision: 277507
URL: https://svnweb.freebsd.org/changeset/base/277507

Log:
  Fix a FWXF_INQ race in the firewire driver.
  
  sys/dev/firewire/firewire.c:
        In fw_xfer_unload() expand lock coverage so that
        the test for FWXF_INQ doesn't race with it being
        cleared in another thread.
  
  Submitted by: gibbs
  MFC after:    1 week
  Sponsored by: Spectra Logic
  MFSpectraBSD: 1110207 on 2015/01/02

Modified:
  head/sys/dev/firewire/firewire.c

Modified: head/sys/dev/firewire/firewire.c
==============================================================================
--- head/sys/dev/firewire/firewire.c    Wed Jan 21 19:59:09 2015        
(r277506)
+++ head/sys/dev/firewire/firewire.c    Wed Jan 21 20:02:16 2015        
(r277507)
@@ -1022,9 +1022,7 @@ static void
 fw_tl_free(struct firewire_comm *fc, struct fw_xfer *xfer)
 {
        struct fw_xfer *txfer;
-       int s;
 
-       s = splfw();
        mtx_lock(&fc->tlabel_lock);
        if (xfer->tl < 0) {
                mtx_unlock(&fc->tlabel_lock);
@@ -1042,14 +1040,12 @@ fw_tl_free(struct firewire_comm *fc, str
                fw_dump_hdr(&xfer->recv.hdr, "recv");
                kdb_backtrace();
                mtx_unlock(&fc->tlabel_lock);
-               splx(s);
                return;
        }
 
        STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel);
        xfer->tl = -1;
        mtx_unlock(&fc->tlabel_lock);
-       splx(s);
        return;
 }
 
@@ -1157,22 +1153,18 @@ fw_xfer_done(struct fw_xfer *xfer)
 void
 fw_xfer_unload(struct fw_xfer *xfer)
 {
-       int s;
 
        if (xfer == NULL)
                return;
+       FW_GLOCK(xfer->fc);
        if (xfer->flag & FWXF_INQ) {
-               printf("fw_xfer_free FWXF_INQ\n");
-               s = splfw();
-               FW_GLOCK(xfer->fc);
                STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
                xfer->flag &= ~FWXF_INQ;
 #if 0
                xfer->q->queued--;
 #endif
-               FW_GUNLOCK(xfer->fc);
-               splx(s);
        }
+       FW_GUNLOCK(xfer->fc);
        if (xfer->fc != NULL) {
                /*
                 * Ensure that any tlabel owner can't access this
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to