Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

blk-mq: use __smp_call_function_single directly

__smp_call_function_single already avoids multiple IPIs by internally
queing up the items, and now also is available for non-SMP builds as
a trivially correct stub, so there is no need to wrap it. If the
additional lock roundtrip cause problems my patch to convert the
generic IPI code to llists is waiting to get merged will fix it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Christoph Hellwig and committed by
Jens Axboe
3d6efbf6 c7b22bb1

+11 -89
-31
block/blk-mq-cpu.c
··· 28 28 return NOTIFY_OK; 29 29 } 30 30 31 - static void blk_mq_cpu_notify(void *data, unsigned long action, 32 - unsigned int cpu) 33 - { 34 - if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { 35 - /* 36 - * If the CPU goes away, ensure that we run any pending 37 - * completions. 38 - */ 39 - struct llist_node *node; 40 - struct request *rq; 41 - 42 - local_irq_disable(); 43 - 44 - node = llist_del_all(&per_cpu(ipi_lists, cpu)); 45 - while (node) { 46 - struct llist_node *next = node->next; 47 - 48 - rq = llist_entry(node, struct request, ll_list); 49 - __blk_mq_end_io(rq, rq->errors); 50 - node = next; 51 - } 52 - 53 - local_irq_enable(); 54 - } 55 - } 56 - 57 31 static struct notifier_block __cpuinitdata blk_mq_main_cpu_notifier = { 58 32 .notifier_call = blk_mq_main_cpu_notify, 59 33 }; ··· 56 82 notifier->data = data; 57 83 } 58 84 59 - static struct blk_mq_cpu_notifier __cpuinitdata cpu_notifier = { 60 - .notify = blk_mq_cpu_notify, 61 - }; 62 - 63 85 void __init blk_mq_cpu_init(void) 64 86 { 65 87 register_hotcpu_notifier(&blk_mq_main_cpu_notifier); 66 - blk_mq_register_cpu_notifier(&cpu_notifier); 67 88 }
+11 -57
block/blk-mq.c
··· 27 27 28 28 static void __blk_mq_run_hw_queue(struct blk_mq_hw_ctx *hctx); 29 29 30 - DEFINE_PER_CPU(struct llist_head, ipi_lists); 31 - 32 30 static struct blk_mq_ctx *__blk_mq_get_ctx(struct request_queue *q, 33 31 unsigned int cpu) 34 32 { ··· 337 339 blk_mq_complete_request(rq, error); 338 340 } 339 341 340 - #if defined(CONFIG_SMP) 341 - 342 - /* 343 - * Called with interrupts disabled. 344 - */ 345 - static void ipi_end_io(void *data) 342 + static void blk_mq_end_io_remote(void *data) 346 343 { 347 - struct llist_head *list = &per_cpu(ipi_lists, smp_processor_id()); 348 - struct llist_node *entry, *next; 349 - struct request *rq; 344 + struct request *rq = data; 350 345 351 - entry = llist_del_all(list); 352 - 353 - while (entry) { 354 - next = entry->next; 355 - rq = llist_entry(entry, struct request, ll_list); 356 - __blk_mq_end_io(rq, rq->errors); 357 - entry = next; 358 - } 346 + __blk_mq_end_io(rq, rq->errors); 359 347 } 360 - 361 - static int ipi_remote_cpu(struct blk_mq_ctx *ctx, const int cpu, 362 - struct request *rq, const int error) 363 - { 364 - struct call_single_data *data = &rq->csd; 365 - 366 - rq->errors = error; 367 - rq->ll_list.next = NULL; 368 - 369 - /* 370 - * If the list is non-empty, an existing IPI must already 371 - * be "in flight". If that is the case, we need not schedule 372 - * a new one. 373 - */ 374 - if (llist_add(&rq->ll_list, &per_cpu(ipi_lists, ctx->cpu))) { 375 - data->func = ipi_end_io; 376 - data->flags = 0; 377 - __smp_call_function_single(ctx->cpu, data, 0); 378 - } 379 - 380 - return true; 381 - } 382 - #else /* CONFIG_SMP */ 383 - static int ipi_remote_cpu(struct blk_mq_ctx *ctx, const int cpu, 384 - struct request *rq, const int error) 385 - { 386 - return false; 387 - } 388 - #endif 389 348 390 349 /* 391 350 * End IO on this request on a multiqueue enabled driver. We'll either do ··· 358 403 return __blk_mq_end_io(rq, error); 359 404 360 405 cpu = get_cpu(); 361 - 362 - if (cpu == ctx->cpu || !cpu_online(ctx->cpu) || 363 - !ipi_remote_cpu(ctx, cpu, rq, error)) 406 + if (cpu != ctx->cpu && cpu_online(ctx->cpu)) { 407 + rq->errors = error; 408 + rq->csd.func = blk_mq_end_io_remote; 409 + rq->csd.info = rq; 410 + rq->csd.flags = 0; 411 + __smp_call_function_single(ctx->cpu, &rq->csd, 0); 412 + } else { 364 413 __blk_mq_end_io(rq, error); 365 - 414 + } 366 415 put_cpu(); 367 416 } 368 417 EXPORT_SYMBOL(blk_mq_end_io); ··· 1465 1506 1466 1507 static int __init blk_mq_init(void) 1467 1508 { 1468 - unsigned int i; 1469 - 1470 - for_each_possible_cpu(i) 1471 - init_llist_head(&per_cpu(ipi_lists, i)); 1472 - 1473 1509 blk_mq_cpu_init(); 1474 1510 1475 1511 /* Must be called after percpu_counter_hotcpu_callback() */
-1
block/blk-mq.h
··· 40 40 void blk_mq_register_cpu_notifier(struct blk_mq_cpu_notifier *notifier); 41 41 void blk_mq_unregister_cpu_notifier(struct blk_mq_cpu_notifier *notifier); 42 42 void blk_mq_cpu_init(void); 43 - DECLARE_PER_CPU(struct llist_head, ipi_lists); 44 43 45 44 /* 46 45 * CPU -> queue mappings