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

dm: allow immutable request-based targets to use blk-mq pdu

This will allow DM multipath to use a portion of the blk-mq pdu space
for target data (e.g. struct dm_mpath_io).

Signed-off-by: Mike Snitzer <snitzer@redhat.com>

+28 -9
+1 -1
drivers/md/dm-ioctl.c
··· 1304 1304 dm_set_md_type(md, dm_table_get_type(t)); 1305 1305 1306 1306 /* setup md->queue to reflect md's type (may block) */ 1307 - r = dm_setup_md_queue(md); 1307 + r = dm_setup_md_queue(md, t); 1308 1308 if (r) { 1309 1309 DMWARN("unable to set up device queue for new table."); 1310 1310 goto err_unlock_md_type;
+26 -7
drivers/md/dm.c
··· 224 224 225 225 /* for blk-mq request-based DM support */ 226 226 struct blk_mq_tag_set *tag_set; 227 - bool use_blk_mq; 227 + bool use_blk_mq:1; 228 + bool init_tio_pdu:1; 228 229 }; 229 230 230 231 #ifdef CONFIG_DM_MQ_DEFAULT ··· 244 243 { 245 244 return md->use_blk_mq; 246 245 } 246 + EXPORT_SYMBOL_GPL(dm_use_blk_mq); 247 247 248 248 /* 249 249 * For mempools pre-allocation at the table loading time. ··· 1891 1889 tio->clone = NULL; 1892 1890 tio->orig = rq; 1893 1891 tio->error = 0; 1894 - memset(&tio->info, 0, sizeof(tio->info)); 1892 + /* 1893 + * Avoid initializing info for blk-mq; it passes 1894 + * target-specific data through info.ptr 1895 + * (see: dm_mq_init_request) 1896 + */ 1897 + if (!md->init_tio_pdu) 1898 + memset(&tio->info, 0, sizeof(tio->info)); 1895 1899 if (md->kworker_task) 1896 1900 init_kthread_work(&tio->work, map_tio_request); 1897 1901 } ··· 2321 2313 goto bad_io_barrier; 2322 2314 2323 2315 md->use_blk_mq = use_blk_mq; 2316 + md->init_tio_pdu = false; 2324 2317 md->type = DM_TYPE_NONE; 2325 2318 mutex_init(&md->suspend_lock); 2326 2319 mutex_init(&md->type_lock); ··· 2662 2653 */ 2663 2654 tio->md = md; 2664 2655 2656 + if (md->init_tio_pdu) { 2657 + /* target-specific per-io data is immediately after the tio */ 2658 + tio->info.ptr = tio + 1; 2659 + } 2660 + 2665 2661 return 0; 2666 2662 } 2667 2663 ··· 2718 2704 .init_request = dm_mq_init_request, 2719 2705 }; 2720 2706 2721 - static int dm_mq_init_request_queue(struct mapped_device *md) 2707 + static int dm_mq_init_request_queue(struct mapped_device *md, 2708 + struct dm_target *immutable_tgt) 2722 2709 { 2723 2710 struct request_queue *q; 2724 2711 int err; ··· 2741 2726 md->tag_set->driver_data = md; 2742 2727 2743 2728 md->tag_set->cmd_size = sizeof(struct dm_rq_target_io); 2729 + if (immutable_tgt && immutable_tgt->per_io_data_size) { 2730 + /* any target-specific per-io data is immediately after the tio */ 2731 + md->tag_set->cmd_size += immutable_tgt->per_io_data_size; 2732 + md->init_tio_pdu = true; 2733 + } 2744 2734 2745 2735 err = blk_mq_alloc_tag_set(md->tag_set); 2746 2736 if (err) ··· 2783 2763 /* 2784 2764 * Setup the DM device's queue based on md's type 2785 2765 */ 2786 - int dm_setup_md_queue(struct mapped_device *md) 2766 + int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t) 2787 2767 { 2788 2768 int r; 2789 2769 unsigned md_type = filter_md_type(dm_get_md_type(md), md); ··· 2797 2777 } 2798 2778 break; 2799 2779 case DM_TYPE_MQ_REQUEST_BASED: 2800 - r = dm_mq_init_request_queue(md); 2780 + r = dm_mq_init_request_queue(md, dm_table_get_immutable_target(t)); 2801 2781 if (r) { 2802 2782 DMERR("Cannot initialize queue for request-based dm-mq mapped device"); 2803 2783 return r; ··· 3525 3505 if (!pool_size) 3526 3506 pool_size = dm_get_reserved_rq_based_ios(); 3527 3507 front_pad = offsetof(struct dm_rq_clone_bio_info, clone); 3528 - /* per_io_data_size is not used. */ 3529 - WARN_ON(per_io_data_size != 0); 3508 + /* per_io_data_size is used for blk-mq pdu at queue allocation */ 3530 3509 break; 3531 3510 default: 3532 3511 BUG();
+1 -1
drivers/md/dm.h
··· 86 86 unsigned dm_get_md_type(struct mapped_device *md); 87 87 struct target_type *dm_get_immutable_target_type(struct mapped_device *md); 88 88 89 - int dm_setup_md_queue(struct mapped_device *md); 89 + int dm_setup_md_queue(struct mapped_device *md, struct dm_table *t); 90 90 91 91 /* 92 92 * To check the return value from dm_table_find_target().