diff options
| -rw-r--r-- | MAINTAINERS | 2 | ||||
| -rw-r--r-- | block/bfq-cgroup.c | 6 | ||||
| -rw-r--r-- | block/blk-cgroup.c | 2 | ||||
| -rw-r--r-- | block/blk-core.c | 13 | ||||
| -rw-r--r-- | block/blk-mq-sched.c | 30 | ||||
| -rw-r--r-- | block/blk-mq-sched.h | 1 | ||||
| -rw-r--r-- | block/blk-sysfs.c | 2 | ||||
| -rw-r--r-- | block/blk.h | 10 | ||||
| -rw-r--r-- | block/elevator.c | 2 | ||||
| -rw-r--r-- | drivers/block/aoe/aoeblk.c | 16 | ||||
| -rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 1 | ||||
| -rw-r--r-- | drivers/block/rsxx/core.c | 1 | ||||
| -rw-r--r-- | drivers/mmc/core/queue.c | 2 | ||||
| -rw-r--r-- | drivers/nvme/host/core.c | 3 | ||||
| -rw-r--r-- | drivers/nvme/host/pci.c | 6 | ||||
| -rw-r--r-- | drivers/nvme/host/rdma.c | 152 | ||||
| -rw-r--r-- | drivers/nvme/host/tcp.c | 57 | ||||
| -rw-r--r-- | drivers/nvme/target/io-cmd-bdev.c | 1 | ||||
| -rw-r--r-- | include/linux/cgroup-defs.h | 3 | ||||
| -rw-r--r-- | kernel/cgroup/cgroup.c | 33 |
20 files changed, 251 insertions, 92 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 36a84614d6c3..df83b6769c17 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -14995,7 +14995,7 @@ S: Odd Fixes | |||
| 14995 | F: drivers/net/ethernet/adaptec/starfire* | 14995 | F: drivers/net/ethernet/adaptec/starfire* |
| 14996 | 14996 | ||
| 14997 | STEC S1220 SKD DRIVER | 14997 | STEC S1220 SKD DRIVER |
| 14998 | M: Bart Van Assche <bart.vanassche@wdc.com> | 14998 | M: Damien Le Moal <Damien.LeMoal@wdc.com> |
| 14999 | L: linux-block@vger.kernel.org | 14999 | L: linux-block@vger.kernel.org |
| 15000 | S: Maintained | 15000 | S: Maintained |
| 15001 | F: drivers/block/skd*[ch] | 15001 | F: drivers/block/skd*[ch] |
diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c index b3796a40a61a..59f46904cb11 100644 --- a/block/bfq-cgroup.c +++ b/block/bfq-cgroup.c | |||
| @@ -1046,7 +1046,8 @@ struct blkcg_policy blkcg_policy_bfq = { | |||
| 1046 | struct cftype bfq_blkcg_legacy_files[] = { | 1046 | struct cftype bfq_blkcg_legacy_files[] = { |
| 1047 | { | 1047 | { |
| 1048 | .name = "bfq.weight", | 1048 | .name = "bfq.weight", |
| 1049 | .flags = CFTYPE_NOT_ON_ROOT, | 1049 | .link_name = "weight", |
| 1050 | .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_SYMLINKED, | ||
| 1050 | .seq_show = bfq_io_show_weight, | 1051 | .seq_show = bfq_io_show_weight, |
| 1051 | .write_u64 = bfq_io_set_weight_legacy, | 1052 | .write_u64 = bfq_io_set_weight_legacy, |
| 1052 | }, | 1053 | }, |
| @@ -1166,7 +1167,8 @@ struct cftype bfq_blkcg_legacy_files[] = { | |||
| 1166 | struct cftype bfq_blkg_files[] = { | 1167 | struct cftype bfq_blkg_files[] = { |
| 1167 | { | 1168 | { |
| 1168 | .name = "bfq.weight", | 1169 | .name = "bfq.weight", |
| 1169 | .flags = CFTYPE_NOT_ON_ROOT, | 1170 | .link_name = "weight", |
| 1171 | .flags = CFTYPE_NOT_ON_ROOT | CFTYPE_SYMLINKED, | ||
| 1170 | .seq_show = bfq_io_show_weight, | 1172 | .seq_show = bfq_io_show_weight, |
| 1171 | .write = bfq_io_set_weight, | 1173 | .write = bfq_io_set_weight, |
| 1172 | }, | 1174 | }, |
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b97b479e4f64..1f7127b03490 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c | |||
| @@ -881,7 +881,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, | |||
| 881 | blkg_free(new_blkg); | 881 | blkg_free(new_blkg); |
| 882 | } else { | 882 | } else { |
| 883 | blkg = blkg_create(pos, q, new_blkg); | 883 | blkg = blkg_create(pos, q, new_blkg); |
| 884 | if (unlikely(IS_ERR(blkg))) { | 884 | if (IS_ERR(blkg)) { |
| 885 | ret = PTR_ERR(blkg); | 885 | ret = PTR_ERR(blkg); |
| 886 | goto fail_unlock; | 886 | goto fail_unlock; |
| 887 | } | 887 | } |
diff --git a/block/blk-core.c b/block/blk-core.c index ee1b35fe8572..8340f69670d8 100644 --- a/block/blk-core.c +++ b/block/blk-core.c | |||
| @@ -320,6 +320,19 @@ void blk_cleanup_queue(struct request_queue *q) | |||
| 320 | if (queue_is_mq(q)) | 320 | if (queue_is_mq(q)) |
| 321 | blk_mq_exit_queue(q); | 321 | blk_mq_exit_queue(q); |
| 322 | 322 | ||
| 323 | /* | ||
| 324 | * In theory, request pool of sched_tags belongs to request queue. | ||
| 325 | * However, the current implementation requires tag_set for freeing | ||
| 326 | * requests, so free the pool now. | ||
| 327 | * | ||
| 328 | * Queue has become frozen, there can't be any in-queue requests, so | ||
| 329 | * it is safe to free requests now. | ||
| 330 | */ | ||
| 331 | mutex_lock(&q->sysfs_lock); | ||
| 332 | if (q->elevator) | ||
| 333 | blk_mq_sched_free_requests(q); | ||
| 334 | mutex_unlock(&q->sysfs_lock); | ||
| 335 | |||
| 323 | percpu_ref_exit(&q->q_usage_counter); | 336 | percpu_ref_exit(&q->q_usage_counter); |
| 324 | 337 | ||
| 325 | /* @q is and will stay empty, shutdown and put */ | 338 | /* @q is and will stay empty, shutdown and put */ |
diff --git a/block/blk-mq-sched.c b/block/blk-mq-sched.c index 74c6bb871f7e..500cb04901cc 100644 --- a/block/blk-mq-sched.c +++ b/block/blk-mq-sched.c | |||
| @@ -475,14 +475,18 @@ static int blk_mq_sched_alloc_tags(struct request_queue *q, | |||
| 475 | return ret; | 475 | return ret; |
| 476 | } | 476 | } |
| 477 | 477 | ||
| 478 | /* called in queue's release handler, tagset has gone away */ | ||
| 478 | static void blk_mq_sched_tags_teardown(struct request_queue *q) | 479 | static void blk_mq_sched_tags_teardown(struct request_queue *q) |
| 479 | { | 480 | { |
| 480 | struct blk_mq_tag_set *set = q->tag_set; | ||
| 481 | struct blk_mq_hw_ctx *hctx; | 481 | struct blk_mq_hw_ctx *hctx; |
| 482 | int i; | 482 | int i; |
| 483 | 483 | ||
| 484 | queue_for_each_hw_ctx(q, hctx, i) | 484 | queue_for_each_hw_ctx(q, hctx, i) { |
| 485 | blk_mq_sched_free_tags(set, hctx, i); | 485 | if (hctx->sched_tags) { |
| 486 | blk_mq_free_rq_map(hctx->sched_tags); | ||
| 487 | hctx->sched_tags = NULL; | ||
| 488 | } | ||
| 489 | } | ||
| 486 | } | 490 | } |
| 487 | 491 | ||
| 488 | int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) | 492 | int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) |
| @@ -523,6 +527,7 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) | |||
| 523 | ret = e->ops.init_hctx(hctx, i); | 527 | ret = e->ops.init_hctx(hctx, i); |
| 524 | if (ret) { | 528 | if (ret) { |
| 525 | eq = q->elevator; | 529 | eq = q->elevator; |
| 530 | blk_mq_sched_free_requests(q); | ||
| 526 | blk_mq_exit_sched(q, eq); | 531 | blk_mq_exit_sched(q, eq); |
| 527 | kobject_put(&eq->kobj); | 532 | kobject_put(&eq->kobj); |
| 528 | return ret; | 533 | return ret; |
| @@ -534,11 +539,30 @@ int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e) | |||
| 534 | return 0; | 539 | return 0; |
| 535 | 540 | ||
| 536 | err: | 541 | err: |
| 542 | blk_mq_sched_free_requests(q); | ||
| 537 | blk_mq_sched_tags_teardown(q); | 543 | blk_mq_sched_tags_teardown(q); |
| 538 | q->elevator = NULL; | 544 | q->elevator = NULL; |
| 539 | return ret; | 545 | return ret; |
| 540 | } | 546 | } |
| 541 | 547 | ||
| 548 | /* | ||
| 549 | * called in either blk_queue_cleanup or elevator_switch, tagset | ||
| 550 | * is required for freeing requests | ||
| 551 | */ | ||
| 552 | void blk_mq_sched_free_requests(struct request_queue *q) | ||
| 553 | { | ||
| 554 | struct blk_mq_hw_ctx *hctx; | ||
| 555 | int i; | ||
| 556 | |||
| 557 | lockdep_assert_held(&q->sysfs_lock); | ||
| 558 | WARN_ON(!q->elevator); | ||
| 559 | |||
| 560 | queue_for_each_hw_ctx(q, hctx, i) { | ||
| 561 | if (hctx->sched_tags) | ||
| 562 | blk_mq_free_rqs(q->tag_set, hctx->sched_tags, i); | ||
| 563 | } | ||
| 564 | } | ||
| 565 | |||
| 542 | void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) | 566 | void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e) |
| 543 | { | 567 | { |
| 544 | struct blk_mq_hw_ctx *hctx; | 568 | struct blk_mq_hw_ctx *hctx; |
diff --git a/block/blk-mq-sched.h b/block/blk-mq-sched.h index c7bdb52367ac..3cf92cbbd8ac 100644 --- a/block/blk-mq-sched.h +++ b/block/blk-mq-sched.h | |||
| @@ -28,6 +28,7 @@ void blk_mq_sched_dispatch_requests(struct blk_mq_hw_ctx *hctx); | |||
| 28 | 28 | ||
| 29 | int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e); | 29 | int blk_mq_init_sched(struct request_queue *q, struct elevator_type *e); |
| 30 | void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e); | 30 | void blk_mq_exit_sched(struct request_queue *q, struct elevator_queue *e); |
| 31 | void blk_mq_sched_free_requests(struct request_queue *q); | ||
| 31 | 32 | ||
| 32 | static inline bool | 33 | static inline bool |
| 33 | blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio) | 34 | blk_mq_sched_bio_merge(struct request_queue *q, struct bio *bio) |
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 75b5281cc577..977c659dcd18 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
| @@ -850,7 +850,7 @@ static void blk_exit_queue(struct request_queue *q) | |||
| 850 | */ | 850 | */ |
| 851 | if (q->elevator) { | 851 | if (q->elevator) { |
| 852 | ioc_clear_queue(q); | 852 | ioc_clear_queue(q); |
| 853 | elevator_exit(q, q->elevator); | 853 | __elevator_exit(q, q->elevator); |
| 854 | q->elevator = NULL; | 854 | q->elevator = NULL; |
| 855 | } | 855 | } |
| 856 | 856 | ||
diff --git a/block/blk.h b/block/blk.h index 91b3581b7c7a..7814aa207153 100644 --- a/block/blk.h +++ b/block/blk.h | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <linux/blk-mq.h> | 6 | #include <linux/blk-mq.h> |
| 7 | #include <xen/xen.h> | 7 | #include <xen/xen.h> |
| 8 | #include "blk-mq.h" | 8 | #include "blk-mq.h" |
| 9 | #include "blk-mq-sched.h" | ||
| 9 | 10 | ||
| 10 | /* Max future timer expiry for timeouts */ | 11 | /* Max future timer expiry for timeouts */ |
| 11 | #define BLK_MAX_TIMEOUT (5 * HZ) | 12 | #define BLK_MAX_TIMEOUT (5 * HZ) |
| @@ -176,10 +177,17 @@ void blk_insert_flush(struct request *rq); | |||
| 176 | int elevator_init_mq(struct request_queue *q); | 177 | int elevator_init_mq(struct request_queue *q); |
| 177 | int elevator_switch_mq(struct request_queue *q, | 178 | int elevator_switch_mq(struct request_queue *q, |
| 178 | struct elevator_type *new_e); | 179 | struct elevator_type *new_e); |
| 179 | void elevator_exit(struct request_queue *, struct elevator_queue *); | 180 | void __elevator_exit(struct request_queue *, struct elevator_queue *); |
| 180 | int elv_register_queue(struct request_queue *q); | 181 | int elv_register_queue(struct request_queue *q); |
| 181 | void elv_unregister_queue(struct request_queue *q); | 182 | void elv_unregister_queue(struct request_queue *q); |
| 182 | 183 | ||
| 184 | static inline void elevator_exit(struct request_queue *q, | ||
| 185 | struct elevator_queue *e) | ||
| 186 | { | ||
| 187 | blk_mq_sched_free_requests(q); | ||
| 188 | __elevator_exit(q, e); | ||
| 189 | } | ||
| 190 | |||
| 183 | struct hd_struct *__disk_get_part(struct gendisk *disk, int partno); | 191 | struct hd_struct *__disk_get_part(struct gendisk *disk, int partno); |
| 184 | 192 | ||
| 185 | #ifdef CONFIG_FAIL_IO_TIMEOUT | 193 | #ifdef CONFIG_FAIL_IO_TIMEOUT |
diff --git a/block/elevator.c b/block/elevator.c index ec55d5fc0b3e..2f17d66d0e61 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
| @@ -178,7 +178,7 @@ static void elevator_release(struct kobject *kobj) | |||
| 178 | kfree(e); | 178 | kfree(e); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | void elevator_exit(struct request_queue *q, struct elevator_queue *e) | 181 | void __elevator_exit(struct request_queue *q, struct elevator_queue *e) |
| 182 | { | 182 | { |
| 183 | mutex_lock(&e->sysfs_lock); | 183 | mutex_lock(&e->sysfs_lock); |
| 184 | if (e->type->ops.exit_sched) | 184 | if (e->type->ops.exit_sched) |
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c index e2c6aae2d636..bd19f8af950b 100644 --- a/drivers/block/aoe/aoeblk.c +++ b/drivers/block/aoe/aoeblk.c | |||
| @@ -196,7 +196,6 @@ static const struct file_operations aoe_debugfs_fops = { | |||
| 196 | static void | 196 | static void |
| 197 | aoedisk_add_debugfs(struct aoedev *d) | 197 | aoedisk_add_debugfs(struct aoedev *d) |
| 198 | { | 198 | { |
| 199 | struct dentry *entry; | ||
| 200 | char *p; | 199 | char *p; |
| 201 | 200 | ||
| 202 | if (aoe_debugfs_dir == NULL) | 201 | if (aoe_debugfs_dir == NULL) |
| @@ -207,15 +206,8 @@ aoedisk_add_debugfs(struct aoedev *d) | |||
| 207 | else | 206 | else |
| 208 | p++; | 207 | p++; |
| 209 | BUG_ON(*p == '\0'); | 208 | BUG_ON(*p == '\0'); |
| 210 | entry = debugfs_create_file(p, 0444, aoe_debugfs_dir, d, | 209 | d->debugfs = debugfs_create_file(p, 0444, aoe_debugfs_dir, d, |
| 211 | &aoe_debugfs_fops); | 210 | &aoe_debugfs_fops); |
| 212 | if (IS_ERR_OR_NULL(entry)) { | ||
| 213 | pr_info("aoe: cannot create debugfs file for %s\n", | ||
| 214 | d->gd->disk_name); | ||
| 215 | return; | ||
| 216 | } | ||
| 217 | BUG_ON(d->debugfs); | ||
| 218 | d->debugfs = entry; | ||
| 219 | } | 211 | } |
| 220 | void | 212 | void |
| 221 | aoedisk_rm_debugfs(struct aoedev *d) | 213 | aoedisk_rm_debugfs(struct aoedev *d) |
| @@ -472,10 +464,6 @@ aoeblk_init(void) | |||
| 472 | if (buf_pool_cache == NULL) | 464 | if (buf_pool_cache == NULL) |
| 473 | return -ENOMEM; | 465 | return -ENOMEM; |
| 474 | aoe_debugfs_dir = debugfs_create_dir("aoe", NULL); | 466 | aoe_debugfs_dir = debugfs_create_dir("aoe", NULL); |
| 475 | if (IS_ERR_OR_NULL(aoe_debugfs_dir)) { | ||
| 476 | pr_info("aoe: cannot create debugfs directory\n"); | ||
| 477 | aoe_debugfs_dir = NULL; | ||
| 478 | } | ||
| 479 | return 0; | 467 | return 0; |
| 480 | } | 468 | } |
| 481 | 469 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index bacfdac7161c..a14b09ab3a41 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
| @@ -3676,6 +3676,7 @@ skip_create_disk: | |||
| 3676 | blk_queue_physical_block_size(dd->queue, 4096); | 3676 | blk_queue_physical_block_size(dd->queue, 4096); |
| 3677 | blk_queue_max_hw_sectors(dd->queue, 0xffff); | 3677 | blk_queue_max_hw_sectors(dd->queue, 0xffff); |
| 3678 | blk_queue_max_segment_size(dd->queue, 0x400000); | 3678 | blk_queue_max_segment_size(dd->queue, 0x400000); |
| 3679 | dma_set_max_seg_size(&dd->pdev->dev, 0x400000); | ||
| 3679 | blk_queue_io_min(dd->queue, 4096); | 3680 | blk_queue_io_min(dd->queue, 4096); |
| 3680 | 3681 | ||
| 3681 | /* Set the capacity of the device in 512 byte sectors. */ | 3682 | /* Set the capacity of the device in 512 byte sectors. */ |
diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index de9b2d2f8654..76b73ddf8fd7 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c | |||
| @@ -767,7 +767,6 @@ static int rsxx_pci_probe(struct pci_dev *dev, | |||
| 767 | goto failed_enable; | 767 | goto failed_enable; |
| 768 | 768 | ||
| 769 | pci_set_master(dev); | 769 | pci_set_master(dev); |
| 770 | dma_set_max_seg_size(&dev->dev, RSXX_HW_BLK_SIZE); | ||
| 771 | 770 | ||
| 772 | st = dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); | 771 | st = dma_set_mask(&dev->dev, DMA_BIT_MASK(64)); |
| 773 | if (st) { | 772 | if (st) { |
diff --git a/drivers/mmc/core/queue.c b/drivers/mmc/core/queue.c index b5b9c6142f08..92900a095796 100644 --- a/drivers/mmc/core/queue.c +++ b/drivers/mmc/core/queue.c | |||
| @@ -377,6 +377,8 @@ static void mmc_setup_queue(struct mmc_queue *mq, struct mmc_card *card) | |||
| 377 | blk_queue_max_segment_size(mq->queue, | 377 | blk_queue_max_segment_size(mq->queue, |
| 378 | round_down(host->max_seg_size, block_size)); | 378 | round_down(host->max_seg_size, block_size)); |
| 379 | 379 | ||
| 380 | dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue)); | ||
| 381 | |||
| 380 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); | 382 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); |
| 381 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); | 383 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); |
| 382 | 384 | ||
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1b7c2afd84cb..120fb593d1da 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c | |||
| @@ -3400,7 +3400,8 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl, unsigned nn) | |||
| 3400 | { | 3400 | { |
| 3401 | struct nvme_ns *ns; | 3401 | struct nvme_ns *ns; |
| 3402 | __le32 *ns_list; | 3402 | __le32 *ns_list; |
| 3403 | unsigned i, j, nsid, prev = 0, num_lists = DIV_ROUND_UP(nn, 1024); | 3403 | unsigned i, j, nsid, prev = 0; |
| 3404 | unsigned num_lists = DIV_ROUND_UP_ULL((u64)nn, 1024); | ||
| 3404 | int ret = 0; | 3405 | int ret = 0; |
| 3405 | 3406 | ||
| 3406 | ns_list = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL); | 3407 | ns_list = kzalloc(NVME_IDENTIFY_DATA_SIZE, GFP_KERNEL); |
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index f562154551ce..524d6bd6d095 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c | |||
| @@ -2513,6 +2513,12 @@ static void nvme_reset_work(struct work_struct *work) | |||
| 2513 | */ | 2513 | */ |
| 2514 | dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1; | 2514 | dev->ctrl.max_hw_sectors = NVME_MAX_KB_SZ << 1; |
| 2515 | dev->ctrl.max_segments = NVME_MAX_SEGS; | 2515 | dev->ctrl.max_segments = NVME_MAX_SEGS; |
| 2516 | |||
| 2517 | /* | ||
| 2518 | * Don't limit the IOMMU merged segment size. | ||
| 2519 | */ | ||
| 2520 | dma_set_max_seg_size(dev->dev, 0xffffffff); | ||
| 2521 | |||
| 2516 | mutex_unlock(&dev->shutdown_lock); | 2522 | mutex_unlock(&dev->shutdown_lock); |
| 2517 | 2523 | ||
| 2518 | /* | 2524 | /* |
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index f383146e7d0f..97f668a39ae1 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c | |||
| @@ -213,6 +213,11 @@ static struct nvme_rdma_qe *nvme_rdma_alloc_ring(struct ib_device *ibdev, | |||
| 213 | if (!ring) | 213 | if (!ring) |
| 214 | return NULL; | 214 | return NULL; |
| 215 | 215 | ||
| 216 | /* | ||
| 217 | * Bind the CQEs (post recv buffers) DMA mapping to the RDMA queue | ||
| 218 | * lifetime. It's safe, since any chage in the underlying RDMA device | ||
| 219 | * will issue error recovery and queue re-creation. | ||
| 220 | */ | ||
| 216 | for (i = 0; i < ib_queue_size; i++) { | 221 | for (i = 0; i < ib_queue_size; i++) { |
| 217 | if (nvme_rdma_alloc_qe(ibdev, &ring[i], capsule_size, dir)) | 222 | if (nvme_rdma_alloc_qe(ibdev, &ring[i], capsule_size, dir)) |
| 218 | goto out_free_ring; | 223 | goto out_free_ring; |
| @@ -274,14 +279,9 @@ static int nvme_rdma_create_qp(struct nvme_rdma_queue *queue, const int factor) | |||
| 274 | static void nvme_rdma_exit_request(struct blk_mq_tag_set *set, | 279 | static void nvme_rdma_exit_request(struct blk_mq_tag_set *set, |
| 275 | struct request *rq, unsigned int hctx_idx) | 280 | struct request *rq, unsigned int hctx_idx) |
| 276 | { | 281 | { |
| 277 | struct nvme_rdma_ctrl *ctrl = set->driver_data; | ||
| 278 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); | 282 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); |
| 279 | int queue_idx = (set == &ctrl->tag_set) ? hctx_idx + 1 : 0; | ||
| 280 | struct nvme_rdma_queue *queue = &ctrl->queues[queue_idx]; | ||
| 281 | struct nvme_rdma_device *dev = queue->device; | ||
| 282 | 283 | ||
| 283 | nvme_rdma_free_qe(dev->dev, &req->sqe, sizeof(struct nvme_command), | 284 | kfree(req->sqe.data); |
| 284 | DMA_TO_DEVICE); | ||
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | static int nvme_rdma_init_request(struct blk_mq_tag_set *set, | 287 | static int nvme_rdma_init_request(struct blk_mq_tag_set *set, |
| @@ -292,15 +292,11 @@ static int nvme_rdma_init_request(struct blk_mq_tag_set *set, | |||
| 292 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); | 292 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); |
| 293 | int queue_idx = (set == &ctrl->tag_set) ? hctx_idx + 1 : 0; | 293 | int queue_idx = (set == &ctrl->tag_set) ? hctx_idx + 1 : 0; |
| 294 | struct nvme_rdma_queue *queue = &ctrl->queues[queue_idx]; | 294 | struct nvme_rdma_queue *queue = &ctrl->queues[queue_idx]; |
| 295 | struct nvme_rdma_device *dev = queue->device; | ||
| 296 | struct ib_device *ibdev = dev->dev; | ||
| 297 | int ret; | ||
| 298 | 295 | ||
| 299 | nvme_req(rq)->ctrl = &ctrl->ctrl; | 296 | nvme_req(rq)->ctrl = &ctrl->ctrl; |
| 300 | ret = nvme_rdma_alloc_qe(ibdev, &req->sqe, sizeof(struct nvme_command), | 297 | req->sqe.data = kzalloc(sizeof(struct nvme_command), GFP_KERNEL); |
| 301 | DMA_TO_DEVICE); | 298 | if (!req->sqe.data) |
| 302 | if (ret) | 299 | return -ENOMEM; |
| 303 | return ret; | ||
| 304 | 300 | ||
| 305 | req->queue = queue; | 301 | req->queue = queue; |
| 306 | 302 | ||
| @@ -641,34 +637,16 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl) | |||
| 641 | { | 637 | { |
| 642 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; | 638 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; |
| 643 | struct ib_device *ibdev = ctrl->device->dev; | 639 | struct ib_device *ibdev = ctrl->device->dev; |
| 644 | unsigned int nr_io_queues; | 640 | unsigned int nr_io_queues, nr_default_queues; |
| 641 | unsigned int nr_read_queues, nr_poll_queues; | ||
| 645 | int i, ret; | 642 | int i, ret; |
| 646 | 643 | ||
| 647 | nr_io_queues = min(opts->nr_io_queues, num_online_cpus()); | 644 | nr_read_queues = min_t(unsigned int, ibdev->num_comp_vectors, |
| 648 | 645 | min(opts->nr_io_queues, num_online_cpus())); | |
| 649 | /* | 646 | nr_default_queues = min_t(unsigned int, ibdev->num_comp_vectors, |
| 650 | * we map queues according to the device irq vectors for | 647 | min(opts->nr_write_queues, num_online_cpus())); |
| 651 | * optimal locality so we don't need more queues than | 648 | nr_poll_queues = min(opts->nr_poll_queues, num_online_cpus()); |
| 652 | * completion vectors. | 649 | nr_io_queues = nr_read_queues + nr_default_queues + nr_poll_queues; |
| 653 | */ | ||
| 654 | nr_io_queues = min_t(unsigned int, nr_io_queues, | ||
| 655 | ibdev->num_comp_vectors); | ||
| 656 | |||
| 657 | if (opts->nr_write_queues) { | ||
| 658 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = | ||
| 659 | min(opts->nr_write_queues, nr_io_queues); | ||
| 660 | nr_io_queues += ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 661 | } else { | ||
| 662 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = nr_io_queues; | ||
| 663 | } | ||
| 664 | |||
| 665 | ctrl->io_queues[HCTX_TYPE_READ] = nr_io_queues; | ||
| 666 | |||
| 667 | if (opts->nr_poll_queues) { | ||
| 668 | ctrl->io_queues[HCTX_TYPE_POLL] = | ||
| 669 | min(opts->nr_poll_queues, num_online_cpus()); | ||
| 670 | nr_io_queues += ctrl->io_queues[HCTX_TYPE_POLL]; | ||
| 671 | } | ||
| 672 | 650 | ||
| 673 | ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues); | 651 | ret = nvme_set_queue_count(&ctrl->ctrl, &nr_io_queues); |
| 674 | if (ret) | 652 | if (ret) |
| @@ -681,6 +659,34 @@ static int nvme_rdma_alloc_io_queues(struct nvme_rdma_ctrl *ctrl) | |||
| 681 | dev_info(ctrl->ctrl.device, | 659 | dev_info(ctrl->ctrl.device, |
| 682 | "creating %d I/O queues.\n", nr_io_queues); | 660 | "creating %d I/O queues.\n", nr_io_queues); |
| 683 | 661 | ||
| 662 | if (opts->nr_write_queues && nr_read_queues < nr_io_queues) { | ||
| 663 | /* | ||
| 664 | * separate read/write queues | ||
| 665 | * hand out dedicated default queues only after we have | ||
| 666 | * sufficient read queues. | ||
| 667 | */ | ||
| 668 | ctrl->io_queues[HCTX_TYPE_READ] = nr_read_queues; | ||
| 669 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 670 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = | ||
| 671 | min(nr_default_queues, nr_io_queues); | ||
| 672 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 673 | } else { | ||
| 674 | /* | ||
| 675 | * shared read/write queues | ||
| 676 | * either no write queues were requested, or we don't have | ||
| 677 | * sufficient queue count to have dedicated default queues. | ||
| 678 | */ | ||
| 679 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = | ||
| 680 | min(nr_read_queues, nr_io_queues); | ||
| 681 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 682 | } | ||
| 683 | |||
| 684 | if (opts->nr_poll_queues && nr_io_queues) { | ||
| 685 | /* map dedicated poll queues only if we have queues left */ | ||
| 686 | ctrl->io_queues[HCTX_TYPE_POLL] = | ||
| 687 | min(nr_poll_queues, nr_io_queues); | ||
| 688 | } | ||
| 689 | |||
| 684 | for (i = 1; i < ctrl->ctrl.queue_count; i++) { | 690 | for (i = 1; i < ctrl->ctrl.queue_count; i++) { |
| 685 | ret = nvme_rdma_alloc_queue(ctrl, i, | 691 | ret = nvme_rdma_alloc_queue(ctrl, i, |
| 686 | ctrl->ctrl.sqsize + 1); | 692 | ctrl->ctrl.sqsize + 1); |
| @@ -769,6 +775,11 @@ static int nvme_rdma_configure_admin_queue(struct nvme_rdma_ctrl *ctrl, | |||
| 769 | 775 | ||
| 770 | ctrl->max_fr_pages = nvme_rdma_get_max_fr_pages(ctrl->device->dev); | 776 | ctrl->max_fr_pages = nvme_rdma_get_max_fr_pages(ctrl->device->dev); |
| 771 | 777 | ||
| 778 | /* | ||
| 779 | * Bind the async event SQE DMA mapping to the admin queue lifetime. | ||
| 780 | * It's safe, since any chage in the underlying RDMA device will issue | ||
| 781 | * error recovery and queue re-creation. | ||
| 782 | */ | ||
| 772 | error = nvme_rdma_alloc_qe(ctrl->device->dev, &ctrl->async_event_sqe, | 783 | error = nvme_rdma_alloc_qe(ctrl->device->dev, &ctrl->async_event_sqe, |
| 773 | sizeof(struct nvme_command), DMA_TO_DEVICE); | 784 | sizeof(struct nvme_command), DMA_TO_DEVICE); |
| 774 | if (error) | 785 | if (error) |
| @@ -1709,12 +1720,20 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 1709 | return nvmf_fail_nonready_command(&queue->ctrl->ctrl, rq); | 1720 | return nvmf_fail_nonready_command(&queue->ctrl->ctrl, rq); |
| 1710 | 1721 | ||
| 1711 | dev = queue->device->dev; | 1722 | dev = queue->device->dev; |
| 1723 | |||
| 1724 | req->sqe.dma = ib_dma_map_single(dev, req->sqe.data, | ||
| 1725 | sizeof(struct nvme_command), | ||
| 1726 | DMA_TO_DEVICE); | ||
| 1727 | err = ib_dma_mapping_error(dev, req->sqe.dma); | ||
| 1728 | if (unlikely(err)) | ||
| 1729 | return BLK_STS_RESOURCE; | ||
| 1730 | |||
| 1712 | ib_dma_sync_single_for_cpu(dev, sqe->dma, | 1731 | ib_dma_sync_single_for_cpu(dev, sqe->dma, |
| 1713 | sizeof(struct nvme_command), DMA_TO_DEVICE); | 1732 | sizeof(struct nvme_command), DMA_TO_DEVICE); |
| 1714 | 1733 | ||
| 1715 | ret = nvme_setup_cmd(ns, rq, c); | 1734 | ret = nvme_setup_cmd(ns, rq, c); |
| 1716 | if (ret) | 1735 | if (ret) |
| 1717 | return ret; | 1736 | goto unmap_qe; |
| 1718 | 1737 | ||
| 1719 | blk_mq_start_request(rq); | 1738 | blk_mq_start_request(rq); |
| 1720 | 1739 | ||
| @@ -1739,10 +1758,16 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 1739 | } | 1758 | } |
| 1740 | 1759 | ||
| 1741 | return BLK_STS_OK; | 1760 | return BLK_STS_OK; |
| 1761 | |||
| 1742 | err: | 1762 | err: |
| 1743 | if (err == -ENOMEM || err == -EAGAIN) | 1763 | if (err == -ENOMEM || err == -EAGAIN) |
| 1744 | return BLK_STS_RESOURCE; | 1764 | ret = BLK_STS_RESOURCE; |
| 1745 | return BLK_STS_IOERR; | 1765 | else |
| 1766 | ret = BLK_STS_IOERR; | ||
| 1767 | unmap_qe: | ||
| 1768 | ib_dma_unmap_single(dev, req->sqe.dma, sizeof(struct nvme_command), | ||
| 1769 | DMA_TO_DEVICE); | ||
| 1770 | return ret; | ||
| 1746 | } | 1771 | } |
| 1747 | 1772 | ||
| 1748 | static int nvme_rdma_poll(struct blk_mq_hw_ctx *hctx) | 1773 | static int nvme_rdma_poll(struct blk_mq_hw_ctx *hctx) |
| @@ -1755,25 +1780,36 @@ static int nvme_rdma_poll(struct blk_mq_hw_ctx *hctx) | |||
| 1755 | static void nvme_rdma_complete_rq(struct request *rq) | 1780 | static void nvme_rdma_complete_rq(struct request *rq) |
| 1756 | { | 1781 | { |
| 1757 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); | 1782 | struct nvme_rdma_request *req = blk_mq_rq_to_pdu(rq); |
| 1783 | struct nvme_rdma_queue *queue = req->queue; | ||
| 1784 | struct ib_device *ibdev = queue->device->dev; | ||
| 1758 | 1785 | ||
| 1759 | nvme_rdma_unmap_data(req->queue, rq); | 1786 | nvme_rdma_unmap_data(queue, rq); |
| 1787 | ib_dma_unmap_single(ibdev, req->sqe.dma, sizeof(struct nvme_command), | ||
| 1788 | DMA_TO_DEVICE); | ||
| 1760 | nvme_complete_rq(rq); | 1789 | nvme_complete_rq(rq); |
| 1761 | } | 1790 | } |
| 1762 | 1791 | ||
| 1763 | static int nvme_rdma_map_queues(struct blk_mq_tag_set *set) | 1792 | static int nvme_rdma_map_queues(struct blk_mq_tag_set *set) |
| 1764 | { | 1793 | { |
| 1765 | struct nvme_rdma_ctrl *ctrl = set->driver_data; | 1794 | struct nvme_rdma_ctrl *ctrl = set->driver_data; |
| 1795 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; | ||
| 1766 | 1796 | ||
| 1767 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | 1797 | if (opts->nr_write_queues && ctrl->io_queues[HCTX_TYPE_READ]) { |
| 1768 | set->map[HCTX_TYPE_DEFAULT].nr_queues = | ||
| 1769 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1770 | set->map[HCTX_TYPE_READ].nr_queues = ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 1771 | if (ctrl->ctrl.opts->nr_write_queues) { | ||
| 1772 | /* separate read/write queues */ | 1798 | /* separate read/write queues */ |
| 1799 | set->map[HCTX_TYPE_DEFAULT].nr_queues = | ||
| 1800 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1801 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | ||
| 1802 | set->map[HCTX_TYPE_READ].nr_queues = | ||
| 1803 | ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 1773 | set->map[HCTX_TYPE_READ].queue_offset = | 1804 | set->map[HCTX_TYPE_READ].queue_offset = |
| 1774 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | 1805 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; |
| 1775 | } else { | 1806 | } else { |
| 1776 | /* mixed read/write queues */ | 1807 | /* shared read/write queues */ |
| 1808 | set->map[HCTX_TYPE_DEFAULT].nr_queues = | ||
| 1809 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1810 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | ||
| 1811 | set->map[HCTX_TYPE_READ].nr_queues = | ||
| 1812 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1777 | set->map[HCTX_TYPE_READ].queue_offset = 0; | 1813 | set->map[HCTX_TYPE_READ].queue_offset = 0; |
| 1778 | } | 1814 | } |
| 1779 | blk_mq_rdma_map_queues(&set->map[HCTX_TYPE_DEFAULT], | 1815 | blk_mq_rdma_map_queues(&set->map[HCTX_TYPE_DEFAULT], |
| @@ -1781,16 +1817,22 @@ static int nvme_rdma_map_queues(struct blk_mq_tag_set *set) | |||
| 1781 | blk_mq_rdma_map_queues(&set->map[HCTX_TYPE_READ], | 1817 | blk_mq_rdma_map_queues(&set->map[HCTX_TYPE_READ], |
| 1782 | ctrl->device->dev, 0); | 1818 | ctrl->device->dev, 0); |
| 1783 | 1819 | ||
| 1784 | if (ctrl->ctrl.opts->nr_poll_queues) { | 1820 | if (opts->nr_poll_queues && ctrl->io_queues[HCTX_TYPE_POLL]) { |
| 1821 | /* map dedicated poll queues only if we have queues left */ | ||
| 1785 | set->map[HCTX_TYPE_POLL].nr_queues = | 1822 | set->map[HCTX_TYPE_POLL].nr_queues = |
| 1786 | ctrl->io_queues[HCTX_TYPE_POLL]; | 1823 | ctrl->io_queues[HCTX_TYPE_POLL]; |
| 1787 | set->map[HCTX_TYPE_POLL].queue_offset = | 1824 | set->map[HCTX_TYPE_POLL].queue_offset = |
| 1788 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | 1825 | ctrl->io_queues[HCTX_TYPE_DEFAULT] + |
| 1789 | if (ctrl->ctrl.opts->nr_write_queues) | 1826 | ctrl->io_queues[HCTX_TYPE_READ]; |
| 1790 | set->map[HCTX_TYPE_POLL].queue_offset += | ||
| 1791 | ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 1792 | blk_mq_map_queues(&set->map[HCTX_TYPE_POLL]); | 1827 | blk_mq_map_queues(&set->map[HCTX_TYPE_POLL]); |
| 1793 | } | 1828 | } |
| 1829 | |||
| 1830 | dev_info(ctrl->ctrl.device, | ||
| 1831 | "mapped %d/%d/%d default/read/poll queues.\n", | ||
| 1832 | ctrl->io_queues[HCTX_TYPE_DEFAULT], | ||
| 1833 | ctrl->io_queues[HCTX_TYPE_READ], | ||
| 1834 | ctrl->io_queues[HCTX_TYPE_POLL]); | ||
| 1835 | |||
| 1794 | return 0; | 1836 | return 0; |
| 1795 | } | 1837 | } |
| 1796 | 1838 | ||
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 2b107a1d152b..08a2501b9357 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c | |||
| @@ -111,6 +111,7 @@ struct nvme_tcp_ctrl { | |||
| 111 | struct work_struct err_work; | 111 | struct work_struct err_work; |
| 112 | struct delayed_work connect_work; | 112 | struct delayed_work connect_work; |
| 113 | struct nvme_tcp_request async_req; | 113 | struct nvme_tcp_request async_req; |
| 114 | u32 io_queues[HCTX_MAX_TYPES]; | ||
| 114 | }; | 115 | }; |
| 115 | 116 | ||
| 116 | static LIST_HEAD(nvme_tcp_ctrl_list); | 117 | static LIST_HEAD(nvme_tcp_ctrl_list); |
| @@ -1564,6 +1565,35 @@ static unsigned int nvme_tcp_nr_io_queues(struct nvme_ctrl *ctrl) | |||
| 1564 | return nr_io_queues; | 1565 | return nr_io_queues; |
| 1565 | } | 1566 | } |
| 1566 | 1567 | ||
| 1568 | static void nvme_tcp_set_io_queues(struct nvme_ctrl *nctrl, | ||
| 1569 | unsigned int nr_io_queues) | ||
| 1570 | { | ||
| 1571 | struct nvme_tcp_ctrl *ctrl = to_tcp_ctrl(nctrl); | ||
| 1572 | struct nvmf_ctrl_options *opts = nctrl->opts; | ||
| 1573 | |||
| 1574 | if (opts->nr_write_queues && opts->nr_io_queues < nr_io_queues) { | ||
| 1575 | /* | ||
| 1576 | * separate read/write queues | ||
| 1577 | * hand out dedicated default queues only after we have | ||
| 1578 | * sufficient read queues. | ||
| 1579 | */ | ||
| 1580 | ctrl->io_queues[HCTX_TYPE_READ] = opts->nr_io_queues; | ||
| 1581 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 1582 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = | ||
| 1583 | min(opts->nr_write_queues, nr_io_queues); | ||
| 1584 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1585 | } else { | ||
| 1586 | /* | ||
| 1587 | * shared read/write queues | ||
| 1588 | * either no write queues were requested, or we don't have | ||
| 1589 | * sufficient queue count to have dedicated default queues. | ||
| 1590 | */ | ||
| 1591 | ctrl->io_queues[HCTX_TYPE_DEFAULT] = | ||
| 1592 | min(opts->nr_io_queues, nr_io_queues); | ||
| 1593 | nr_io_queues -= ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 1594 | } | ||
| 1595 | } | ||
| 1596 | |||
| 1567 | static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) | 1597 | static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) |
| 1568 | { | 1598 | { |
| 1569 | unsigned int nr_io_queues; | 1599 | unsigned int nr_io_queues; |
| @@ -1581,6 +1611,8 @@ static int nvme_tcp_alloc_io_queues(struct nvme_ctrl *ctrl) | |||
| 1581 | dev_info(ctrl->device, | 1611 | dev_info(ctrl->device, |
| 1582 | "creating %d I/O queues.\n", nr_io_queues); | 1612 | "creating %d I/O queues.\n", nr_io_queues); |
| 1583 | 1613 | ||
| 1614 | nvme_tcp_set_io_queues(ctrl, nr_io_queues); | ||
| 1615 | |||
| 1584 | return __nvme_tcp_alloc_io_queues(ctrl); | 1616 | return __nvme_tcp_alloc_io_queues(ctrl); |
| 1585 | } | 1617 | } |
| 1586 | 1618 | ||
| @@ -2089,23 +2121,34 @@ static blk_status_t nvme_tcp_queue_rq(struct blk_mq_hw_ctx *hctx, | |||
| 2089 | static int nvme_tcp_map_queues(struct blk_mq_tag_set *set) | 2121 | static int nvme_tcp_map_queues(struct blk_mq_tag_set *set) |
| 2090 | { | 2122 | { |
| 2091 | struct nvme_tcp_ctrl *ctrl = set->driver_data; | 2123 | struct nvme_tcp_ctrl *ctrl = set->driver_data; |
| 2124 | struct nvmf_ctrl_options *opts = ctrl->ctrl.opts; | ||
| 2092 | 2125 | ||
| 2093 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | 2126 | if (opts->nr_write_queues && ctrl->io_queues[HCTX_TYPE_READ]) { |
| 2094 | set->map[HCTX_TYPE_READ].nr_queues = ctrl->ctrl.opts->nr_io_queues; | ||
| 2095 | if (ctrl->ctrl.opts->nr_write_queues) { | ||
| 2096 | /* separate read/write queues */ | 2127 | /* separate read/write queues */ |
| 2097 | set->map[HCTX_TYPE_DEFAULT].nr_queues = | 2128 | set->map[HCTX_TYPE_DEFAULT].nr_queues = |
| 2098 | ctrl->ctrl.opts->nr_write_queues; | 2129 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; |
| 2130 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | ||
| 2131 | set->map[HCTX_TYPE_READ].nr_queues = | ||
| 2132 | ctrl->io_queues[HCTX_TYPE_READ]; | ||
| 2099 | set->map[HCTX_TYPE_READ].queue_offset = | 2133 | set->map[HCTX_TYPE_READ].queue_offset = |
| 2100 | ctrl->ctrl.opts->nr_write_queues; | 2134 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; |
| 2101 | } else { | 2135 | } else { |
| 2102 | /* mixed read/write queues */ | 2136 | /* shared read/write queues */ |
| 2103 | set->map[HCTX_TYPE_DEFAULT].nr_queues = | 2137 | set->map[HCTX_TYPE_DEFAULT].nr_queues = |
| 2104 | ctrl->ctrl.opts->nr_io_queues; | 2138 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; |
| 2139 | set->map[HCTX_TYPE_DEFAULT].queue_offset = 0; | ||
| 2140 | set->map[HCTX_TYPE_READ].nr_queues = | ||
| 2141 | ctrl->io_queues[HCTX_TYPE_DEFAULT]; | ||
| 2105 | set->map[HCTX_TYPE_READ].queue_offset = 0; | 2142 | set->map[HCTX_TYPE_READ].queue_offset = 0; |
| 2106 | } | 2143 | } |
| 2107 | blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); | 2144 | blk_mq_map_queues(&set->map[HCTX_TYPE_DEFAULT]); |
| 2108 | blk_mq_map_queues(&set->map[HCTX_TYPE_READ]); | 2145 | blk_mq_map_queues(&set->map[HCTX_TYPE_READ]); |
| 2146 | |||
| 2147 | dev_info(ctrl->ctrl.device, | ||
| 2148 | "mapped %d/%d default/read queues.\n", | ||
| 2149 | ctrl->io_queues[HCTX_TYPE_DEFAULT], | ||
| 2150 | ctrl->io_queues[HCTX_TYPE_READ]); | ||
| 2151 | |||
| 2109 | return 0; | 2152 | return 0; |
| 2110 | } | 2153 | } |
| 2111 | 2154 | ||
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c index 3efc52f9c309..7a1cf6437a6a 100644 --- a/drivers/nvme/target/io-cmd-bdev.c +++ b/drivers/nvme/target/io-cmd-bdev.c | |||
| @@ -293,6 +293,7 @@ u16 nvmet_bdev_parse_io_cmd(struct nvmet_req *req) | |||
| 293 | return 0; | 293 | return 0; |
| 294 | case nvme_cmd_write_zeroes: | 294 | case nvme_cmd_write_zeroes: |
| 295 | req->execute = nvmet_bdev_execute_write_zeroes; | 295 | req->execute = nvmet_bdev_execute_write_zeroes; |
| 296 | req->data_len = 0; | ||
| 296 | return 0; | 297 | return 0; |
| 297 | default: | 298 | default: |
| 298 | pr_err("unhandled cmd %d on qid %d\n", cmd->common.opcode, | 299 | pr_err("unhandled cmd %d on qid %d\n", cmd->common.opcode, |
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 11e215d7937e..d71b079bb021 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h | |||
| @@ -106,6 +106,8 @@ enum { | |||
| 106 | CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ | 106 | CFTYPE_WORLD_WRITABLE = (1 << 4), /* (DON'T USE FOR NEW FILES) S_IWUGO */ |
| 107 | CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ | 107 | CFTYPE_DEBUG = (1 << 5), /* create when cgroup_debug */ |
| 108 | 108 | ||
| 109 | CFTYPE_SYMLINKED = (1 << 6), /* pointed to by symlink too */ | ||
| 110 | |||
| 109 | /* internal flags, do not use outside cgroup core proper */ | 111 | /* internal flags, do not use outside cgroup core proper */ |
| 110 | __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ | 112 | __CFTYPE_ONLY_ON_DFL = (1 << 16), /* only on default hierarchy */ |
| 111 | __CFTYPE_NOT_ON_DFL = (1 << 17), /* not on default hierarchy */ | 113 | __CFTYPE_NOT_ON_DFL = (1 << 17), /* not on default hierarchy */ |
| @@ -543,6 +545,7 @@ struct cftype { | |||
| 543 | * end of cftype array. | 545 | * end of cftype array. |
| 544 | */ | 546 | */ |
| 545 | char name[MAX_CFTYPE_NAME]; | 547 | char name[MAX_CFTYPE_NAME]; |
| 548 | char link_name[MAX_CFTYPE_NAME]; | ||
| 546 | unsigned long private; | 549 | unsigned long private; |
| 547 | 550 | ||
| 548 | /* | 551 | /* |
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 426a0026225c..155048b0eca2 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c | |||
| @@ -1460,8 +1460,8 @@ struct cgroup *task_cgroup_from_root(struct task_struct *task, | |||
| 1460 | 1460 | ||
| 1461 | static struct kernfs_syscall_ops cgroup_kf_syscall_ops; | 1461 | static struct kernfs_syscall_ops cgroup_kf_syscall_ops; |
| 1462 | 1462 | ||
| 1463 | static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, | 1463 | static char *cgroup_fill_name(struct cgroup *cgrp, const struct cftype *cft, |
| 1464 | char *buf) | 1464 | char *buf, bool write_link_name) |
| 1465 | { | 1465 | { |
| 1466 | struct cgroup_subsys *ss = cft->ss; | 1466 | struct cgroup_subsys *ss = cft->ss; |
| 1467 | 1467 | ||
| @@ -1471,13 +1471,26 @@ static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, | |||
| 1471 | 1471 | ||
| 1472 | snprintf(buf, CGROUP_FILE_NAME_MAX, "%s%s.%s", | 1472 | snprintf(buf, CGROUP_FILE_NAME_MAX, "%s%s.%s", |
| 1473 | dbg, cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, | 1473 | dbg, cgroup_on_dfl(cgrp) ? ss->name : ss->legacy_name, |
| 1474 | cft->name); | 1474 | write_link_name ? cft->link_name : cft->name); |
| 1475 | } else { | 1475 | } else { |
| 1476 | strscpy(buf, cft->name, CGROUP_FILE_NAME_MAX); | 1476 | strscpy(buf, write_link_name ? cft->link_name : cft->name, |
| 1477 | CGROUP_FILE_NAME_MAX); | ||
| 1477 | } | 1478 | } |
| 1478 | return buf; | 1479 | return buf; |
| 1479 | } | 1480 | } |
| 1480 | 1481 | ||
| 1482 | static char *cgroup_file_name(struct cgroup *cgrp, const struct cftype *cft, | ||
| 1483 | char *buf) | ||
| 1484 | { | ||
| 1485 | return cgroup_fill_name(cgrp, cft, buf, false); | ||
| 1486 | } | ||
| 1487 | |||
| 1488 | static char *cgroup_link_name(struct cgroup *cgrp, const struct cftype *cft, | ||
| 1489 | char *buf) | ||
| 1490 | { | ||
| 1491 | return cgroup_fill_name(cgrp, cft, buf, true); | ||
| 1492 | } | ||
| 1493 | |||
| 1481 | /** | 1494 | /** |
| 1482 | * cgroup_file_mode - deduce file mode of a control file | 1495 | * cgroup_file_mode - deduce file mode of a control file |
| 1483 | * @cft: the control file in question | 1496 | * @cft: the control file in question |
| @@ -1636,6 +1649,9 @@ static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft) | |||
| 1636 | } | 1649 | } |
| 1637 | 1650 | ||
| 1638 | kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); | 1651 | kernfs_remove_by_name(cgrp->kn, cgroup_file_name(cgrp, cft, name)); |
| 1652 | if (cft->flags & CFTYPE_SYMLINKED) | ||
| 1653 | kernfs_remove_by_name(cgrp->kn, | ||
| 1654 | cgroup_link_name(cgrp, cft, name)); | ||
| 1639 | } | 1655 | } |
| 1640 | 1656 | ||
| 1641 | /** | 1657 | /** |
| @@ -3821,6 +3837,7 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp, | |||
| 3821 | { | 3837 | { |
| 3822 | char name[CGROUP_FILE_NAME_MAX]; | 3838 | char name[CGROUP_FILE_NAME_MAX]; |
| 3823 | struct kernfs_node *kn; | 3839 | struct kernfs_node *kn; |
| 3840 | struct kernfs_node *kn_link; | ||
| 3824 | struct lock_class_key *key = NULL; | 3841 | struct lock_class_key *key = NULL; |
| 3825 | int ret; | 3842 | int ret; |
| 3826 | 3843 | ||
| @@ -3851,6 +3868,14 @@ static int cgroup_add_file(struct cgroup_subsys_state *css, struct cgroup *cgrp, | |||
| 3851 | spin_unlock_irq(&cgroup_file_kn_lock); | 3868 | spin_unlock_irq(&cgroup_file_kn_lock); |
| 3852 | } | 3869 | } |
| 3853 | 3870 | ||
| 3871 | if (cft->flags & CFTYPE_SYMLINKED) { | ||
| 3872 | kn_link = kernfs_create_link(cgrp->kn, | ||
| 3873 | cgroup_link_name(cgrp, cft, name), | ||
| 3874 | kn); | ||
| 3875 | if (IS_ERR(kn_link)) | ||
| 3876 | return PTR_ERR(kn_link); | ||
| 3877 | } | ||
| 3878 | |||
| 3854 | return 0; | 3879 | return 0; |
| 3855 | } | 3880 | } |
| 3856 | 3881 | ||
