]> git.pld-linux.org Git - packages/kernel.git/blob - kernel-scsi-corruption.patch
- fetch 2.6.37; .36 is on LINUX_2_6_36
[packages/kernel.git] / kernel-scsi-corruption.patch
1 >>>>> "Jens" == Jens Axboe <jaxboe@fusionio.com> writes:
2
3 Jens> Great, the two different values and needing to sync them was
4 Jens> horrible.  What kind of testing did you do? Have to be a little
5 Jens> extra careful at this point.
6
7 Yeah, we should probably let it soak a bit in -next just to make sure.
8
9 There really aren't many devices from this millennium that don't support
10 clustering. Which I guess is why we haven't seen any problems.
11
12 I ended up disabling clustering in one of the FC drivers to test with a
13 real workload. Threw in a BUG_ON(nsegs > queue_max_segments(q)) for good
14 measure.
15
16 I also tested mixing and matching clustered and non-clustered bottom
17 devices while stacking with DM.
18
19 New version below, fixing the things you and Matthew pointed out...
20
21
22
23 block: Deprecate QUEUE_FLAG_CLUSTER and use queue_limits instead
24
25 When stacking devices, a request_queue is not always available. This
26 forced us to have a no_cluster flag in the queue_limits that could be
27 used as a carrier until the request_queue had been set up for a
28 metadevice.
29
30 There were several problems with that approach. First of all it was up
31 to the stacking device to remember to set queue flag after stacking had
32 completed. Also, the queue flag and the queue limits had to be kept in
33 sync at all times. We got that wrong, which could lead to us issuing
34 commands that went beyond the max scatterlist limit set by the driver.
35
36 The proper fix is to avoid having two flags for tracking the same thing.
37 We deprecate QUEUE_FLAG_CLUSTER and use the queue limit directly in the
38 block layer merging functions. The queue_limit 'no_cluster' is turned
39 into 'cluster' to avoid double negatives and to ease stacking.
40 Clustering defaults to being enabled as before. The queue flag logic is
41 removed from the stacking function, and explicitly setting the cluster
42 flag is no longer necessary in DM and MD.
43
44 Reported-by: Ed Lin <ed.lin@promise.com>
45 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
46
47 diff --git a/block/blk-merge.c b/block/blk-merge.c
48 index 77b7c26..74bc4a7 100644
49 --- a/block/blk-merge.c
50 +++ b/block/blk-merge.c
51 @@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
52                 return 0;
53  
54         fbio = bio;
55 -       cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
56 +       cluster = blk_queue_cluster(q);
57         seg_size = 0;
58         nr_phys_segs = 0;
59         for_each_bio(bio) {
60 @@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments);
61  static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
62                                    struct bio *nxt)
63  {
64 -       if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
65 +       if (!blk_queue_cluster(q))
66                 return 0;
67  
68         if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
69 @@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
70         int nsegs, cluster;
71  
72         nsegs = 0;
73 -       cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
74 +       cluster = blk_queue_cluster(q);
75  
76         /*
77          * for each bio in rq
78 diff --git a/block/blk-settings.c b/block/blk-settings.c
79 index 701859f..e55f5fc 100644
80 --- a/block/blk-settings.c
81 +++ b/block/blk-settings.c
82 @@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim)
83         lim->alignment_offset = 0;
84         lim->io_opt = 0;
85         lim->misaligned = 0;
86 -       lim->no_cluster = 0;
87 +       lim->cluster = 1;
88  }
89  EXPORT_SYMBOL(blk_set_default_limits);
90  
91 @@ -464,15 +464,6 @@ EXPORT_SYMBOL(blk_queue_io_opt);
92  void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b)
93  {
94         blk_stack_limits(&t->limits, &b->limits, 0);
95 -
96 -       if (!t->queue_lock)
97 -               WARN_ON_ONCE(1);
98 -       else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
99 -               unsigned long flags;
100 -               spin_lock_irqsave(t->queue_lock, flags);
101 -               queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
102 -               spin_unlock_irqrestore(t->queue_lock, flags);
103 -       }
104  }
105  EXPORT_SYMBOL(blk_queue_stack_limits);
106  
107 @@ -545,7 +536,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
108         t->io_min = max(t->io_min, b->io_min);
109         t->io_opt = lcm(t->io_opt, b->io_opt);
110  
111 -       t->no_cluster |= b->no_cluster;
112 +       t->cluster &= b->cluster;
113         t->discard_zeroes_data &= b->discard_zeroes_data;
114  
115         /* Physical block size a multiple of the logical block size? */
116 @@ -641,7 +632,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
117                        sector_t offset)
118  {
119         struct request_queue *t = disk->queue;
120 -       struct request_queue *b = bdev_get_queue(bdev);
121  
122         if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) {
123                 char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE];
124 @@ -652,17 +642,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev,
125                 printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n",
126                        top, bottom);
127         }
128 -
129 -       if (!t->queue_lock)
130 -               WARN_ON_ONCE(1);
131 -       else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
132 -               unsigned long flags;
133 -
134 -               spin_lock_irqsave(t->queue_lock, flags);
135 -               if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags))
136 -                       queue_flag_clear(QUEUE_FLAG_CLUSTER, t);
137 -               spin_unlock_irqrestore(t->queue_lock, flags);
138 -       }
139  }
140  EXPORT_SYMBOL(disk_stack_limits);
141  
142 diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
143 index 013457f..41fb691 100644
144 --- a/block/blk-sysfs.c
145 +++ b/block/blk-sysfs.c
146 @@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *
147  
148  static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
149  {
150 -       if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
151 +       if (blk_queue_cluster(q))
152                 return queue_var_show(queue_max_segment_size(q), (page));
153  
154         return queue_var_show(PAGE_CACHE_SIZE, (page));
155 diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
156 index 90267f8..e2da191 100644
157 --- a/drivers/md/dm-table.c
158 +++ b/drivers/md/dm-table.c
159 @@ -1131,11 +1131,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
160          */
161         q->limits = *limits;
162  
163 -       if (limits->no_cluster)
164 -               queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
165 -       else
166 -               queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
167 -
168         if (!dm_table_supports_discards(t))
169                 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
170         else
171 diff --git a/drivers/md/md.c b/drivers/md/md.c
172 index 84c46a1..52694d2 100644
173 --- a/drivers/md/md.c
174 +++ b/drivers/md/md.c
175 @@ -4296,9 +4296,6 @@ static int md_alloc(dev_t dev, char *name)
176                 goto abort;
177         mddev->queue->queuedata = mddev;
178  
179 -       /* Can be unlocked because the queue is new: no concurrency */
180 -       queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
181 -
182         blk_queue_make_request(mddev->queue, md_make_request);
183  
184         disk = alloc_disk(1 << shift);
185 diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
186 index b55b0ec..3852e51 100644
187 --- a/drivers/scsi/scsi_lib.c
188 +++ b/drivers/scsi/scsi_lib.c
189 @@ -1643,9 +1643,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
190  
191         blk_queue_max_segment_size(q, dma_get_max_seg_size(dev));
192  
193 -       /* New queue, no concurrency on queue_flags */
194         if (!shost->use_clustering)
195 -               queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
196 +               q->limits.cluster = 0;
197  
198         /*
199          * set a reasonable default alignment on word boundaries: the
200 diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
201 index aae86fd..95aeeeb 100644
202 --- a/include/linux/blkdev.h
203 +++ b/include/linux/blkdev.h
204 @@ -250,7 +250,7 @@ struct queue_limits {
205  
206         unsigned char           misaligned;
207         unsigned char           discard_misaligned;
208 -       unsigned char           no_cluster;
209 +       unsigned char           cluster;
210         signed char             discard_zeroes_data;
211  };
212  
213 @@ -380,7 +380,6 @@ struct request_queue
214  #endif
215  };
216  
217 -#define QUEUE_FLAG_CLUSTER     0       /* cluster several segments into 1 */
218  #define QUEUE_FLAG_QUEUED      1       /* uses generic tag queueing */
219  #define QUEUE_FLAG_STOPPED     2       /* queue is stopped */
220  #define        QUEUE_FLAG_SYNCFULL     3       /* read queue has been filled */
221 @@ -403,7 +402,6 @@ struct request_queue
222  #define QUEUE_FLAG_SECDISCARD  19      /* supports SECDISCARD */
223  
224  #define QUEUE_FLAG_DEFAULT     ((1 << QUEUE_FLAG_IO_STAT) |            \
225 -                                (1 << QUEUE_FLAG_CLUSTER) |            \
226                                  (1 << QUEUE_FLAG_STACKABLE)    |       \
227                                  (1 << QUEUE_FLAG_SAME_COMP)    |       \
228                                  (1 << QUEUE_FLAG_ADD_RANDOM))
229 @@ -510,6 +508,11 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
230  
231  #define rq_data_dir(rq)                ((rq)->cmd_flags & 1)
232  
233 +static inline unsigned int blk_queue_cluster(struct request_queue *q)
234 +{
235 +       return q->limits.cluster;
236 +}
237 +
238  /*
239   * We regard a request as sync, if either a read or a sync write
240   */
241
242
243 --
244 dm-devel mailing list
245 dm-devel@redhat.com
246 https://www.redhat.com/mailman/listinfo/dm-devel
This page took 0.052922 seconds and 3 git commands to generate.