SOURCES (LINUX_2_6): linux-blk-race.patch (NEW), linux-stex.patch ...

arekm arekm at pld-linux.org
Thu Sep 13 23:24:01 CEST 2007


Author: arekm                        Date: Thu Sep 13 21:24:01 2007 GMT
Module: SOURCES                       Tag: LINUX_2_6
---- Log message:
- fix bug not symptoms

---- Files affected:
SOURCES:
   linux-blk-race.patch (NONE -> 1.1)  (NEW), linux-stex.patch (1.1.2.1 -> NONE)  (REMOVED)

---- Diffs:

================================================================
Index: SOURCES/linux-blk-race.patch
diff -u /dev/null SOURCES/linux-blk-race.patch:1.1
--- /dev/null	Thu Sep 13 23:24:01 2007
+++ SOURCES/linux-blk-race.patch	Thu Sep 13 23:23:56 2007
@@ -0,0 +1,57 @@
+commit f3da54ba140c6427fa4a32913e1bf406f41b5dda
+Author: Jens Axboe <jens.axboe at oracle.com>
+Date:   Thu Sep 13 14:26:53 2007 +0200
+
+    Fix race with shared tag queue maps
+    
+    There's a race condition in blk_queue_end_tag() for shared tag maps,
+    users include stex (promise supertrak thingy) and qla2xxx.  The former
+    at least has reported bugs in this area, not sure why we haven't seen
+    any for the latter.  It could be because the window is narrow and that
+    other conditions in the qla2xxx code hide this.  It's a real bug,
+    though, as the stex smp users can attest.
+    
+    We need to ensure two things - the tag bit clearing needs to happen
+    AFTER we cleared the tag pointer, as the tag bit clearing/setting is
+    what protects this map.  Secondly, we need to ensure that the visibility
+    of the tag pointer and tag bit clear are ordered properly.
+    
+    [ I removed the SMP barriers - "test_and_clear_bit()" already implies
+      all the required barriers.  -- Linus ]
+    
+    Also see http://bugzilla.kernel.org/show_bug.cgi?id=7842
+    
+    Signed-off-by: Jens Axboe <jens.axboe at oracle.com>
+    Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
+
+diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
+index a15845c..cd20367 100644
+--- a/block/ll_rw_blk.c
++++ b/block/ll_rw_blk.c
+@@ -1075,12 +1075,6 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
+ 		 */
+ 		return;
+ 
+-	if (unlikely(!__test_and_clear_bit(tag, bqt->tag_map))) {
+-		printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
+-		       __FUNCTION__, tag);
+-		return;
+-	}
+-
+ 	list_del_init(&rq->queuelist);
+ 	rq->cmd_flags &= ~REQ_QUEUED;
+ 	rq->tag = -1;
+@@ -1090,6 +1084,13 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
+ 		       __FUNCTION__, tag);
+ 
+ 	bqt->tag_index[tag] = NULL;
++
++	if (unlikely(!test_and_clear_bit(tag, bqt->tag_map))) {
++		printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
++		       __FUNCTION__, tag);
++		return;
++	}
++
+ 	bqt->busy--;
+ }
+ 
================================================================


More information about the pld-cvs-commit mailing list