1 // SPDX-License-Identifier: GPL-2.0
3 * fault injection support for nvme.
5 * Copyright (c) 2018, Oracle and/or its affiliates
8 #include <linux/moduleparam.h>
9 #include <linux/debugfs.h>
12 static DECLARE_FAULT_ATTR(fail_default_attr
);
13 /* optional fault injection attributes boot time option:
14 * nvme_core.fail_request=<interval>,<probability>,<space>,<times>
16 static char *fail_request
;
17 module_param(fail_request
, charp
, 0000);
19 void nvme_fault_inject_init(struct nvme_fault_inject
*fault_inj
,
22 struct dentry
*dir
, *parent
;
23 struct fault_attr
*attr
= &fault_inj
->attr
;
25 /* set default fault injection attribute */
27 setup_fault_attr(&fail_default_attr
, fail_request
);
29 /* create debugfs directory and attribute */
30 parent
= debugfs_create_dir(dev_name
, NULL
);
32 pr_warn("%s: failed to create debugfs directory\n", dev_name
);
36 *attr
= fail_default_attr
;
37 dir
= fault_create_debugfs_attr("fault_inject", parent
, attr
);
39 pr_warn("%s: failed to create debugfs attr\n", dev_name
);
40 debugfs_remove_recursive(parent
);
43 fault_inj
->parent
= parent
;
45 /* create debugfs for status code and dont_retry */
46 fault_inj
->status
= NVME_SC_INVALID_OPCODE
;
47 fault_inj
->dont_retry
= true;
48 debugfs_create_x16("status", 0600, dir
, &fault_inj
->status
);
49 debugfs_create_bool("dont_retry", 0600, dir
, &fault_inj
->dont_retry
);
52 void nvme_fault_inject_fini(struct nvme_fault_inject
*fault_inject
)
54 /* remove debugfs directories */
55 debugfs_remove_recursive(fault_inject
->parent
);
58 void nvme_should_fail(struct request
*req
)
60 struct gendisk
*disk
= req
->q
->disk
;
61 struct nvme_fault_inject
*fault_inject
= NULL
;
65 struct nvme_ns
*ns
= disk
->private_data
;
68 fault_inject
= &ns
->fault_inject
;
70 WARN_ONCE(1, "No namespace found for request\n");
72 fault_inject
= &nvme_req(req
)->ctrl
->fault_inject
;
75 if (fault_inject
&& should_fail(&fault_inject
->attr
, 1)) {
76 /* inject status code and DNR bit */
77 status
= fault_inject
->status
;
78 if (fault_inject
->dont_retry
)
79 status
|= NVME_STATUS_DNR
;
80 nvme_req(req
)->status
= status
;
83 EXPORT_SYMBOL_GPL(nvme_should_fail
);