Skip to content

Commit

Permalink
Merge tag 'nvme-6.8-2024-02-01' of git://git.infradead.org/nvme into …
Browse files Browse the repository at this point in the history
…block-6.8

Pull NVMe fixes from Keith:

"nvme fixes for Linux 6.8

 - Remove duplicated enums (Guixen)
 - Use appropriate controller state accessors (Keith)
 - Retryable authentication (Hannes)
 - Add missing module descriptions (Chaitanya)
 - Fibre-channel fixes for blktests (Daniel)
 - Various type correctness updates (Caleb)
 - Improve fabrics connection debugging prints (Nitin)
 - Passthrough command verbose error logging (Adam)"

* tag 'nvme-6.8-2024-02-01' of git://git.infradead.org/nvme: (31 commits)
  nvme: allow passthru cmd error logging
  nvme-fc: show hostnqn when connecting to fc target
  nvme-rdma: show hostnqn when connecting to rdma target
  nvme-tcp: show hostnqn when connecting to tcp target
  nvmet-fc: use RCU list iterator for assoc_list
  nvmet-fc: take ref count on tgtport before delete assoc
  nvmet-fc: avoid deadlock on delete association path
  nvmet-fc: abort command when there is no binding
  nvmet-fc: do not tack refs on tgtports from assoc
  nvmet-fc: remove null hostport pointer check
  nvmet-fc: hold reference on hostport match
  nvmet-fc: free queue and assoc directly
  nvmet-fc: defer cleanup using RCU properly
  nvmet-fc: release reference on target port
  nvmet-fcloop: swap the list_add_tail arguments
  nvme-fc: do not wait in vain when unloading module
  nvme-fc: log human-readable opcode on timeout
  nvme: split out fabrics version of nvme_opcode_str()
  nvme: take const cmd pointer in read-only helpers
  nvme: remove redundant status mask
  ...
  • Loading branch information
Jens Axboe committed Feb 1, 2024
2 parents 5af2c3f + 9f079dd commit 3735816
Show file tree
Hide file tree
Showing 23 changed files with 380 additions and 236 deletions.
1 change: 1 addition & 0 deletions drivers/nvme/common/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,4 +471,5 @@ int nvme_auth_generate_key(u8 *secret, struct nvme_dhchap_key **ret_key)
}
EXPORT_SYMBOL_GPL(nvme_auth_generate_key);

MODULE_DESCRIPTION("NVMe Authentication framework");
MODULE_LICENSE("GPL v2");
1 change: 1 addition & 0 deletions drivers/nvme/common/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,6 @@ static void __exit nvme_keyring_exit(void)

MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Hannes Reinecke <hare@suse.de>");
MODULE_DESCRIPTION("NVMe Keyring implementation");
module_init(nvme_keyring_init);
module_exit(nvme_keyring_exit);
13 changes: 7 additions & 6 deletions drivers/nvme/host/apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ static int apple_nvme_init_request(struct blk_mq_tag_set *set,

static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown)
{
enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);
u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);
bool dead = false, freeze = false;
unsigned long flags;
Expand All @@ -808,8 +809,8 @@ static void apple_nvme_disable(struct apple_nvme *anv, bool shutdown)
if (csts & NVME_CSTS_CFS)
dead = true;

if (anv->ctrl.state == NVME_CTRL_LIVE ||
anv->ctrl.state == NVME_CTRL_RESETTING) {
if (state == NVME_CTRL_LIVE ||
state == NVME_CTRL_RESETTING) {
freeze = true;
nvme_start_freeze(&anv->ctrl);
}
Expand Down Expand Up @@ -881,7 +882,7 @@ static enum blk_eh_timer_return apple_nvme_timeout(struct request *req)
unsigned long flags;
u32 csts = readl(anv->mmio_nvme + NVME_REG_CSTS);

if (anv->ctrl.state != NVME_CTRL_LIVE) {
if (nvme_ctrl_state(&anv->ctrl) != NVME_CTRL_LIVE) {
/*
* From rdma.c:
* If we are resetting, connecting or deleting we should
Expand Down Expand Up @@ -985,10 +986,10 @@ static void apple_nvme_reset_work(struct work_struct *work)
u32 boot_status, aqa;
struct apple_nvme *anv =
container_of(work, struct apple_nvme, ctrl.reset_work);
enum nvme_ctrl_state state = nvme_ctrl_state(&anv->ctrl);

if (anv->ctrl.state != NVME_CTRL_RESETTING) {
dev_warn(anv->dev, "ctrl state %d is not RESETTING\n",
anv->ctrl.state);
if (state != NVME_CTRL_RESETTING) {
dev_warn(anv->dev, "ctrl state %d is not RESETTING\n", state);
ret = -ENODEV;
goto out;
}
Expand Down
19 changes: 9 additions & 10 deletions drivers/nvme/host/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,6 @@ struct nvme_dhchap_queue_context {

static struct workqueue_struct *nvme_auth_wq;

#define nvme_auth_flags_from_qid(qid) \
(qid == 0) ? 0 : BLK_MQ_REQ_NOWAIT | BLK_MQ_REQ_RESERVED
#define nvme_auth_queue_from_qid(ctrl, qid) \
(qid == 0) ? (ctrl)->fabrics_q : (ctrl)->connect_q

static inline int ctrl_max_dhchaps(struct nvme_ctrl *ctrl)
{
return ctrl->opts->nr_io_queues + ctrl->opts->nr_write_queues +
Expand All @@ -63,10 +58,15 @@ static int nvme_auth_submit(struct nvme_ctrl *ctrl, int qid,
void *data, size_t data_len, bool auth_send)
{
struct nvme_command cmd = {};
blk_mq_req_flags_t flags = nvme_auth_flags_from_qid(qid);
struct request_queue *q = nvme_auth_queue_from_qid(ctrl, qid);
nvme_submit_flags_t flags = NVME_SUBMIT_RETRY;
struct request_queue *q = ctrl->fabrics_q;
int ret;

if (qid != 0) {
flags |= NVME_SUBMIT_NOWAIT | NVME_SUBMIT_RESERVED;
q = ctrl->connect_q;
}

cmd.auth_common.opcode = nvme_fabrics_command;
cmd.auth_common.secp = NVME_AUTH_DHCHAP_PROTOCOL_IDENTIFIER;
cmd.auth_common.spsp0 = 0x01;
Expand All @@ -80,8 +80,7 @@ static int nvme_auth_submit(struct nvme_ctrl *ctrl, int qid,
}

ret = __nvme_submit_sync_cmd(q, &cmd, NULL, data, data_len,
qid == 0 ? NVME_QID_ANY : qid,
0, flags);
qid == 0 ? NVME_QID_ANY : qid, flags);
if (ret > 0)
dev_warn(ctrl->device,
"qid %d auth_send failed with status %d\n", qid, ret);
Expand Down Expand Up @@ -897,7 +896,7 @@ static void nvme_ctrl_auth_work(struct work_struct *work)
* If the ctrl is no connected, bail as reconnect will handle
* authentication.
*/
if (ctrl->state != NVME_CTRL_LIVE)
if (nvme_ctrl_state(ctrl) != NVME_CTRL_LIVE)
return;

/* Authenticate admin queue first */
Expand Down
10 changes: 5 additions & 5 deletions drivers/nvme/host/constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,31 +171,31 @@ static const char * const nvme_statuses[] = {
[NVME_SC_HOST_ABORTED_CMD] = "Host Aborted Command",
};

const unsigned char *nvme_get_error_status_str(u16 status)
const char *nvme_get_error_status_str(u16 status)
{
status &= 0x7ff;
if (status < ARRAY_SIZE(nvme_statuses) && nvme_statuses[status])
return nvme_statuses[status & 0x7ff];
return nvme_statuses[status];
return "Unknown";
}

const unsigned char *nvme_get_opcode_str(u8 opcode)
const char *nvme_get_opcode_str(u8 opcode)
{
if (opcode < ARRAY_SIZE(nvme_ops) && nvme_ops[opcode])
return nvme_ops[opcode];
return "Unknown";
}
EXPORT_SYMBOL_GPL(nvme_get_opcode_str);

const unsigned char *nvme_get_admin_opcode_str(u8 opcode)
const char *nvme_get_admin_opcode_str(u8 opcode)
{
if (opcode < ARRAY_SIZE(nvme_admin_ops) && nvme_admin_ops[opcode])
return nvme_admin_ops[opcode];
return "Unknown";
}
EXPORT_SYMBOL_GPL(nvme_get_admin_opcode_str);

const unsigned char *nvme_get_fabrics_opcode_str(u8 opcode) {
const char *nvme_get_fabrics_opcode_str(u8 opcode) {
if (opcode < ARRAY_SIZE(nvme_fabrics_ops) && nvme_fabrics_ops[opcode])
return nvme_fabrics_ops[opcode];
return "Unknown";
Expand Down
85 changes: 70 additions & 15 deletions drivers/nvme/host/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,30 @@ static void nvme_log_error(struct request *req)
nr->status & NVME_SC_DNR ? "DNR " : "");
}

static void nvme_log_err_passthru(struct request *req)
{
struct nvme_ns *ns = req->q->queuedata;
struct nvme_request *nr = nvme_req(req);

pr_err_ratelimited("%s: %s(0x%x), %s (sct 0x%x / sc 0x%x) %s%s"
"cdw10=0x%x cdw11=0x%x cdw12=0x%x cdw13=0x%x cdw14=0x%x cdw15=0x%x\n",
ns ? ns->disk->disk_name : dev_name(nr->ctrl->device),
ns ? nvme_get_opcode_str(nr->cmd->common.opcode) :
nvme_get_admin_opcode_str(nr->cmd->common.opcode),
nr->cmd->common.opcode,
nvme_get_error_status_str(nr->status),
nr->status >> 8 & 7, /* Status Code Type */
nr->status & 0xff, /* Status Code */
nr->status & NVME_SC_MORE ? "MORE " : "",
nr->status & NVME_SC_DNR ? "DNR " : "",
nr->cmd->common.cdw10,
nr->cmd->common.cdw11,
nr->cmd->common.cdw12,
nr->cmd->common.cdw13,
nr->cmd->common.cdw14,
nr->cmd->common.cdw14);
}

enum nvme_disposition {
COMPLETE,
RETRY,
Expand Down Expand Up @@ -385,8 +409,12 @@ static inline void nvme_end_req(struct request *req)
{
blk_status_t status = nvme_error_status(nvme_req(req)->status);

if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET)))
nvme_log_error(req);
if (unlikely(nvme_req(req)->status && !(req->rq_flags & RQF_QUIET))) {
if (blk_rq_is_passthrough(req))
nvme_log_err_passthru(req);
else
nvme_log_error(req);
}
nvme_end_req_zoned(req);
nvme_trace_bio_complete(req);
if (req->cmd_flags & REQ_NVME_MPATH)
Expand Down Expand Up @@ -679,10 +707,21 @@ static inline void nvme_clear_nvme_request(struct request *req)
/* initialize a passthrough request */
void nvme_init_request(struct request *req, struct nvme_command *cmd)
{
if (req->q->queuedata)
struct nvme_request *nr = nvme_req(req);
bool logging_enabled;

if (req->q->queuedata) {
struct nvme_ns *ns = req->q->disk->private_data;

logging_enabled = ns->passthru_err_log_enabled;
req->timeout = NVME_IO_TIMEOUT;
else /* no queuedata implies admin queue */
} else { /* no queuedata implies admin queue */
logging_enabled = nr->ctrl->passthru_err_log_enabled;
req->timeout = NVME_ADMIN_TIMEOUT;
}

if (!logging_enabled)
req->rq_flags |= RQF_QUIET;

/* passthru commands should let the driver set the SGL flags */
cmd->common.flags &= ~NVME_CMD_SGL_ALL;
Expand All @@ -691,8 +730,7 @@ void nvme_init_request(struct request *req, struct nvme_command *cmd)
if (req->mq_hctx->type == HCTX_TYPE_POLL)
req->cmd_flags |= REQ_POLLED;
nvme_clear_nvme_request(req);
req->rq_flags |= RQF_QUIET;
memcpy(nvme_req(req)->cmd, cmd, sizeof(*cmd));
memcpy(nr->cmd, cmd, sizeof(*cmd));
}
EXPORT_SYMBOL_GPL(nvme_init_request);

Expand Down Expand Up @@ -721,7 +759,7 @@ blk_status_t nvme_fail_nonready_command(struct nvme_ctrl *ctrl,
EXPORT_SYMBOL_GPL(nvme_fail_nonready_command);

bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
bool queue_live)
bool queue_live, enum nvme_ctrl_state state)
{
struct nvme_request *req = nvme_req(rq);

Expand All @@ -742,7 +780,7 @@ bool __nvme_check_ready(struct nvme_ctrl *ctrl, struct request *rq,
* command, which is require to set the queue live in the
* appropinquate states.
*/
switch (nvme_ctrl_state(ctrl)) {
switch (state) {
case NVME_CTRL_CONNECTING:
if (blk_rq_is_passthrough(rq) && nvme_is_fabrics(req->cmd) &&
(req->cmd->fabrics.fctype == nvme_fabrics_type_connect ||
Expand Down Expand Up @@ -1051,28 +1089,35 @@ EXPORT_SYMBOL_NS_GPL(nvme_execute_rq, NVME_TARGET_PASSTHRU);
*/
int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
union nvme_result *result, void *buffer, unsigned bufflen,
int qid, int at_head, blk_mq_req_flags_t flags)
int qid, nvme_submit_flags_t flags)
{
struct request *req;
int ret;
blk_mq_req_flags_t blk_flags = 0;

if (flags & NVME_SUBMIT_NOWAIT)
blk_flags |= BLK_MQ_REQ_NOWAIT;
if (flags & NVME_SUBMIT_RESERVED)
blk_flags |= BLK_MQ_REQ_RESERVED;
if (qid == NVME_QID_ANY)
req = blk_mq_alloc_request(q, nvme_req_op(cmd), flags);
req = blk_mq_alloc_request(q, nvme_req_op(cmd), blk_flags);
else
req = blk_mq_alloc_request_hctx(q, nvme_req_op(cmd), flags,
req = blk_mq_alloc_request_hctx(q, nvme_req_op(cmd), blk_flags,
qid - 1);

if (IS_ERR(req))
return PTR_ERR(req);
nvme_init_request(req, cmd);
if (flags & NVME_SUBMIT_RETRY)
req->cmd_flags &= ~REQ_FAILFAST_DRIVER;

if (buffer && bufflen) {
ret = blk_rq_map_kern(q, req, buffer, bufflen, GFP_KERNEL);
if (ret)
goto out;
}

ret = nvme_execute_rq(req, at_head);
ret = nvme_execute_rq(req, flags & NVME_SUBMIT_AT_HEAD);
if (result && ret >= 0)
*result = nvme_req(req)->result;
out:
Expand All @@ -1085,7 +1130,7 @@ int nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd,
void *buffer, unsigned bufflen)
{
return __nvme_submit_sync_cmd(q, cmd, NULL, buffer, bufflen,
NVME_QID_ANY, 0, 0);
NVME_QID_ANY, 0);
}
EXPORT_SYMBOL_GPL(nvme_submit_sync_cmd);

Expand Down Expand Up @@ -1560,7 +1605,7 @@ static int nvme_features(struct nvme_ctrl *dev, u8 op, unsigned int fid,
c.features.dword11 = cpu_to_le32(dword11);

ret = __nvme_submit_sync_cmd(dev->admin_q, &c, &res,
buffer, buflen, NVME_QID_ANY, 0, 0);
buffer, buflen, NVME_QID_ANY, 0);
if (ret >= 0 && result)
*result = le32_to_cpu(res.u32);
return ret;
Expand Down Expand Up @@ -2172,7 +2217,7 @@ static int nvme_sec_submit(void *data, u16 spsp, u8 secp, void *buffer, size_t l
cmd.common.cdw11 = cpu_to_le32(len);

return __nvme_submit_sync_cmd(ctrl->admin_q, &cmd, NULL, buffer, len,
NVME_QID_ANY, 1, 0);
NVME_QID_ANY, NVME_SUBMIT_AT_HEAD);
}

static void nvme_configure_opal(struct nvme_ctrl *ctrl, bool was_suspended)
Expand Down Expand Up @@ -3651,6 +3696,7 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)

ns->disk = disk;
ns->queue = disk->queue;
ns->passthru_err_log_enabled = false;

if (ctrl->opts && ctrl->opts->data_digest)
blk_queue_flag_set(QUEUE_FLAG_STABLE_WRITES, ns->queue);
Expand Down Expand Up @@ -3714,6 +3760,13 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, struct nvme_ns_info *info)
nvme_mpath_add_disk(ns, info->anagrpid);
nvme_fault_inject_init(&ns->fault_inject, ns->disk->disk_name);

/*
* Set ns->disk->device->driver_data to ns so we can access
* ns->logging_enabled in nvme_passthru_err_log_enabled_store() and
* nvme_passthru_err_log_enabled_show().
*/
dev_set_drvdata(disk_to_dev(ns->disk), ns);

return;

out_cleanup_ns_from_list:
Expand Down Expand Up @@ -4514,6 +4567,7 @@ int nvme_init_ctrl(struct nvme_ctrl *ctrl, struct device *dev,
int ret;

WRITE_ONCE(ctrl->state, NVME_CTRL_NEW);
ctrl->passthru_err_log_enabled = false;
clear_bit(NVME_CTRL_FAILFAST_EXPIRED, &ctrl->flags);
spin_lock_init(&ctrl->lock);
mutex_init(&ctrl->scan_lock);
Expand Down Expand Up @@ -4851,5 +4905,6 @@ static void __exit nvme_core_exit(void)

MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
MODULE_DESCRIPTION("NVMe host core framework");
module_init(nvme_core_init);
module_exit(nvme_core_exit);
Loading

0 comments on commit 3735816

Please sign in to comment.