nvme: enable to inject errors into admin commands
authorAkinobu Mita <akinobu.mita@gmail.com>
Sun, 9 Jun 2019 14:17:01 +0000 (23:17 +0900)
committerChristoph Hellwig <hch@lst.de>
Fri, 21 Jun 2019 09:15:50 +0000 (11:15 +0200)
This enables to inject errors into the commands submitted to the admin
queue.

It is useful to test error handling in the controller initialization.

# echo 100 > /sys/kernel/debug/nvme0/fault_inject/probability
# echo 1 > /sys/kernel/debug/nvme0/fault_inject/times
# echo 10 > /sys/kernel/debug/nvme0/fault_inject/space
# nvme reset /dev/nvme0
# dmesg
...
nvme nvme0: Could not set queue count (16385)
nvme nvme0: IO queues not created

Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Reviewed-by: Minwoo Im <minwoo.im.dev@gmail.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Chaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c
drivers/nvme/host/fault_inject.c
drivers/nvme/host/nvme.h

index 625605f8a0b50d45c22dc7824b45ad8c6942301b..b2dd4e391f5c20558c3bdc109078ea53fcaee9d2 100644 (file)
@@ -3722,6 +3722,7 @@ EXPORT_SYMBOL_GPL(nvme_start_ctrl);
 
 void nvme_uninit_ctrl(struct nvme_ctrl *ctrl)
 {
+       nvme_fault_inject_fini(&ctrl->fault_inject);
        dev_pm_qos_hide_latency_tolerance(ctrl->device);
        cdev_device_del(&ctrl->cdev, ctrl->device);
 }
@@ -3817,6 +3818,8 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
        dev_pm_qos_update_user_latency_tolerance(ctrl->device,
                min(default_ps_max_latency_us, (unsigned long)S32_MAX));
 
+       nvme_fault_inject_init(&ctrl->fault_inject, dev_name(ctrl->device));
+
        return 0;
 out_free_name:
        kfree_const(ctrl->device->kobj.name);
index e37b8c2fddeac5110796de598429bcfd01561c25..1352159733b08496f065b4583914922d34a34046 100644 (file)
@@ -60,9 +60,6 @@ void nvme_should_fail(struct request *req)
        struct nvme_fault_inject *fault_inject = NULL;
        u16 status;
 
-       /*
-        * make sure this request is coming from a valid namespace
-        */
        if (disk) {
                struct nvme_ns *ns = disk->private_data;
 
@@ -70,6 +67,8 @@ void nvme_should_fail(struct request *req)
                        fault_inject = &ns->fault_inject;
                else
                        WARN_ONCE(1, "No namespace found for request\n");
+       } else {
+               fault_inject = &nvme_req(req)->ctrl->fault_inject;
        }
 
        if (fault_inject && should_fail(&fault_inject->attr, 1)) {
index 8f907576efb6e5fda0bcd03dad994a0b56f57772..ea45d7d393ad176051ddb70af1eb94794104c1ff 100644 (file)
@@ -256,6 +256,8 @@ struct nvme_ctrl {
 
        struct page *discard_page;
        unsigned long discard_page_busy;
+
+       struct nvme_fault_inject fault_inject;
 };
 
 enum nvme_iopolicy {