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