Commit ce2c350b authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

null_blk: use blk_complete_request and blk_mq_complete_request

Use the block layer helpers for CPU-local completions instead of
reimplementing them locally.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent 5124c285
...@@ -60,7 +60,9 @@ enum { ...@@ -60,7 +60,9 @@ enum {
NULL_IRQ_NONE = 0, NULL_IRQ_NONE = 0,
NULL_IRQ_SOFTIRQ = 1, NULL_IRQ_SOFTIRQ = 1,
NULL_IRQ_TIMER = 2, NULL_IRQ_TIMER = 2,
};
enum {
NULL_Q_BIO = 0, NULL_Q_BIO = 0,
NULL_Q_RQ = 1, NULL_Q_RQ = 1,
NULL_Q_MQ = 2, NULL_Q_MQ = 2,
...@@ -172,17 +174,19 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) ...@@ -172,17 +174,19 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait)
static void end_cmd(struct nullb_cmd *cmd) static void end_cmd(struct nullb_cmd *cmd)
{ {
if (cmd->rq) { switch (queue_mode) {
if (queue_mode == NULL_Q_MQ) case NULL_Q_MQ:
blk_mq_end_io(cmd->rq, 0); blk_mq_end_io(cmd->rq, 0);
else { return;
case NULL_Q_RQ:
INIT_LIST_HEAD(&cmd->rq->queuelist); INIT_LIST_HEAD(&cmd->rq->queuelist);
blk_end_request_all(cmd->rq, 0); blk_end_request_all(cmd->rq, 0);
} break;
} else if (cmd->bio) case NULL_Q_BIO:
bio_endio(cmd->bio, 0); bio_endio(cmd->bio, 0);
break;
}
if (queue_mode != NULL_Q_MQ)
free_cmd(cmd); free_cmd(cmd);
} }
...@@ -222,62 +226,31 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd) ...@@ -222,62 +226,31 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd)
static void null_softirq_done_fn(struct request *rq) static void null_softirq_done_fn(struct request *rq)
{ {
blk_end_request_all(rq, 0); end_cmd(rq->special);
} }
#ifdef CONFIG_SMP
static void null_ipi_cmd_end_io(void *data)
{
struct completion_queue *cq;
struct llist_node *entry, *next;
struct nullb_cmd *cmd;
cq = &per_cpu(completion_queues, smp_processor_id());
entry = llist_del_all(&cq->list);
entry = llist_reverse_order(entry);
while (entry) {
next = entry->next;
cmd = llist_entry(entry, struct nullb_cmd, ll_list);
end_cmd(cmd);
entry = next;
}
}
static void null_cmd_end_ipi(struct nullb_cmd *cmd)
{
struct call_single_data *data = &cmd->csd;
int cpu = get_cpu();
struct completion_queue *cq = &per_cpu(completion_queues, cpu);
cmd->ll_list.next = NULL;
if (llist_add(&cmd->ll_list, &cq->list)) {
data->func = null_ipi_cmd_end_io;
data->flags = 0;
__smp_call_function_single(cpu, data, 0);
}
put_cpu();
}
#endif /* CONFIG_SMP */
static inline void null_handle_cmd(struct nullb_cmd *cmd) static inline void null_handle_cmd(struct nullb_cmd *cmd)
{ {
/* Complete IO by inline, softirq or timer */ /* Complete IO by inline, softirq or timer */
switch (irqmode) { switch (irqmode) {
case NULL_IRQ_NONE: case NULL_IRQ_SOFTIRQ:
switch (queue_mode) {
case NULL_Q_MQ:
blk_mq_complete_request(cmd->rq);
break;
case NULL_Q_RQ:
blk_complete_request(cmd->rq);
break;
case NULL_Q_BIO:
/*
* XXX: no proper submitting cpu information available.
*/
end_cmd(cmd); end_cmd(cmd);
break; break;
case NULL_IRQ_SOFTIRQ: }
#ifdef CONFIG_SMP break;
null_cmd_end_ipi(cmd); case NULL_IRQ_NONE:
#else
end_cmd(cmd); end_cmd(cmd);
#endif
break; break;
case NULL_IRQ_TIMER: case NULL_IRQ_TIMER:
null_cmd_end_timer(cmd); null_cmd_end_timer(cmd);
...@@ -413,6 +386,7 @@ static struct blk_mq_ops null_mq_ops = { ...@@ -413,6 +386,7 @@ static struct blk_mq_ops null_mq_ops = {
.queue_rq = null_queue_rq, .queue_rq = null_queue_rq,
.map_queue = blk_mq_map_queue, .map_queue = blk_mq_map_queue,
.init_hctx = null_init_hctx, .init_hctx = null_init_hctx,
.complete = null_softirq_done_fn,
}; };
static struct blk_mq_reg null_mq_reg = { static struct blk_mq_reg null_mq_reg = {
...@@ -611,13 +585,6 @@ static int __init null_init(void) ...@@ -611,13 +585,6 @@ static int __init null_init(void)
{ {
unsigned int i; unsigned int i;
#if !defined(CONFIG_SMP)
if (irqmode == NULL_IRQ_SOFTIRQ) {
pr_warn("null_blk: softirq completions not available.\n");
pr_warn("null_blk: using direct completions.\n");
irqmode = NULL_IRQ_NONE;
}
#endif
if (bs > PAGE_SIZE) { if (bs > PAGE_SIZE) {
pr_warn("null_blk: invalid block size\n"); pr_warn("null_blk: invalid block size\n");
pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE); pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment