|
60 | 60 | NULL_IRQ_NONE = 0,
|
61 | 61 | NULL_IRQ_SOFTIRQ = 1,
|
62 | 62 | NULL_IRQ_TIMER = 2,
|
| 63 | +}; |
63 | 64 |
|
| 65 | +enum { |
64 | 66 | NULL_Q_BIO = 0,
|
65 | 67 | NULL_Q_RQ = 1,
|
66 | 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 | 175 | static void end_cmd(struct nullb_cmd *cmd)
|
174 | 176 | {
|
175 |
| - if (cmd->rq) { |
176 |
| - if (queue_mode == NULL_Q_MQ) |
177 |
| - blk_mq_end_io(cmd->rq, 0); |
178 |
| - else { |
179 |
| - INIT_LIST_HEAD(&cmd->rq->queuelist); |
180 |
| - blk_end_request_all(cmd->rq, 0); |
181 |
| - } |
182 |
| - } else if (cmd->bio) |
| 177 | + switch (queue_mode) { |
| 178 | + case NULL_Q_MQ: |
| 179 | + blk_mq_end_io(cmd->rq, 0); |
| 180 | + return; |
| 181 | + case NULL_Q_RQ: |
| 182 | + INIT_LIST_HEAD(&cmd->rq->queuelist); |
| 183 | + blk_end_request_all(cmd->rq, 0); |
| 184 | + break; |
| 185 | + case NULL_Q_BIO: |
183 | 186 | bio_endio(cmd->bio, 0);
|
| 187 | + break; |
| 188 | + } |
184 | 189 |
|
185 |
| - if (queue_mode != NULL_Q_MQ) |
186 |
| - free_cmd(cmd); |
| 190 | + free_cmd(cmd); |
187 | 191 | }
|
188 | 192 |
|
189 | 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 | 227 | static void null_softirq_done_fn(struct request *rq)
|
224 | 228 | {
|
225 |
| - blk_end_request_all(rq, 0); |
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(); |
| 229 | + end_cmd(rq->special); |
264 | 230 | }
|
265 | 231 |
|
266 |
| -#endif /* CONFIG_SMP */ |
267 |
| - |
268 | 232 | static inline void null_handle_cmd(struct nullb_cmd *cmd)
|
269 | 233 | {
|
270 | 234 | /* Complete IO by inline, softirq or timer */
|
271 | 235 | switch (irqmode) {
|
272 |
| - case NULL_IRQ_NONE: |
273 |
| - end_cmd(cmd); |
274 |
| - break; |
275 | 236 | case NULL_IRQ_SOFTIRQ:
|
276 |
| -#ifdef CONFIG_SMP |
277 |
| - null_cmd_end_ipi(cmd); |
278 |
| -#else |
| 237 | + switch (queue_mode) { |
| 238 | + case NULL_Q_MQ: |
| 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 | 253 | end_cmd(cmd);
|
280 |
| -#endif |
281 | 254 | break;
|
282 | 255 | case NULL_IRQ_TIMER:
|
283 | 256 | null_cmd_end_timer(cmd);
|
@@ -413,6 +386,7 @@ static struct blk_mq_ops null_mq_ops = {
|
413 | 386 | .queue_rq = null_queue_rq,
|
414 | 387 | .map_queue = blk_mq_map_queue,
|
415 | 388 | .init_hctx = null_init_hctx,
|
| 389 | + .complete = null_softirq_done_fn, |
416 | 390 | };
|
417 | 391 |
|
418 | 392 | static struct blk_mq_reg null_mq_reg = {
|
@@ -611,13 +585,6 @@ static int __init null_init(void)
|
611 | 585 | {
|
612 | 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 | 588 | if (bs > PAGE_SIZE) {
|
622 | 589 | pr_warn("null_blk: invalid block size\n");
|
623 | 590 | pr_warn("null_blk: defaults block size to %lu\n", PAGE_SIZE);
|
|
0 commit comments