nvme 4.17 patch series
Subsystems (3)
cover nvme 4.17 patch series
This series merges cleanly with linux-block/for-linus.
Arnd Bergmann (1):
nvme: target: fix buffer overflow
Daniel Verkamp (1):
nvmet: fix space padding in serial number
James Smart (1):
nvme: expand nvmf_check_if_ready checks
Johannes Thumshirn (2):
nvme: unexport nvme_start_keep_alive
nvme: don't send keep-alives to the discovery controller
Keith Busch (4):
nvme-pci: Skip queue deletion if there are no queues
nvme-pci: Remove unused queue parameter
nvme-pci: Separate IO and admin queue IRQ vectors
nvme: Use admin command effects for admin commands
Matias Bj?rling (1):
nvme: enforce 64bit offset for nvme_get_log_ext fn
Max Gurtovoy (1):
nvme: check return value of init_srcu_struct function
Ming Lei (1):
nvme-loop: fix kernel oops in case of unhandled command
Rodrigo R. Galvao (1):
nvmet: Fix nvmet_execute_write_zeroes sector count
drivers/nvme/host/core.c | 33 ++++++++++------ drivers/nvme/host/fabrics.c | 83 ++++++++++++++++++++++++++++++++++++++++- drivers/nvme/host/fabrics.h | 33 +--------------- drivers/nvme/host/fc.c | 12 ++---- drivers/nvme/host/nvme.h | 4 +- drivers/nvme/host/pci.c | 35 ++++++++++------- drivers/nvme/host/rdma.c | 14 +------ drivers/nvme/target/admin-cmd.c | 1 + drivers/nvme/target/discovery.c | 2 +- drivers/nvme/target/io-cmd.c | 4 +- drivers/nvme/target/loop.c | 20 ++-------- 11 files changed, 141 insertions(+), 100 deletions(-)
Signature · 1 line
2.14.3
PATCH 1/13 nvme: enforce 64bit offset for nvme_get_log_ext fn
From: Matias Bj?rling <[email protected]>
Compiling on 32 bits system produces a warning for the shift width when shifting 32 bit integer with 64bit integer.
Make sure that offset always is 64bit, and use macros for retrieving lower and upper bits of the offset.
--- drivers/nvme/host/core.c | 6 +++--- drivers/nvme/host/nvme.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/nvme/host/core.c +3 -3
@@ -2220,7 +2220,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)int nvme_get_log_ext (struct nvme_ctrl *ctrl,struct nvme_ns *ns,u8 log_page,void *log, -size_t size,size_t offset) +size_t size,u64 offset) {struct nvme_command c = { };unsigned long dwlen = size /4 -1 ;
@@ -2235,8 +2235,8 @@ int nvme_get_log_ext(struct nvme_ctrl *ctrl, struct nvme_ns *ns, c.get_log_page.lid = log_page; c.get_log_page.numdl =cpu_to_le16 (dwlen & ((1 <<16 ) -1 )); c.get_log_page.numdu =cpu_to_le16 (dwlen >>16 ); - c.get_log_page.lpol =cpu_to_le32 (offset & ((1ULL <<32 ) -1 )); - c.get_log_page.lpou =cpu_to_le32 (offset >>32ULL ); + c.get_log_page.lpol =cpu_to_le32 (lower_32_bits (offset)); + c.get_log_page.lpou =cpu_to_le32 (upper_32_bits (offset));return nvme_submit_sync_cmd (ctrl->admin_q, &c, log, size); }
drivers/nvme/host/nvme.h +1 -1
@@ -430,7 +430,7 @@ int nvme_delete_ctrl(struct nvme_ctrl *ctrl);int nvme_delete_ctrl_sync (struct nvme_ctrl *ctrl);int nvme_get_log_ext (struct nvme_ctrl *ctrl,struct nvme_ns *ns, -u8 log_page,void *log,size_t size,size_t offset); +u8 log_page,void *log,size_t size,u64 offset);extern const struct attribute_group nvme_ns_id_attr_group;extern const struct block_device_operations nvme_ns_head_ops;
Signature · 1 line
2.14.3
PATCH 2/13 nvme-loop: fix kernel oops in case of unhandled command
In reply to Keith BuschFrom: Ming Lei <[email protected]>
When nvmet_req_init() fails, __nvmet_req_complete() is called to handle the target request via .queue_response(), so nvme_loop_queue_response() shouldn't be called again for handling the failure.
This patch fixes this case by the following way:
- move blk_mq_start_request() before nvmet_req_init(), so nvme_loop_queue_response() may work well to complete this host request
- don't call nvme_cleanup_cmd() which is done in nvme_loop_complete_rq()
- don't call nvme_loop_queue_response() which is done via .queue_response()
--- drivers/nvme/target/loop.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
drivers/nvme/target/loop.c +2 -7
@@ -174,15 +174,12 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,if (ret)return ret; +blk_mq_start_request (req); iod->cmd.common.flags |=NVME_CMD_SGL_METABUF ; iod->req.port = nvmet_loop_port;if (!nvmet_req_init (&iod->req, &queue->nvme_cq, - &queue->nvme_sq, &nvme_loop_ops)) { -nvme_cleanup_cmd (req); -blk_mq_start_request (req); -nvme_loop_queue_response (&iod->req); + &queue->nvme_sq, &nvme_loop_ops))return BLK_STS_OK ; - }if (blk_rq_payload_bytes (req)) { iod->sg_table.sgl = iod->first_sgl;
@@ -196,8 +193,6 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx, iod->req.transfer_len =blk_rq_payload_bytes (req); } -blk_mq_start_request (req); -schedule_work (&iod->work);return BLK_STS_OK ; }
Signature · 1 line
2.14.3
PATCH 3/13 nvme: unexport nvme_start_keep_alive
In reply to Keith BuschFrom: Johannes Thumshirn <[email protected]>
nvme_start_keep_alive() isn't used outside core.c so unexport it and make it static.
--- drivers/nvme/host/core.c | 3 +-- drivers/nvme/host/nvme.h | 1 - 2 files changed, 1 insertion(+), 3 deletions(-)
drivers/nvme/host/core.c +1 -2
@@ -826,7 +826,7 @@ static void nvme_keep_alive_work(struct work_struct *work) } } -void nvme_start_keep_alive (struct nvme_ctrl *ctrl) +static void nvme_start_keep_alive (struct nvme_ctrl *ctrl) {if (unlikely (ctrl->kato ==0 ))return ;
@@ -836,7 +836,6 @@ void nvme_start_keep_alive(struct nvme_ctrl *ctrl) ctrl->ka_cmd.common.opcode = nvme_admin_keep_alive;schedule_delayed_work (&ctrl->ka_work, ctrl->kato *HZ ); } -EXPORT_SYMBOL_GPL (nvme_start_keep_alive);void nvme_stop_keep_alive (struct nvme_ctrl *ctrl) {
drivers/nvme/host/nvme.h +0 -1
@@ -422,7 +422,6 @@ int __nvme_submit_sync_cmd(struct request_queue *q, struct nvme_command *cmd, unsigned timeout, int qid, int at_head, blk_mq_req_flags_t flags);int nvme_set_queue_count (struct nvme_ctrl *ctrl,int *count); -void nvme_start_keep_alive (struct nvme_ctrl *ctrl);void nvme_stop_keep_alive (struct nvme_ctrl *ctrl);int nvme_reset_ctrl (struct nvme_ctrl *ctrl);int nvme_reset_ctrl_sync (struct nvme_ctrl *ctrl);
Signature · 1 line
2.14.3
PATCH 4/13 nvme: don't send keep-alives to the discovery controller
In reply to Keith BuschFrom: Johannes Thumshirn <[email protected]>
NVMe over Fabrics 1.0 Section 5.2 "Discovery Controller Properties and Command Support" Figure 31 "Discovery Controller ? Admin Commands" explicitly listst all commands but "Get Log Page" and "Identify" as reserved, but NetApp report the Linux host is sending Keep Alive commands to the discovery controller, which is a violation of the Spec.
We're already checking for discovery controllers when configuring the keep alive timeout but when creating a discovery controller we're not hard wiring the keep alive timeout to 0 and thus remain on NVME_DEFAULT_KATO for the discovery controller.
This can be easily remproduced when issuing a direct connect to the discovery susbsystem using:
'nvme connect [...] --nqn=nqn.2014-08.org.nvmexpress.discovery'
--- drivers/nvme/host/fabrics.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/nvme/host/fabrics.c +3 -1
@@ -608,8 +608,10 @@ static int nvmf_parse_options(struct nvmf_ctrl_options *opts, opts->discovery_nqn = !(strcmp (opts->subsysnqn,NVME_DISC_SUBSYS_NAME )); -if (opts->discovery_nqn) +if (opts->discovery_nqn) { + opts->kato =0 ; opts->nr_io_queues =0 ; + }break ;case NVMF_OPT_TRADDR : p =match_strdup (args);
Signature · 1 line
2.14.3
PATCH 5/13 nvme: target: fix buffer overflow
In reply to Keith BuschFrom: Arnd Bergmann <[email protected]>
nvmet_execute_get_disc_log_page() passes a fixed-length string into nvmet_format_discovery_entry(), which then does a longer memcpy() on it, as pointed out by gcc-8:
In function 'nvmet_format_discovery_entry',
inlined from 'nvmet_execute_get_disc_log_page' at drivers/nvme/target/discovery.c:126:4:drivers/nvme/target/discovery.c:62:2: error: 'memcpy' forming offset [38, 223] is out of the bounds [0, 37] [-Werror=array-bounds]
memcpy(e->subnqn, subsys_nqn, NVMF_NQN_SIZE);
Using strncpy() will make this well-defined, filling the rest of the buffer with zeroes, under the assumption that the input is either a NUL-terminated string, or a byte sequence containing no zeroes. If the input is a string that is longer than NVMF_NQN_SIZE, we continue to have no NUL-termination in the output.
--- drivers/nvme/target/discovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/target/discovery.c +1 -1
@@ -59,7 +59,7 @@ static void nvmet_format_discovery_entry(struct nvmf_disc_rsp_page_hdr *hdr,memcpy (e->trsvcid, port->disc_addr.trsvcid,NVMF_TRSVCID_SIZE );memcpy (e->traddr, traddr,NVMF_TRADDR_SIZE );memcpy (e->tsas.common, port->disc_addr.tsas.common,NVMF_TSAS_SIZE ); -memcpy (e->subnqn, subsys_nqn,NVMF_NQN_SIZE ); +strncpy (e->subnqn, subsys_nqn,NVMF_NQN_SIZE ); }/*
Signature · 1 line
2.14.3
PATCH 6/13 nvme-pci: Skip queue deletion if there are no queues
In reply to Keith BuschUser reported controller always retains CSTS.RDY to 1, which fails controller disabling when resetting the controller. This is also before the admin queue is allocated, and trying to disable an unallocated queue results in a NULL dereference.
--- drivers/nvme/host/pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/pci.c +1 -1
@@ -2201,7 +2201,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)nvme_stop_queues (&dev->ctrl); -if (!dead) { +if (!dead && dev->ctrl.queue_count >0 ) {/* * If the controller is still alive tell it to stop using the * host memory buffer. In theory the shutdown / reset should
Signature · 1 line
2.14.3
PATCH 7/13 nvme-pci: Remove unused queue parameter
In reply to Keith BuschAll the queue memory is allocated up front. We don't take the node into consideration when creating queues anymore, so removing the unused parameter.
--- drivers/nvme/host/pci.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/nvme/host/pci.c +3 -7
@@ -1380,8 +1380,7 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,return 0 ; } -static int nvme_alloc_queue (struct nvme_dev *dev,int qid, -int depth,int node) +static int nvme_alloc_queue (struct nvme_dev *dev,int qid,int depth) {struct nvme_queue *nvmeq = &dev->queues[qid];
@@ -1596,8 +1595,7 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev)if (result <0 )return result; - result =nvme_alloc_queue (dev,0 ,NVME_AQ_DEPTH , -dev_to_node (dev->dev)); + result =nvme_alloc_queue (dev,0 ,NVME_AQ_DEPTH );if (result)return result;
@@ -1630,9 +1628,7 @@ static int nvme_create_io_queues(struct nvme_dev *dev)int ret =0 ;for (i = dev->ctrl.queue_count; i <= dev->max_qid; i++) { -/* vector == qid - 1, match nvme_create_queue */ -if (nvme_alloc_queue (dev, i, dev->q_depth, -pci_irq_get_node (to_pci_dev (dev->dev), i -1 ))) { +if (nvme_alloc_queue (dev, i, dev->q_depth)) { ret = -ENOMEM ;break ; }
Signature · 1 line
2.14.3
PATCH 8/13 nvme-pci: Separate IO and admin queue IRQ vectors
In reply to Keith BuschThe admin and first IO queues shared the first irq vector, which has an affinity mask including cpu0. If a system allows cpu0 to be offlined, the admin queue may not be usable if no other CPUs in the affinity mask are online. This is a problem since unlike IO queues, there is only one admin queue that always needs to be usable.
To fix, this patch allocates one pre_vector for the admin queue that is assigned all CPUs, so will always be accessible. The IO queues are assigned the remaining managed vectors.
In case a controller has only one interrupt vector available, the admin and IO queues will share the pre_vector with all CPUs assigned.
--- drivers/nvme/host/pci.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/nvme/host/pci.c +17 -6
@@ -84,6 +84,7 @@ struct nvme_dev {struct dma_pool *prp_small_pool;unsigned online_queues;unsigned max_qid; +unsigned int num_vecs;int q_depth;u32 db_stride;void __iomem *bar;
@@ -414,7 +415,8 @@ static int nvme_pci_map_queues(struct blk_mq_tag_set *set) {struct nvme_dev *dev = set->driver_data; -return blk_mq_pci_map_queues (set,to_pci_dev (dev->dev),0 ); +return blk_mq_pci_map_queues (set,to_pci_dev (dev->dev), + dev->num_vecs >1 ?1 /* admin queue */ :0 ); }/**
@@ -1456,7 +1458,11 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid) nvmeq->sq_cmds_io = dev->cmb + offset; } - nvmeq->cq_vector = qid -1 ; +/* +* A queue's vector matches the queue identifier unless the controller +* has only one vector available. +*/ + nvmeq->cq_vector = dev->num_vecs ==1 ?0 : qid; result =adapter_alloc_cq (dev, qid, nvmeq);if (result <0 ) goto release_vector;
@@ -1910,6 +1916,10 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)int result, nr_io_queues;unsigned long size; +struct irq_affinity affd = { + .pre_vectors =1 + }; + nr_io_queues =num_possible_cpus (); result =nvme_set_queue_count (&dev->ctrl, &nr_io_queues);if (result <0 )
@@ -1945,11 +1955,12 @@ static int nvme_setup_io_queues(struct nvme_dev *dev)* setting up the full range we need. */ pci_free_irq_vectors (pdev); - nr_io_queues =pci_alloc_irq_vectors (pdev,1 , nr_io_queues, -PCI_IRQ_ALL_TYPES |PCI_IRQ_AFFINITY ); -if (nr_io_queues <=0 ) + result =pci_alloc_irq_vectors_affinity (pdev,1 , nr_io_queues +1 , +PCI_IRQ_ALL_TYPES |PCI_IRQ_AFFINITY , &affd); +if (result <=0 )return -EIO ; - dev->max_qid = nr_io_queues; + dev->num_vecs = result; + dev->max_qid =max (result -1 ,1 );/* * Should investigate if there's a performance win from allocating
Signature · 1 line
2.14.3
PATCH 9/13 nvmet: Fix nvmet_execute_write_zeroes sector count
In reply to Keith BuschFrom: "Rodrigo R. Galvao" <[email protected]>
We have to increment the number of logical blocks to a 1's based value in the native format prior to converting to 512b units.
--- drivers/nvme/target/io-cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/target/io-cmd.c +2 -2
@@ -173,8 +173,8 @@ static void nvmet_execute_write_zeroes(struct nvmet_req *req) sector =le64_to_cpu (write_zeroes->slba) << (req->ns->blksize_shift -9 ); - nr_sector = (((sector_t )le16_to_cpu (write_zeroes->length)) << - (req->ns->blksize_shift -9 )) +1 ; + nr_sector = (((sector_t )le16_to_cpu (write_zeroes->length) +1 ) << + (req->ns->blksize_shift -9 ));if (__blkdev_issue_zeroout (req->ns->bdev, sector, nr_sector,GFP_KERNEL , &bio,0 ))
Signature · 1 line
2.14.3
PATCH 10/13 nvme: check return value of init_srcu_struct function
In reply to Keith BuschFrom: Max Gurtovoy <[email protected]>
Also add error flow in case srcu initialization function fails.
--- drivers/nvme/host/core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/nvme/host/core.c +4 -1
@@ -2832,7 +2832,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl, goto out_free_head; head->instance = ret;INIT_LIST_HEAD (&head->list); -init_srcu_struct (&head->srcu); + ret =init_srcu_struct (&head->srcu); +if (ret) + goto out_ida_remove; head->subsys = ctrl->subsys; head->ns_id = nsid;kref_init (&head->ref);
@@ -2854,6 +2856,7 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,return head; out_cleanup_srcu:cleanup_srcu_struct (&head->srcu); +out_ida_remove:ida_simple_remove (&ctrl->subsys->ns_ida, head->instance); out_free_head:kfree (head);
Signature · 1 line
2.14.3
PATCH 11/13 nvmet: fix space padding in serial number
In reply to Keith BuschFrom: Daniel Verkamp <[email protected]>
Commit 42de82a8b544 previously attempted to fix this, and it did correctly pad the MN and FR fields with spaces, but the SN field still contains 0 bytes. The current code fills out the first 16 bytes with hex2bin, leaving the last 4 bytes zeroed. Rather than adding a lot of error-prone math to avoid overwriting SN twice, just set the whole thing to spaces up front (it's only 20 bytes).
--- drivers/nvme/target/admin-cmd.c | 1 + 1 file changed, 1 insertion(+)
drivers/nvme/target/admin-cmd.c +1 -0
@@ -178,6 +178,7 @@ static void nvmet_execute_identify_ctrl(struct nvmet_req *req) id->vid =0 ; id->ssvid =0 ; +memset (id->sn,' ' ,sizeof (id->sn));bin2hex (id->sn, &ctrl->subsys->serial,min (sizeof (ctrl->subsys->serial),sizeof (id->sn) /2 ));memcpy_and_pad (id->mn,sizeof (id->mn), model,sizeof (model) -1 ,' ' );
Signature · 1 line
2.14.3
PATCH 12/13 nvme: Use admin command effects for admin commands
In reply to Keith Busch--- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/nvme/host/core.c +1 -1
@@ -1102,7 +1102,7 @@ static u32 nvme_passthru_start(struct nvme_ctrl *ctrl, struct nvme_ns *ns, }if (ctrl->effects) - effects =le32_to_cpu (ctrl->effects->iocs[opcode]); + effects =le32_to_cpu (ctrl->effects->acs[opcode]);else effects =nvme_known_admin_effects (opcode);
Signature · 1 line
2.14.3
PATCH 13/13 nvme: expand nvmf_check_if_ready checks
In reply to Keith BuschFrom: James Smart <[email protected]>
The nvmf_check_if_ready() checks that were added are very simplistic. As such, the routine allows a lot of cases to fail ios during windows of reset or re-connection. In cases where there are not multi-path options present, the error goes back to the callee - the filesystem or application. Not good.
The common routine was rewritten and calling syntax slightly expanded so that per-transport is_ready routines don't need to be present. The transports now call the routine directly. The routine is now a fabrics routine rather than an inline function.
The routine now looks at controller state to decide the action to take. Some states mandate io failure. Others define the condition where a command can be accepted. When the decision is unclear, a generic queue-or-reject check is made to look for failfast or multipath ios and only fails the io if it is so marked. Otherwise, the io will be queued and wait for the controller state to resolve.
Admin commands issued via ioctl share a live admin queue with commands from the transport for controller init. The ioctls could be intermixed with the initialization commands. It's possible for the ioctl cmd to be issued prior to the controller being enabled. To block this, the ioctl admin commands need to be distinguished from admin commands used for controller init. Added a USERCMD nvme_req(req)->rq_flags bit to reflect this division and set it on ioctls requests. As the nvmf_check_if_ready() routine is called prior to nvme_setup_cmd(), ensure that commands allocated by the ioctl path (actually anything in core.c) preps the nvme_req(req) before starting the io. This will preserve the USERCMD flag during execution and/or retry.
--- drivers/nvme/host/core.c | 17 +++++++--- drivers/nvme/host/fabrics.c | 79 +++++++++++++++++++++++++++++++++++++++++++++ drivers/nvme/host/fabrics.h | 33 ++----------------- drivers/nvme/host/fc.c | 12 ++----- drivers/nvme/host/nvme.h | 1 + drivers/nvme/host/rdma.c | 14 ++------ drivers/nvme/target/loop.c | 11 ++----- 7 files changed, 101 insertions(+), 66 deletions(-)
drivers/nvme/host/core.c +12 -5
@@ -376,6 +376,15 @@ static void nvme_put_ns(struct nvme_ns *ns)kref_put (&ns->kref, nvme_free_ns); } +static inline void nvme_clear_nvme_request (struct request *req) +{ +if (!(req->rq_flags &RQF_DONTPREP )) { +nvme_req (req)->retries =0 ; +nvme_req (req)->flags =0 ; + req->rq_flags |=RQF_DONTPREP ; + } +} +struct request *nvme_alloc_request (struct request_queue *q,struct nvme_command *cmd,blk_mq_req_flags_t flags,int qid) {
@@ -392,6 +401,7 @@ struct request *nvme_alloc_request(struct request_queue *q,return req; req->cmd_flags |=REQ_FAILFAST_DRIVER ; +nvme_clear_nvme_request (req);nvme_req (req)->cmd = cmd;return req;
@@ -608,11 +618,7 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req, {blk_status_t ret =BLK_STS_OK ; -if (!(req->rq_flags &RQF_DONTPREP )) { -nvme_req (req)->retries =0 ; -nvme_req (req)->flags =0 ; - req->rq_flags |=RQF_DONTPREP ; - } +nvme_clear_nvme_request (req);switch (req_op (req)) {case REQ_OP_DRV_IN :
@@ -742,6 +748,7 @@ static int nvme_submit_user_cmd(struct request_queue *q,return PTR_ERR (req); req->timeout = timeout ? timeout :ADMIN_TIMEOUT ; +nvme_req (req)->flags |=NVME_REQ_USERCMD ;if (ubuffer && bufflen) { ret = blk_rq_map_user(q, req, NULL, ubuffer, bufflen,
drivers/nvme/host/fabrics.c +79 -0
85 lines not on this page · raw message
drivers/nvme/host/fabrics.h +2 -31
@@ -157,36 +157,7 @@ void nvmf_unregister_transport(struct nvmf_transport_ops *ops);void nvmf_free_options (struct nvmf_ctrl_options *opts);int nvmf_get_address (struct nvme_ctrl *ctrl,char *buf,int size);bool nvmf_should_reconnect (struct nvme_ctrl *ctrl); - -static inline blk_status_t nvmf_check_init_req (struct nvme_ctrl *ctrl, -struct request *rq) -{ -struct nvme_command *cmd =nvme_req (rq)->cmd; - -/* -* We cannot accept any other command until the connect command has -* completed, so only allow connect to pass. -*/ -if (!blk_rq_is_passthrough (rq) || - cmd->common.opcode != nvme_fabrics_command || - cmd->fabrics.fctype != nvme_fabrics_type_connect) { -/* -* Connecting state means transport disruption or initial -* establishment, which can take a long time and even might -* fail permanently, fail fast to give upper layers a chance -* to failover. -* Deleting state means that the ctrl will never accept commands -* again, fail it permanently. -*/ -if (ctrl->state ==NVME_CTRL_CONNECTING || - ctrl->state ==NVME_CTRL_DELETING ) { -nvme_req (rq)->status =NVME_SC_ABORT_REQ ; -return BLK_STS_IOERR ; - } -return BLK_STS_RESOURCE ;/* try again later */ - } - -return BLK_STS_OK ; -} +blk_status_t nvmf_check_if_ready (struct nvme_ctrl *ctrl, +struct request *rq,bool queue_live,bool is_connected);#endif /* _NVME_FABRICS_H */
drivers/nvme/host/fc.c +3 -9
@@ -2277,14 +2277,6 @@ nvme_fc_start_fcp_op(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,return BLK_STS_OK ; } -static inline blk_status_t nvme_fc_is_ready (struct nvme_fc_queue *queue, -struct request *rq) -{ -if (unlikely (!test_bit (NVME_FC_Q_LIVE , &queue->flags))) -return nvmf_check_init_req (&queue->ctrl->ctrl, rq); -return BLK_STS_OK ; -} -static blk_status_t nvme_fc_queue_rq (struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd)
@@ -2300,7 +2292,9 @@ nvme_fc_queue_rq(struct blk_mq_hw_ctx *hctx,u32 data_len;blk_status_t ret; - ret =nvme_fc_is_ready (queue, rq); + ret =nvmf_check_if_ready (&queue->ctrl->ctrl, rq, +test_bit (NVME_FC_Q_LIVE , &queue->flags), + ctrl->rport->remoteport.port_state ==FC_OBJSTATE_ONLINE );if (unlikely (ret))return ret;
drivers/nvme/host/nvme.h +1 -0
@@ -105,6 +105,7 @@ struct nvme_request {enum {NVME_REQ_CANCELLED = (1 <<0 ), +NVME_REQ_USERCMD = (1 <<1 ), };static inline struct nvme_request *nvme_req (struct request *req)
drivers/nvme/host/rdma.c +2 -12
@@ -1601,17 +1601,6 @@ nvme_rdma_timeout(struct request *rq, bool reserved)return BLK_EH_HANDLED ; } -/* -* We cannot accept any other command until the Connect command has completed. -*/ -static inline blk_status_t -nvme_rdma_is_ready (struct nvme_rdma_queue *queue,struct request *rq) -{ -if (unlikely (!test_bit (NVME_RDMA_Q_LIVE , &queue->flags))) -return nvmf_check_init_req (&queue->ctrl->ctrl, rq); -return BLK_STS_OK ; -} -static blk_status_t nvme_rdma_queue_rq (struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd) {
@@ -1627,7 +1616,8 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,WARN_ON_ONCE (rq->tag <0 ); - ret =nvme_rdma_is_ready (queue, rq); + ret =nvmf_check_if_ready (&queue->ctrl->ctrl, rq, +test_bit (NVME_RDMA_Q_LIVE , &queue->flags), true);if (unlikely (ret))return ret;
drivers/nvme/target/loop.c +2 -9
@@ -149,14 +149,6 @@ nvme_loop_timeout(struct request *rq, bool reserved)return BLK_EH_HANDLED ; } -static inline blk_status_t nvme_loop_is_ready (struct nvme_loop_queue *queue, -struct request *rq) -{ -if (unlikely (!test_bit (NVME_LOOP_Q_LIVE , &queue->flags))) -return nvmf_check_init_req (&queue->ctrl->ctrl, rq); -return BLK_STS_OK ; -} -static blk_status_t nvme_loop_queue_rq (struct blk_mq_hw_ctx *hctx,const struct blk_mq_queue_data *bd) {
@@ -166,7 +158,8 @@ static blk_status_t nvme_loop_queue_rq(struct blk_mq_hw_ctx *hctx,struct nvme_loop_iod *iod =blk_mq_rq_to_pdu (req);blk_status_t ret; - ret =nvme_loop_is_ready (queue, req); + ret =nvmf_check_if_ready (&queue->ctrl->ctrl, req, +test_bit (NVME_LOOP_Q_LIVE , &queue->flags), true);if (unlikely (ret))return ret;
Signature · 1 line
2.14.3
cover nvme 4.17 patch series
In reply to Keith BuschQuoted 33 lines · Keith Busch
This series merges cleanly with linux-block/for-linus.
Arnd Bergmann (1):
nvme: target: fix buffer overflowDaniel Verkamp (1):
nvmet: fix space padding in serial numberJames Smart (1):
nvme: expandnvmf_check_if_readychecksJohannes Thumshirn (2):
nvme: unexportnvme_start_keep_alive
nvme: don't send keep-alives to the discovery controllerKeith Busch (4):
nvme-pci: Skip queue deletion if there are no queues
nvme-pci: Remove unused queue parameter
nvme-pci: Separate IO and admin queue IRQ vectors
nvme: Use admin command effects for admin commandsMatias Bj?rling (1):
nvme: enforce 64bit offset fornvme_get_log_extfnMax Gurtovoy (1):
nvme: check return value ofinit_srcu_structfunctionMing Lei (1):
nvme-loop: fix kernel oops in case of unhandled commandRodrigo R. Galvao (1):
nvmet: Fixnvmet_execute_write_zeroessector count
Quoted 12 lines
drivers/nvme/host/core.c | 33 ++++++++++------ drivers/nvme/host/fabrics.c | 83 ++++++++++++++++++++++++++++++++++++++++- drivers/nvme/host/fabrics.h | 33 +--------------- drivers/nvme/host/fc.c | 12 ++---- drivers/nvme/host/nvme.h | 4 +- drivers/nvme/host/pci.c | 35 ++++++++++------- drivers/nvme/host/rdma.c | 14 +------ drivers/nvme/target/admin-cmd.c | 1 + drivers/nvme/target/discovery.c | 2 +- drivers/nvme/target/io-cmd.c | 4 +- drivers/nvme/target/loop.c | 20 ++-------- 11 files changed, 141 insertions(+), 100 deletions(-)
Thanks, applied.
Signature · 1 line
Jens Axboe