diff options
author | Jens Axboe <axboe@kernel.dk> | 2018-10-12 12:03:14 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-10-14 14:47:52 -0400 |
commit | 3582dd291788e9441c3ba9047e55089edb98da5c (patch) | |
tree | 8500bb8ba0ff66fc3bb5d3ffb1bd8bed66f73d3c | |
parent | e01ad46d53b59720c6ae69963ee1756506954c85 (diff) |
aoe: convert aoeblk to blk-mq
Straight forward conversion - instead of rewriting the internal buffer
retrieval logic, just replace the previous elevator peeking with an
internal list of requests.
Reviewed-by: "Ed L. Cashin" <ed.cashin@acm.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | drivers/block/aoe/aoe.h | 4 | ||||
-rw-r--r-- | drivers/block/aoe/aoeblk.c | 49 | ||||
-rw-r--r-- | drivers/block/aoe/aoecmd.c | 19 | ||||
-rw-r--r-- | drivers/block/aoe/aoedev.c | 14 |
4 files changed, 61 insertions, 25 deletions
diff --git a/drivers/block/aoe/aoe.h b/drivers/block/aoe/aoe.h index 015c68017a1c..7ca76ed2e71a 100644 --- a/drivers/block/aoe/aoe.h +++ b/drivers/block/aoe/aoe.h | |||
@@ -1,4 +1,6 @@ | |||
1 | /* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */ | 1 | /* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */ |
2 | #include <linux/blk-mq.h> | ||
3 | |||
2 | #define VERSION "85" | 4 | #define VERSION "85" |
3 | #define AOE_MAJOR 152 | 5 | #define AOE_MAJOR 152 |
4 | #define DEVICE_NAME "aoe" | 6 | #define DEVICE_NAME "aoe" |
@@ -164,6 +166,8 @@ struct aoedev { | |||
164 | struct gendisk *gd; | 166 | struct gendisk *gd; |
165 | struct dentry *debugfs; | 167 | struct dentry *debugfs; |
166 | struct request_queue *blkq; | 168 | struct request_queue *blkq; |
169 | struct list_head rq_list; | ||
170 | struct blk_mq_tag_set tag_set; | ||
167 | struct hd_geometry geo; | 171 | struct hd_geometry geo; |
168 | sector_t ssize; | 172 | sector_t ssize; |
169 | struct timer_list timer; | 173 | struct timer_list timer; |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index ff770e7d9e52..ed26b7287256 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | #include <linux/kernel.h> | 7 | #include <linux/kernel.h> |
8 | #include <linux/hdreg.h> | 8 | #include <linux/hdreg.h> |
9 | #include <linux/blkdev.h> | 9 | #include <linux/blk-mq.h> |
10 | #include <linux/backing-dev.h> | 10 | #include <linux/backing-dev.h> |
11 | #include <linux/fs.h> | 11 | #include <linux/fs.h> |
12 | #include <linux/ioctl.h> | 12 | #include <linux/ioctl.h> |
@@ -268,23 +268,25 @@ aoeblk_release(struct gendisk *disk, fmode_t mode) | |||
268 | spin_unlock_irqrestore(&d->lock, flags); | 268 | spin_unlock_irqrestore(&d->lock, flags); |
269 | } | 269 | } |
270 | 270 | ||
271 | static void | 271 | static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx, |
272 | aoeblk_request(struct request_queue *q) | 272 | const struct blk_mq_queue_data *bd) |
273 | { | 273 | { |
274 | struct aoedev *d; | 274 | struct aoedev *d = hctx->queue->queuedata; |
275 | struct request *rq; | 275 | |
276 | spin_lock_irq(&d->lock); | ||
276 | 277 | ||
277 | d = q->queuedata; | ||
278 | if ((d->flags & DEVFL_UP) == 0) { | 278 | if ((d->flags & DEVFL_UP) == 0) { |
279 | pr_info_ratelimited("aoe: device %ld.%d is not up\n", | 279 | pr_info_ratelimited("aoe: device %ld.%d is not up\n", |
280 | d->aoemajor, d->aoeminor); | 280 | d->aoemajor, d->aoeminor); |
281 | while ((rq = blk_peek_request(q))) { | 281 | spin_unlock_irq(&d->lock); |
282 | blk_start_request(rq); | 282 | blk_mq_start_request(bd->rq); |
283 | aoe_end_request(d, rq, 1); | 283 | return BLK_STS_IOERR; |
284 | } | ||
285 | return; | ||
286 | } | 284 | } |
285 | |||
286 | list_add_tail(&bd->rq->queuelist, &d->rq_list); | ||
287 | aoecmd_work(d); | 287 | aoecmd_work(d); |
288 | spin_unlock_irq(&d->lock); | ||
289 | return BLK_STS_OK; | ||
288 | } | 290 | } |
289 | 291 | ||
290 | static int | 292 | static int |
@@ -339,6 +341,10 @@ static const struct block_device_operations aoe_bdops = { | |||
339 | .owner = THIS_MODULE, | 341 | .owner = THIS_MODULE, |
340 | }; | 342 | }; |
341 | 343 | ||
344 | static const struct blk_mq_ops aoeblk_mq_ops = { | ||
345 | .queue_rq = aoeblk_queue_rq, | ||
346 | }; | ||
347 | |||
342 | /* alloc_disk and add_disk can sleep */ | 348 | /* alloc_disk and add_disk can sleep */ |
343 | void | 349 | void |
344 | aoeblk_gdalloc(void *vp) | 350 | aoeblk_gdalloc(void *vp) |
@@ -347,9 +353,11 @@ aoeblk_gdalloc(void *vp) | |||
347 | struct gendisk *gd; | 353 | struct gendisk *gd; |
348 | mempool_t *mp; | 354 | mempool_t *mp; |
349 | struct request_queue *q; | 355 | struct request_queue *q; |
356 | struct blk_mq_tag_set *set; | ||
350 | enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; | 357 | enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; |
351 | ulong flags; | 358 | ulong flags; |
352 | int late = 0; | 359 | int late = 0; |
360 | int err; | ||
353 | 361 | ||
354 | spin_lock_irqsave(&d->lock, flags); | 362 | spin_lock_irqsave(&d->lock, flags); |
355 | if (d->flags & DEVFL_GDALLOC | 363 | if (d->flags & DEVFL_GDALLOC |
@@ -376,10 +384,25 @@ aoeblk_gdalloc(void *vp) | |||
376 | d->aoemajor, d->aoeminor); | 384 | d->aoemajor, d->aoeminor); |
377 | goto err_disk; | 385 | goto err_disk; |
378 | } | 386 | } |
379 | q = blk_init_queue(aoeblk_request, &d->lock); | 387 | |
380 | if (q == NULL) { | 388 | set = &d->tag_set; |
389 | set->ops = &aoeblk_mq_ops; | ||
390 | set->nr_hw_queues = 1; | ||
391 | set->queue_depth = 128; | ||
392 | set->numa_node = NUMA_NO_NODE; | ||
393 | set->flags = BLK_MQ_F_SHOULD_MERGE; | ||
394 | err = blk_mq_alloc_tag_set(set); | ||
395 | if (err) { | ||
396 | pr_err("aoe: cannot allocate tag set for %ld.%d\n", | ||
397 | d->aoemajor, d->aoeminor); | ||
398 | goto err_mempool; | ||
399 | } | ||
400 | |||
401 | q = blk_mq_init_queue(set); | ||
402 | if (IS_ERR(q)) { | ||
381 | pr_err("aoe: cannot allocate block queue for %ld.%d\n", | 403 | pr_err("aoe: cannot allocate block queue for %ld.%d\n", |
382 | d->aoemajor, d->aoeminor); | 404 | d->aoemajor, d->aoeminor); |
405 | blk_mq_free_tag_set(set); | ||
383 | goto err_mempool; | 406 | goto err_mempool; |
384 | } | 407 | } |
385 | 408 | ||
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c index 136dc507d020..bb2fba651bd2 100644 --- a/drivers/block/aoe/aoecmd.c +++ b/drivers/block/aoe/aoecmd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/ata.h> | 7 | #include <linux/ata.h> |
8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
9 | #include <linux/hdreg.h> | 9 | #include <linux/hdreg.h> |
10 | #include <linux/blkdev.h> | 10 | #include <linux/blk-mq.h> |
11 | #include <linux/skbuff.h> | 11 | #include <linux/skbuff.h> |
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/genhd.h> | 13 | #include <linux/genhd.h> |
@@ -813,7 +813,7 @@ rexmit_timer(struct timer_list *timer) | |||
813 | out: | 813 | out: |
814 | if ((d->flags & DEVFL_KICKME) && d->blkq) { | 814 | if ((d->flags & DEVFL_KICKME) && d->blkq) { |
815 | d->flags &= ~DEVFL_KICKME; | 815 | d->flags &= ~DEVFL_KICKME; |
816 | d->blkq->request_fn(d->blkq); | 816 | blk_mq_run_hw_queues(d->blkq, true); |
817 | } | 817 | } |
818 | 818 | ||
819 | d->timer.expires = jiffies + TIMERTICK; | 819 | d->timer.expires = jiffies + TIMERTICK; |
@@ -857,10 +857,12 @@ nextbuf(struct aoedev *d) | |||
857 | return d->ip.buf; | 857 | return d->ip.buf; |
858 | rq = d->ip.rq; | 858 | rq = d->ip.rq; |
859 | if (rq == NULL) { | 859 | if (rq == NULL) { |
860 | rq = blk_peek_request(q); | 860 | rq = list_first_entry_or_null(&d->rq_list, struct request, |
861 | queuelist); | ||
861 | if (rq == NULL) | 862 | if (rq == NULL) |
862 | return NULL; | 863 | return NULL; |
863 | blk_start_request(rq); | 864 | list_del_init(&rq->queuelist); |
865 | blk_mq_start_request(rq); | ||
864 | d->ip.rq = rq; | 866 | d->ip.rq = rq; |
865 | d->ip.nxbio = rq->bio; | 867 | d->ip.nxbio = rq->bio; |
866 | rq->special = (void *) rqbiocnt(rq); | 868 | rq->special = (void *) rqbiocnt(rq); |
@@ -1045,6 +1047,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) | |||
1045 | struct bio *bio; | 1047 | struct bio *bio; |
1046 | int bok; | 1048 | int bok; |
1047 | struct request_queue *q; | 1049 | struct request_queue *q; |
1050 | blk_status_t err = BLK_STS_OK; | ||
1048 | 1051 | ||
1049 | q = d->blkq; | 1052 | q = d->blkq; |
1050 | if (rq == d->ip.rq) | 1053 | if (rq == d->ip.rq) |
@@ -1052,11 +1055,15 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail) | |||
1052 | do { | 1055 | do { |
1053 | bio = rq->bio; | 1056 | bio = rq->bio; |
1054 | bok = !fastfail && !bio->bi_status; | 1057 | bok = !fastfail && !bio->bi_status; |
1055 | } while (__blk_end_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size)); | 1058 | if (!bok) |
1059 | err = BLK_STS_IOERR; | ||
1060 | } while (blk_update_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size)); | ||
1061 | |||
1062 | __blk_mq_end_request(rq, err); | ||
1056 | 1063 | ||
1057 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ | 1064 | /* cf. http://lkml.org/lkml/2006/10/31/28 */ |
1058 | if (!fastfail) | 1065 | if (!fastfail) |
1059 | __blk_run_queue(q); | 1066 | blk_mq_run_hw_queues(q, true); |
1060 | } | 1067 | } |
1061 | 1068 | ||
1062 | static void | 1069 | static void |
diff --git a/drivers/block/aoe/aoedev.c b/drivers/block/aoe/aoedev.c index f29a140cdbc1..9063f8efbd3b 100644 --- a/drivers/block/aoe/aoedev.c +++ b/drivers/block/aoe/aoedev.c | |||
@@ -5,7 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/hdreg.h> | 7 | #include <linux/hdreg.h> |
8 | #include <linux/blkdev.h> | 8 | #include <linux/blk-mq.h> |
9 | #include <linux/netdevice.h> | 9 | #include <linux/netdevice.h> |
10 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
@@ -197,7 +197,6 @@ aoedev_downdev(struct aoedev *d) | |||
197 | { | 197 | { |
198 | struct aoetgt *t, **tt, **te; | 198 | struct aoetgt *t, **tt, **te; |
199 | struct list_head *head, *pos, *nx; | 199 | struct list_head *head, *pos, *nx; |
200 | struct request *rq; | ||
201 | int i; | 200 | int i; |
202 | 201 | ||
203 | d->flags &= ~DEVFL_UP; | 202 | d->flags &= ~DEVFL_UP; |
@@ -225,10 +224,11 @@ aoedev_downdev(struct aoedev *d) | |||
225 | 224 | ||
226 | /* fast fail all pending I/O */ | 225 | /* fast fail all pending I/O */ |
227 | if (d->blkq) { | 226 | if (d->blkq) { |
228 | while ((rq = blk_peek_request(d->blkq))) { | 227 | /* UP is cleared, freeze+quiesce to insure all are errored */ |
229 | blk_start_request(rq); | 228 | blk_mq_freeze_queue(d->blkq); |
230 | aoe_end_request(d, rq, 1); | 229 | blk_mq_quiesce_queue(d->blkq); |
231 | } | 230 | blk_mq_unquiesce_queue(d->blkq); |
231 | blk_mq_unfreeze_queue(d->blkq); | ||
232 | } | 232 | } |
233 | 233 | ||
234 | if (d->gd) | 234 | if (d->gd) |
@@ -277,6 +277,7 @@ freedev(struct aoedev *d) | |||
277 | aoedisk_rm_debugfs(d); | 277 | aoedisk_rm_debugfs(d); |
278 | del_gendisk(d->gd); | 278 | del_gendisk(d->gd); |
279 | put_disk(d->gd); | 279 | put_disk(d->gd); |
280 | blk_mq_free_tag_set(&d->tag_set); | ||
280 | blk_cleanup_queue(d->blkq); | 281 | blk_cleanup_queue(d->blkq); |
281 | } | 282 | } |
282 | t = d->targets; | 283 | t = d->targets; |
@@ -463,6 +464,7 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc) | |||
463 | d->ntargets = NTARGETS; | 464 | d->ntargets = NTARGETS; |
464 | INIT_WORK(&d->work, aoecmd_sleepwork); | 465 | INIT_WORK(&d->work, aoecmd_sleepwork); |
465 | spin_lock_init(&d->lock); | 466 | spin_lock_init(&d->lock); |
467 | INIT_LIST_HEAD(&d->rq_list); | ||
466 | skb_queue_head_init(&d->skbpool); | 468 | skb_queue_head_init(&d->skbpool); |
467 | timer_setup(&d->timer, dummy_timer, 0); | 469 | timer_setup(&d->timer, dummy_timer, 0); |
468 | d->timer.expires = jiffies + HZ; | 470 | d->timer.expires = jiffies + HZ; |