nvme: always initialize known command effects
authorKeith Busch <kbusch@kernel.org>
Fri, 27 Jan 2023 16:56:19 +0000 (08:56 -0800)
committerChristoph Hellwig <hch@lst.de>
Wed, 1 Feb 2023 15:10:09 +0000 (16:10 +0100)
Instead of appending command effects flags per IO, set the known effects
flags the driver needs to react to just once during initial setup.

Signed-off-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Kanchan Joshi <joshi.k@samsung.com>
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c

index 564ce60..df929ba 100644 (file)
@@ -1061,41 +1061,12 @@ int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
 }
 EXPORT_SYMBOL_GPL(nvme_submit_sync_cmd);
 
-static u32 nvme_known_admin_effects(u8 opcode)
-{
-       switch (opcode) {
-       case nvme_admin_format_nvm:
-               return NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_NCC |
-                       NVME_CMD_EFFECTS_CSE_MASK;
-       case nvme_admin_sanitize_nvm:
-               return NVME_CMD_EFFECTS_LBCC | NVME_CMD_EFFECTS_CSE_MASK;
-       default:
-               break;
-       }
-       return 0;
-}
-
-static u32 nvme_known_nvm_effects(u8 opcode)
-{
-       switch (opcode) {
-       case nvme_cmd_write:
-       case nvme_cmd_write_zeroes:
-       case nvme_cmd_write_uncor:
-                return NVME_CMD_EFFECTS_LBCC;
-       default:
-               return 0;
-       }
-}
-
 u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
 {
        u32 effects = 0;
 
        if (ns) {
-               if (ns->head->effects)
-                       effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
-               if (ns->head->ids.csi == NVME_CSI_NVM)
-                       effects |= nvme_known_nvm_effects(opcode);
+               effects = le32_to_cpu(ns->head->effects->iocs[opcode]);
                if (effects & ~(NVME_CMD_EFFECTS_CSUPP | NVME_CMD_EFFECTS_LBCC))
                        dev_warn_once(ctrl->device,
                                "IO command:%02x has unusual effects:%08x\n",
@@ -1108,9 +1079,7 @@ u32 nvme_command_effects(struct nvme_ctrl *ctrl, struct nvme_ns *ns, u8 opcode)
                 */
                effects &= ~NVME_CMD_EFFECTS_CSE_MASK;
        } else {
-               if (ctrl->effects)
-                       effects = le32_to_cpu(ctrl->effects->acs[opcode]);
-               effects |= nvme_known_admin_effects(opcode);
+               effects = le32_to_cpu(ctrl->effects->acs[opcode]);
        }
 
        return effects;
@@ -3112,6 +3081,45 @@ free_data:
        return ret;
 }
 
+static void nvme_init_known_nvm_effects(struct nvme_ctrl *ctrl)
+{
+       struct nvme_effects_log *log = ctrl->effects;
+
+       log->acs[nvme_admin_format_nvm] |= cpu_to_le32(NVME_CMD_EFFECTS_LBCC |
+                                               NVME_CMD_EFFECTS_NCC |
+                                               NVME_CMD_EFFECTS_CSE_MASK);
+       log->acs[nvme_admin_sanitize_nvm] |= cpu_to_le32(NVME_CMD_EFFECTS_LBCC |
+                                               NVME_CMD_EFFECTS_CSE_MASK);
+
+       log->iocs[nvme_cmd_write] |= cpu_to_le32(NVME_CMD_EFFECTS_LBCC);
+       log->iocs[nvme_cmd_write_zeroes] |= cpu_to_le32(NVME_CMD_EFFECTS_LBCC);
+       log->iocs[nvme_cmd_write_uncor] |= cpu_to_le32(NVME_CMD_EFFECTS_LBCC);
+}
+
+static int nvme_init_effects(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+{
+       int ret = 0;
+
+       if (ctrl->effects)
+               return 0;
+
+       if (id->lpa & NVME_CTRL_LPA_CMD_EFFECTS_LOG) {
+               ret = nvme_get_effects_log(ctrl, NVME_CSI_NVM, &ctrl->effects);
+               if (ret < 0)
+                       return ret;
+       }
+
+       if (!ctrl->effects) {
+               ctrl->effects = kzalloc(sizeof(*ctrl->effects), GFP_KERNEL);
+               if (!ctrl->effects)
+                       return -ENOMEM;
+               xa_store(&ctrl->cels, NVME_CSI_NVM, ctrl->effects, GFP_KERNEL);
+       }
+
+       nvme_init_known_nvm_effects(ctrl);
+       return 0;
+}
+
 static int nvme_init_identify(struct nvme_ctrl *ctrl)
 {
        struct nvme_id_ctrl *id;
@@ -3125,12 +3133,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
                return -EIO;
        }
 
-       if (id->lpa & NVME_CTRL_LPA_CMD_EFFECTS_LOG) {
-               ret = nvme_get_effects_log(ctrl, NVME_CSI_NVM, &ctrl->effects);
-               if (ret < 0)
-                       goto out_free;
-       }
-
        if (!(ctrl->ops->flags & NVME_F_FABRICS))
                ctrl->cntlid = le16_to_cpu(id->cntlid);
 
@@ -3153,6 +3155,10 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
                ret = nvme_init_subsystem(ctrl, id);
                if (ret)
                        goto out_free;
+
+               ret = nvme_init_effects(ctrl, id);
+               if (ret)
+                       goto out_free;
        }
        memcpy(ctrl->subsys->firmware_rev, id->fr,
               sizeof(ctrl->subsys->firmware_rev));