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>
This commit is contained in:
Jens Axboe 2018-10-12 10:03:14 -06:00
parent e01ad46d53
commit 3582dd2917
4 changed files with 61 additions and 25 deletions

View File

@ -1,4 +1,6 @@
/* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */ /* Copyright (c) 2013 Coraid, Inc. See COPYING for GPL terms. */
#include <linux/blk-mq.h>
#define VERSION "85" #define VERSION "85"
#define AOE_MAJOR 152 #define AOE_MAJOR 152
#define DEVICE_NAME "aoe" #define DEVICE_NAME "aoe"
@ -164,6 +166,8 @@ struct aoedev {
struct gendisk *gd; struct gendisk *gd;
struct dentry *debugfs; struct dentry *debugfs;
struct request_queue *blkq; struct request_queue *blkq;
struct list_head rq_list;
struct blk_mq_tag_set tag_set;
struct hd_geometry geo; struct hd_geometry geo;
sector_t ssize; sector_t ssize;
struct timer_list timer; struct timer_list timer;

View File

@ -6,7 +6,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ioctl.h> #include <linux/ioctl.h>
@ -268,23 +268,25 @@ aoeblk_release(struct gendisk *disk, fmode_t mode)
spin_unlock_irqrestore(&d->lock, flags); spin_unlock_irqrestore(&d->lock, flags);
} }
static void static blk_status_t aoeblk_queue_rq(struct blk_mq_hw_ctx *hctx,
aoeblk_request(struct request_queue *q) const struct blk_mq_queue_data *bd)
{ {
struct aoedev *d; struct aoedev *d = hctx->queue->queuedata;
struct request *rq;
spin_lock_irq(&d->lock);
d = q->queuedata;
if ((d->flags & DEVFL_UP) == 0) { if ((d->flags & DEVFL_UP) == 0) {
pr_info_ratelimited("aoe: device %ld.%d is not up\n", pr_info_ratelimited("aoe: device %ld.%d is not up\n",
d->aoemajor, d->aoeminor); d->aoemajor, d->aoeminor);
while ((rq = blk_peek_request(q))) { spin_unlock_irq(&d->lock);
blk_start_request(rq); blk_mq_start_request(bd->rq);
aoe_end_request(d, rq, 1); return BLK_STS_IOERR;
}
return;
} }
list_add_tail(&bd->rq->queuelist, &d->rq_list);
aoecmd_work(d); aoecmd_work(d);
spin_unlock_irq(&d->lock);
return BLK_STS_OK;
} }
static int static int
@ -339,6 +341,10 @@ static const struct block_device_operations aoe_bdops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static const struct blk_mq_ops aoeblk_mq_ops = {
.queue_rq = aoeblk_queue_rq,
};
/* alloc_disk and add_disk can sleep */ /* alloc_disk and add_disk can sleep */
void void
aoeblk_gdalloc(void *vp) aoeblk_gdalloc(void *vp)
@ -347,9 +353,11 @@ aoeblk_gdalloc(void *vp)
struct gendisk *gd; struct gendisk *gd;
mempool_t *mp; mempool_t *mp;
struct request_queue *q; struct request_queue *q;
struct blk_mq_tag_set *set;
enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, }; enum { KB = 1024, MB = KB * KB, READ_AHEAD = 2 * MB, };
ulong flags; ulong flags;
int late = 0; int late = 0;
int err;
spin_lock_irqsave(&d->lock, flags); spin_lock_irqsave(&d->lock, flags);
if (d->flags & DEVFL_GDALLOC if (d->flags & DEVFL_GDALLOC
@ -376,10 +384,25 @@ aoeblk_gdalloc(void *vp)
d->aoemajor, d->aoeminor); d->aoemajor, d->aoeminor);
goto err_disk; goto err_disk;
} }
q = blk_init_queue(aoeblk_request, &d->lock);
if (q == NULL) { set = &d->tag_set;
set->ops = &aoeblk_mq_ops;
set->nr_hw_queues = 1;
set->queue_depth = 128;
set->numa_node = NUMA_NO_NODE;
set->flags = BLK_MQ_F_SHOULD_MERGE;
err = blk_mq_alloc_tag_set(set);
if (err) {
pr_err("aoe: cannot allocate tag set for %ld.%d\n",
d->aoemajor, d->aoeminor);
goto err_mempool;
}
q = blk_mq_init_queue(set);
if (IS_ERR(q)) {
pr_err("aoe: cannot allocate block queue for %ld.%d\n", pr_err("aoe: cannot allocate block queue for %ld.%d\n",
d->aoemajor, d->aoeminor); d->aoemajor, d->aoeminor);
blk_mq_free_tag_set(set);
goto err_mempool; goto err_mempool;
} }

View File

@ -7,7 +7,7 @@
#include <linux/ata.h> #include <linux/ata.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/genhd.h> #include <linux/genhd.h>
@ -813,7 +813,7 @@ rexmit_timer(struct timer_list *timer)
out: out:
if ((d->flags & DEVFL_KICKME) && d->blkq) { if ((d->flags & DEVFL_KICKME) && d->blkq) {
d->flags &= ~DEVFL_KICKME; d->flags &= ~DEVFL_KICKME;
d->blkq->request_fn(d->blkq); blk_mq_run_hw_queues(d->blkq, true);
} }
d->timer.expires = jiffies + TIMERTICK; d->timer.expires = jiffies + TIMERTICK;
@ -857,10 +857,12 @@ nextbuf(struct aoedev *d)
return d->ip.buf; return d->ip.buf;
rq = d->ip.rq; rq = d->ip.rq;
if (rq == NULL) { if (rq == NULL) {
rq = blk_peek_request(q); rq = list_first_entry_or_null(&d->rq_list, struct request,
queuelist);
if (rq == NULL) if (rq == NULL)
return NULL; return NULL;
blk_start_request(rq); list_del_init(&rq->queuelist);
blk_mq_start_request(rq);
d->ip.rq = rq; d->ip.rq = rq;
d->ip.nxbio = rq->bio; d->ip.nxbio = rq->bio;
rq->special = (void *) rqbiocnt(rq); rq->special = (void *) rqbiocnt(rq);
@ -1045,6 +1047,7 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
struct bio *bio; struct bio *bio;
int bok; int bok;
struct request_queue *q; struct request_queue *q;
blk_status_t err = BLK_STS_OK;
q = d->blkq; q = d->blkq;
if (rq == d->ip.rq) if (rq == d->ip.rq)
@ -1052,11 +1055,15 @@ aoe_end_request(struct aoedev *d, struct request *rq, int fastfail)
do { do {
bio = rq->bio; bio = rq->bio;
bok = !fastfail && !bio->bi_status; bok = !fastfail && !bio->bi_status;
} while (__blk_end_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size)); if (!bok)
err = BLK_STS_IOERR;
} while (blk_update_request(rq, bok ? BLK_STS_OK : BLK_STS_IOERR, bio->bi_iter.bi_size));
__blk_mq_end_request(rq, err);
/* cf. http://lkml.org/lkml/2006/10/31/28 */ /* cf. http://lkml.org/lkml/2006/10/31/28 */
if (!fastfail) if (!fastfail)
__blk_run_queue(q); blk_mq_run_hw_queues(q, true);
} }
static void static void

View File

@ -5,7 +5,7 @@
*/ */
#include <linux/hdreg.h> #include <linux/hdreg.h>
#include <linux/blkdev.h> #include <linux/blk-mq.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/slab.h> #include <linux/slab.h>
@ -197,7 +197,6 @@ aoedev_downdev(struct aoedev *d)
{ {
struct aoetgt *t, **tt, **te; struct aoetgt *t, **tt, **te;
struct list_head *head, *pos, *nx; struct list_head *head, *pos, *nx;
struct request *rq;
int i; int i;
d->flags &= ~DEVFL_UP; d->flags &= ~DEVFL_UP;
@ -225,10 +224,11 @@ aoedev_downdev(struct aoedev *d)
/* fast fail all pending I/O */ /* fast fail all pending I/O */
if (d->blkq) { if (d->blkq) {
while ((rq = blk_peek_request(d->blkq))) { /* UP is cleared, freeze+quiesce to insure all are errored */
blk_start_request(rq); blk_mq_freeze_queue(d->blkq);
aoe_end_request(d, rq, 1); blk_mq_quiesce_queue(d->blkq);
} blk_mq_unquiesce_queue(d->blkq);
blk_mq_unfreeze_queue(d->blkq);
} }
if (d->gd) if (d->gd)
@ -277,6 +277,7 @@ freedev(struct aoedev *d)
aoedisk_rm_debugfs(d); aoedisk_rm_debugfs(d);
del_gendisk(d->gd); del_gendisk(d->gd);
put_disk(d->gd); put_disk(d->gd);
blk_mq_free_tag_set(&d->tag_set);
blk_cleanup_queue(d->blkq); blk_cleanup_queue(d->blkq);
} }
t = d->targets; t = d->targets;
@ -463,6 +464,7 @@ aoedev_by_aoeaddr(ulong maj, int min, int do_alloc)
d->ntargets = NTARGETS; d->ntargets = NTARGETS;
INIT_WORK(&d->work, aoecmd_sleepwork); INIT_WORK(&d->work, aoecmd_sleepwork);
spin_lock_init(&d->lock); spin_lock_init(&d->lock);
INIT_LIST_HEAD(&d->rq_list);
skb_queue_head_init(&d->skbpool); skb_queue_head_init(&d->skbpool);
timer_setup(&d->timer, dummy_timer, 0); timer_setup(&d->timer, dummy_timer, 0);
d->timer.expires = jiffies + HZ; d->timer.expires = jiffies + HZ;