1 >>>>> "Jens" == Jens Axboe <jaxboe@fusionio.com> writes:
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.
7 Yeah, we should probably let it soak a bit in -next just to make sure.
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.
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
16 I also tested mixing and matching clustered and non-clustered bottom
17 devices while stacking with DM.
19 New version below, fixing the things you and Matthew pointed out...
23 block: Deprecate QUEUE_FLAG_CLUSTER and use queue_limits instead
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
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.
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.
44 Reported-by: Ed Lin <ed.lin@promise.com>
45 Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
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,
55 - cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
56 + cluster = blk_queue_cluster(q);
60 @@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments);
61 static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
64 - if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags))
65 + if (!blk_queue_cluster(q))
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,
73 - cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
74 + cluster = blk_queue_cluster(q);
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;
86 - lim->no_cluster = 0;
89 EXPORT_SYMBOL(blk_set_default_limits);
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)
94 blk_stack_limits(&t->limits, &b->limits, 0);
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);
105 EXPORT_SYMBOL(blk_queue_stack_limits);
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);
111 - t->no_cluster |= b->no_cluster;
112 + t->cluster &= b->cluster;
113 t->discard_zeroes_data &= b->discard_zeroes_data;
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,
119 struct request_queue *t = disk->queue;
120 - struct request_queue *b = bdev_get_queue(bdev);
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",
129 - if (!t->queue_lock)
131 - else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) {
132 - unsigned long flags;
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);
140 EXPORT_SYMBOL(disk_stack_limits);
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 *
148 static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
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));
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,
163 - if (limits->no_cluster)
164 - queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q);
166 - queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q);
168 if (!dm_table_supports_discards(t))
169 queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q);
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)
177 mddev->queue->queuedata = mddev;
179 - /* Can be unlocked because the queue is new: no concurrency */
180 - queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
182 blk_queue_make_request(mddev->queue, md_make_request);
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,
191 blk_queue_max_segment_size(q, dma_get_max_seg_size(dev));
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;
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 {
206 unsigned char misaligned;
207 unsigned char discard_misaligned;
208 - unsigned char no_cluster;
209 + unsigned char cluster;
210 signed char discard_zeroes_data;
213 @@ -380,7 +380,6 @@ struct request_queue
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 */
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)
231 #define rq_data_dir(rq) ((rq)->cmd_flags & 1)
233 +static inline unsigned int blk_queue_cluster(struct request_queue *q)
235 + return q->limits.cluster;
239 * We regard a request as sync, if either a read or a sync write
244 dm-devel mailing list
246 https://www.redhat.com/mailman/listinfo/dm-devel