From: Greg Kroah-Hartman Date: Mon, 24 May 2021 12:22:19 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v4.4.270~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ccb585156b4666a36c1eaae2a69656d64316b55e;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: nvme-multipath-fix-double-initialization-of-ana-state.patch --- diff --git a/queue-5.10/nvme-multipath-fix-double-initialization-of-ana-state.patch b/queue-5.10/nvme-multipath-fix-double-initialization-of-ana-state.patch new file mode 100644 index 00000000000..9292ed6bc48 --- /dev/null +++ b/queue-5.10/nvme-multipath-fix-double-initialization-of-ana-state.patch @@ -0,0 +1,150 @@ +From 5e1f689913a4498e3081093670ef9d85b2c60920 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig +Date: Thu, 29 Apr 2021 14:18:53 +0200 +Subject: nvme-multipath: fix double initialization of ANA state + +From: Christoph Hellwig + +commit 5e1f689913a4498e3081093670ef9d85b2c60920 upstream. + +nvme_init_identify and thus nvme_mpath_init can be called multiple +times and thus must not overwrite potentially initialized or in-use +fields. Split out a helper for the basic initialization when the +controller is initialized and make sure the init_identify path does +not blindly change in-use data structures. + +Fixes: 0d0b660f214d ("nvme: add ANA support") +Reported-by: Martin Wilck +Signed-off-by: Christoph Hellwig +Reviewed-by: Keith Busch +Reviewed-by: Sagi Grimberg +Reviewed-by: Hannes Reinecke +Signed-off-by: Greg Kroah-Hartman +--- + drivers/nvme/host/core.c | 3 +- + drivers/nvme/host/multipath.c | 55 ++++++++++++++++++++++-------------------- + drivers/nvme/host/nvme.h | 8 ++++-- + 3 files changed, 37 insertions(+), 29 deletions(-) + +--- a/drivers/nvme/host/core.c ++++ b/drivers/nvme/host/core.c +@@ -3131,7 +3131,7 @@ int nvme_init_identify(struct nvme_ctrl + ctrl->hmmaxd = le16_to_cpu(id->hmmaxd); + } + +- ret = nvme_mpath_init(ctrl, id); ++ ret = nvme_mpath_init_identify(ctrl, id); + kfree(id); + + if (ret < 0) +@@ -4517,6 +4517,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctr + min(default_ps_max_latency_us, (unsigned long)S32_MAX)); + + nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device)); ++ nvme_mpath_init_ctrl(ctrl); + + return 0; + out_free_name: +--- a/drivers/nvme/host/multipath.c ++++ b/drivers/nvme/host/multipath.c +@@ -708,9 +708,18 @@ void nvme_mpath_remove_disk(struct nvme_ + put_disk(head->disk); + } + +-int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) ++void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) + { +- int error; ++ mutex_init(&ctrl->ana_lock); ++ timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); ++ INIT_WORK(&ctrl->ana_work, nvme_ana_work); ++} ++ ++int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) ++{ ++ size_t max_transfer_size = ctrl->max_hw_sectors << SECTOR_SHIFT; ++ size_t ana_log_size; ++ int error = 0; + + /* check if multipath is enabled and we have the capability */ + if (!multipath || !ctrl->subsys || +@@ -722,37 +731,31 @@ int nvme_mpath_init(struct nvme_ctrl *ct + ctrl->nanagrpid = le32_to_cpu(id->nanagrpid); + ctrl->anagrpmax = le32_to_cpu(id->anagrpmax); + +- mutex_init(&ctrl->ana_lock); +- timer_setup(&ctrl->anatt_timer, nvme_anatt_timeout, 0); +- ctrl->ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + +- ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc); +- ctrl->ana_log_size += ctrl->max_namespaces * sizeof(__le32); +- +- if (ctrl->ana_log_size > ctrl->max_hw_sectors << SECTOR_SHIFT) { ++ ana_log_size = sizeof(struct nvme_ana_rsp_hdr) + ++ ctrl->nanagrpid * sizeof(struct nvme_ana_group_desc) + ++ ctrl->max_namespaces * sizeof(__le32); ++ if (ana_log_size > max_transfer_size) { + dev_err(ctrl->device, +- "ANA log page size (%zd) larger than MDTS (%d).\n", +- ctrl->ana_log_size, +- ctrl->max_hw_sectors << SECTOR_SHIFT); ++ "ANA log page size (%zd) larger than MDTS (%zd).\n", ++ ana_log_size, max_transfer_size); + dev_err(ctrl->device, "disabling ANA support.\n"); +- return 0; ++ goto out_uninit; + } +- +- INIT_WORK(&ctrl->ana_work, nvme_ana_work); +- kfree(ctrl->ana_log_buf); +- ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL); +- if (!ctrl->ana_log_buf) { +- error = -ENOMEM; +- goto out; ++ if (ana_log_size > ctrl->ana_log_size) { ++ nvme_mpath_stop(ctrl); ++ kfree(ctrl->ana_log_buf); ++ ctrl->ana_log_buf = kmalloc(ctrl->ana_log_size, GFP_KERNEL); ++ if (!ctrl->ana_log_buf) ++ return -ENOMEM; + } +- ++ ctrl->ana_log_size = ana_log_size; + error = nvme_read_ana_log(ctrl); + if (error) +- goto out_free_ana_log_buf; ++ goto out_uninit; + return 0; +-out_free_ana_log_buf: +- kfree(ctrl->ana_log_buf); +- ctrl->ana_log_buf = NULL; +-out: ++ ++out_uninit: ++ nvme_mpath_uninit(ctrl); + return error; + } + +--- a/drivers/nvme/host/nvme.h ++++ b/drivers/nvme/host/nvme.h +@@ -654,7 +654,8 @@ void nvme_kick_requeue_lists(struct nvme + int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl,struct nvme_ns_head *head); + void nvme_mpath_add_disk(struct nvme_ns *ns, struct nvme_id_ns *id); + void nvme_mpath_remove_disk(struct nvme_ns_head *head); +-int nvme_mpath_init(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); ++int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id); ++void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl); + void nvme_mpath_uninit(struct nvme_ctrl *ctrl); + void nvme_mpath_stop(struct nvme_ctrl *ctrl); + bool nvme_mpath_clear_current_path(struct nvme_ns *ns); +@@ -730,7 +731,10 @@ static inline void nvme_trace_bio_comple + blk_status_t status) + { + } +-static inline int nvme_mpath_init(struct nvme_ctrl *ctrl, ++static inline void nvme_mpath_init_ctrl(struct nvme_ctrl *ctrl) ++{ ++} ++static inline int nvme_mpath_init_identify(struct nvme_ctrl *ctrl, + struct nvme_id_ctrl *id) + { + if (ctrl->subsys->cmic & (1 << 3)) diff --git a/queue-5.10/series b/queue-5.10/series index a34abfe8af5..4a227683989 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -99,3 +99,4 @@ tty-vt-always-invoke-vc-vc_sw-con_resize-callback.patch drm-i915-gt-disable-hiz-raw-stall-optimization-on-broken-gen7.patch openrisc-mm-init.c-remove-unused-memblock_region-variable-in-map_ram.patch x86-xen-swap-nx-determination-and-gdt-setup-on-bsp.patch +nvme-multipath-fix-double-initialization-of-ana-state.patch