diff options
author | Christoph Hellwig <hch@infradead.org> | 2014-02-10 06:24:40 -0500 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2014-02-10 11:27:31 -0500 |
commit | ce2c350b2cfe5b5ca5023a6b1ec4d21821d39add (patch) | |
tree | c074778d490c8a45dc6e52d8161dcd6517906a61 /drivers/block | |
parent | 5124c285797aa33d5fdb909fbe808a61bcc5eb9d (diff) |
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: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/null_blk.c | 97 |
1 files changed, 32 insertions, 65 deletions
diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c index cc801cde5cfa..091b9ea14feb 100644 --- a/drivers/block/null_blk.c +++ b/drivers/block/null_blk.c | |||
@@ -60,7 +60,9 @@ enum { | |||
60 | NULL_IRQ_NONE = 0, | 60 | NULL_IRQ_NONE = 0, |
61 | NULL_IRQ_SOFTIRQ = 1, | 61 | NULL_IRQ_SOFTIRQ = 1, |
62 | NULL_IRQ_TIMER = 2, | 62 | NULL_IRQ_TIMER = 2, |
63 | }; | ||
63 | 64 | ||
65 | enum { | ||
64 | NULL_Q_BIO = 0, | 66 | NULL_Q_BIO = 0, |
65 | NULL_Q_RQ = 1, | 67 | NULL_Q_RQ = 1, |
66 | NULL_Q_MQ = 2, | 68 | NULL_Q_MQ = 2, |
@@ -172,18 +174,20 @@ static struct nullb_cmd *alloc_cmd(struct nullb_queue *nq, int can_wait) | |||
172 | 174 | ||
173 | static void end_cmd(struct nullb_cmd *cmd) | 175 | static void end_cmd(struct nullb_cmd *cmd) |
174 | { | 176 | { |
175 | if (cmd->rq) { | 177 | switch (queue_mode) { |
176 | if (queue_mode == NULL_Q_MQ) | 178 | case NULL_Q_MQ: |
177 | blk_mq_end_io(cmd->rq, 0); | 179 | blk_mq_end_io(cmd->rq, 0); |
178 | else { | 180 | return; |
179 | INIT_LIST_HEAD(&cmd->rq->queuelist); | 181 | case NULL_Q_RQ: |
180 | blk_end_request_all(cmd->rq, 0); | 182 | INIT_LIST_HEAD(&cmd->rq->queuelist); |
181 | } | 183 | blk_end_request_all(cmd->rq, 0); |
182 | } else if (cmd->bio) | 184 | break; |
185 | case NULL_Q_BIO: | ||
183 | bio_endio(cmd->bio, 0); | 186 | bio_endio(cmd->bio, 0); |
187 | break; | ||
188 | } | ||
184 | 189 | ||
185 | if (queue_mode != NULL_Q_MQ) | 190 | free_cmd(cmd); |
186 | free_cmd(cmd); | ||
187 | } | 191 | } |
188 | 192 | ||
189 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) | 193 | static enum hrtimer_restart null_cmd_timer_expired(struct hrtimer *timer) |
@@ -222,62 +226,31 @@ static void null_cmd_end_timer(struct nullb_cmd *cmd) | |||
222 | 226 | ||
223 | static void null_softirq_done_fn(struct request *rq) | 227 | static void null_softirq_done_fn(struct request *rq) |
224 | { | 228 | { |
225 | blk_end_request_all(rq, 0); | 229 | end_cmd(rq->special); |
226 | } | ||
227 | |||
228 | #ifdef CONFIG_SMP | ||
229 | |||
230 | static void null_ipi_cmd_end_io(void *data) | ||
231 | { | ||
232 | struct completion_queue *cq; | ||
233 | struct llist_node *entry, *next; | ||
234 | struct nullb_cmd *cmd; | ||
235 | |||
236 | cq = &per_cpu(completion_queues, smp_processor_id()); | ||
237 | |||
238 | entry = llist_del_all(&cq->list); | ||
239 | entry = llist_reverse_order(entry); | ||
240 | |||
241 | while (entry) { | ||
242 | next = entry->next; | ||
243 | cmd = llist_entry(entry, struct nullb_cmd, ll_list); | ||
244 | end_cmd(cmd); | ||
245 | entry = next; | ||
246 | } | ||
247 | } | ||
248 | |||
249 | static void null_cmd_end_ipi(struct nullb_cmd *cmd) | ||
250 | { | ||
251 | struct call_single_data *data = &cmd->csd; | ||
252 | int cpu = get_cpu(); | ||
253 | struct completion_queue *cq = &per_cpu(completion_queues, cpu); | ||
254 | |||
255 | cmd->ll_list.next = NULL; | ||
256 | |||
257 | if (llist_add(&cmd->ll_list, &cq->list)) { | ||
258 | data->func = null_ipi_cmd_end_io; | ||
259 | data->flags = 0; | ||
260 | __smp_call_function_single(cpu, data, 0); | ||
261 | } | ||
262 | |||
263 | put_cpu(); | ||
264 | } | 230 | } |
265 | 231 | ||
266 | #endif /* CONFIG_SMP */ | ||
267 | |||
268 | static inline void null_handle_cmd(struct nullb_cmd *cmd) | 232 | static inline void null_handle_cmd(struct nullb_cmd *cmd) |
269 | { | 233 | { |
270 | /* Complete IO by inline, softirq or timer */ | 234 | /* Complete IO by inline, softirq or timer */ |
271 | switch (irqmode) { | 235 | switch (irqmode) { |
272 | case NULL_IRQ_NONE: | ||
273 | end_cmd(cmd); | ||
274 | break; | ||
275 | case NULL_IRQ_SOFTIRQ: | 236 | case NULL_IRQ_SOFTIRQ: |
276 | #ifdef CONFIG_SMP | 237 | switch (queue_mode) { |
277 | null_cmd_end_ipi(cmd); | 238 | case NULL_Q_MQ: |
278 | #else | 239 | blk_mq_complete_request(cmd->rq); |
240 | break; | ||
241 | case NULL_Q_RQ: | ||
242 | blk_complete_request(cmd->rq); | ||
243 | break; | ||
244 | case NULL_Q_BIO: | ||
245 | /* | ||
246 | * XXX: no proper submitting cpu information available. | ||
247 | */ | ||
248 | end_cmd(cmd); | ||
249 | break; | ||
250 | } | ||
251 | break; | ||
252 | case NULL_IRQ_NONE: | ||
279 | end_cmd(cmd); | 253 | end_cmd(cmd); |
280 | #endif | ||
281 | break; | 254 | break; |
282 | case NULL_IRQ_TIMER: | 255 | case NULL_IRQ_TIMER: |
283 | null_cmd_end_timer(cmd); | 256 | null_cmd_end_timer(cmd); |
@@ -413,6 +386,7 @@ static struct blk_mq_ops null_mq_ops = { | |||
413 | .queue_rq = null_queue_rq, | 386 | .queue_rq = null_queue_rq, |
414 | .map_queue = blk_mq_map_queue, | 387 | .map_queue = blk_mq_map_queue, |
415 | .init_hctx = null_init_hctx, | 388 | .init_hctx = null_init_hctx, |
389 | .complete = null_softirq_done_fn, | ||
416 | }; | 390 | }; |
417 | 391 | ||
418 | static struct blk_mq_reg null_mq_reg = { | 392 | static struct blk_mq_reg null_mq_reg = { |
@@ -611,13 +585,6 @@ static int __init null_init(void) | |||
611 | { | 585 | { |
612 | unsigned int i; | 586 | unsigned int i; |
613 | 587 | ||
614 | #if !defined(CONFIG_SMP) | ||
615 | if (irqmode == NULL_IRQ_SOFTIRQ) { | ||
616 | pr_warn("null_blk: softirq completions not available.\n"); | ||
617 | pr_warn("null_blk: using direct completions.\n"); | ||
618 | irqmode = NULL_IRQ_NONE; | ||
619 | } | ||
620 | #endif | ||
621 | if (bs > PAGE_SIZE) { | 588 | if (bs > PAGE_SIZE) { |
622 | pr_warn("null_blk: invalid block size\n"); | 589 | pr_warn("null_blk: invalid block size\n"); |
623 | pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE); | 590 | pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE); |