]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-block.patch
- take from suse kernel-source-2.6.22.5-31.src.rpm -> patches.fixes.tar.bz2 -> patche...
[packages/kernel.git] / kernel-block.patch
1 commit 6eca9004dfcb274a502438a591df5b197690afb1
2 Author: Jens Axboe <jens.axboe@oracle.com>
3 Date:   Thu Oct 25 10:14:47 2007 +0200
4
5     [BLOCK] Fix bad sharing of tag busy list on queues with shared tag maps
6     
7     For the locking to work, only the tag map and tag bit map may be shared
8     (incidentally, I was just explaining this to Nick yesterday, but I
9     apparently didn't review the code well enough myself). But we also share
10     the busy list!  The busy_list must be queue private, or we need a
11     block_queue_tag covering lock as well.
12     
13     So we have to move the busy_list to the queue. This'll work fine, and
14     it'll actually also fix a problem with blk_queue_invalidate_tags() which
15     will invalidate tags across all shared queues. This is a bit confusing,
16     the low level driver should call it for each queue seperately since
17     otherwise you cannot kill tags on just a single queue for eg a hard
18     drive that stops responding. Since the function has no callers
19     currently, it's not an issue.
20     
21     Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
22
23 diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
24 index a8a1810..56f2646 100644
25 --- a/block/ll_rw_blk.c
26 +++ b/block/ll_rw_blk.c
27 @@ -791,7 +791,6 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)
28         retval = atomic_dec_and_test(&bqt->refcnt);
29         if (retval) {
30                 BUG_ON(bqt->busy);
31 -               BUG_ON(!list_empty(&bqt->busy_list));
32  
33                 kfree(bqt->tag_index);
34                 bqt->tag_index = NULL;
35 @@ -903,7 +902,6 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct request_queue *q,
36         if (init_tag_map(q, tags, depth))
37                 goto fail;
38  
39 -       INIT_LIST_HEAD(&tags->busy_list);
40         tags->busy = 0;
41         atomic_set(&tags->refcnt, 1);
42         return tags;
43 @@ -954,6 +952,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
44          */
45         q->queue_tags = tags;
46         q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
47 +       INIT_LIST_HEAD(&q->tag_busy_list);
48         return 0;
49  fail:
50         kfree(tags);
51 @@ -1122,7 +1121,7 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
52         rq->tag = tag;
53         bqt->tag_index[tag] = rq;
54         blkdev_dequeue_request(rq);
55 -       list_add(&rq->queuelist, &bqt->busy_list);
56 +       list_add(&rq->queuelist, &q->tag_busy_list);
57         bqt->busy++;
58         return 0;
59  }
60 @@ -1143,11 +1142,10 @@ EXPORT_SYMBOL(blk_queue_start_tag);
61   **/
62  void blk_queue_invalidate_tags(struct request_queue *q)
63  {
64 -       struct blk_queue_tag *bqt = q->queue_tags;
65         struct list_head *tmp, *n;
66         struct request *rq;
67  
68 -       list_for_each_safe(tmp, n, &bqt->busy_list) {
69 +       list_for_each_safe(tmp, n, &q->tag_busy_list) {
70                 rq = list_entry_rq(tmp);
71  
72                 if (rq->tag == -1) {
73 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
74 index bbf906a..8396db2 100644
75 --- a/include/linux/blkdev.h
76 +++ b/include/linux/blkdev.h
77 @@ -341,7 +341,6 @@ enum blk_queue_state {
78  struct blk_queue_tag {
79         struct request **tag_index;     /* map of busy tags */
80         unsigned long *tag_map;         /* bit map of free/busy tags */
81 -       struct list_head busy_list;     /* fifo list of busy tags */
82         int busy;                       /* current depth */
83         int max_depth;                  /* what we will send to device */
84         int real_max_depth;             /* what the array can hold */
85 @@ -435,6 +434,7 @@ struct request_queue
86         unsigned int            dma_alignment;
87  
88         struct blk_queue_tag    *queue_tags;
89 +       struct list_head        tag_busy_list;
90  
91         unsigned int            nr_sorted;
92         unsigned int            in_flight;
This page took 0.04042 seconds and 3 git commands to generate.