Hannes Reinecke ea7077
From: James Smart <jsmart2021@gmail.com>
Hannes Reinecke ea7077
Date: Tue, 31 Mar 2020 09:49:50 -0700
Hannes Reinecke ea7077
Subject: [PATCH] nvme-fc: Ensure private pointers are NULL if no data
Hannes Reinecke ea7077
Git-commit: 17dbd219e6ae3b09a967367071427e44d19f2686
Hannes Reinecke ea7077
Git-repo: git://git.infradead.org/nvme.git
Hannes Reinecke ea7077
Patch-mainline: Queued in subsystem maintainer repository
Hannes Reinecke ea7077
References: bsc#1169045
Hannes Reinecke ea7077
Hannes Reinecke ea7077
Ensure that when allocations are done, and the lldd options indicate
Hannes Reinecke ea7077
no private data is needed, that private pointers will be set to NULL
Hannes Reinecke ea7077
(catches driver error that forgot to set private data size).
Hannes Reinecke ea7077
Hannes Reinecke ea7077
Slightly reorg the allocations so that private data follows allocations
Hannes Reinecke ea7077
for LS request/response buffers. Ensures better alignments for the buffers
Hannes Reinecke ea7077
as well as the private pointer.
Hannes Reinecke ea7077
Hannes Reinecke ea7077
Signed-off-by: James Smart <jsmart2021@gmail.com>
Hannes Reinecke ea7077
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Hannes Reinecke ea7077
Reviewed-by: Hannes Reinecke <hare@suse.de>
Hannes Reinecke ea7077
Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com>
Hannes Reinecke ea7077
Signed-off-by: Christoph Hellwig <hch@lst.de>
Hannes Reinecke ea7077
Acked-by: Hannes Reinecke <hare@suse.com>
Hannes Reinecke ea7077
---
Hannes Reinecke ea7077
 drivers/nvme/host/fc.c   | 81 ++++++++++++++++++++++++++++++------------------
Hannes Reinecke ea7077
 drivers/nvme/target/fc.c |  5 ++-
Hannes Reinecke ea7077
 2 files changed, 54 insertions(+), 32 deletions(-)
Hannes Reinecke ea7077
Hannes Reinecke ea7077
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
Hannes Reinecke ea7077
index 83f9b2ac7c55..bf80b941d739 100644
Hannes Reinecke ea7077
--- a/drivers/nvme/host/fc.c
Hannes Reinecke ea7077
+++ b/drivers/nvme/host/fc.c
Hannes Reinecke ea7077
@@ -395,7 +395,10 @@ nvme_fc_register_localport(struct nvme_fc_port_info *pinfo,
Hannes Reinecke ea7077
 	newrec->ops = template;
Hannes Reinecke ea7077
 	newrec->dev = dev;
Hannes Reinecke ea7077
 	ida_init(&newrec->endp_cnt);
Hannes Reinecke ea7077
-	newrec->localport.private = &newrec[1];
Hannes Reinecke ea7077
+	if (template->local_priv_sz)
Hannes Reinecke ea7077
+		newrec->localport.private = &newrec[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		newrec->localport.private = NULL;
Hannes Reinecke ea7077
 	newrec->localport.node_name = pinfo->node_name;
Hannes Reinecke ea7077
 	newrec->localport.port_name = pinfo->port_name;
Hannes Reinecke ea7077
 	newrec->localport.port_role = pinfo->port_role;
Hannes Reinecke ea7077
@@ -704,7 +707,10 @@ nvme_fc_register_remoteport(struct nvme_fc_local_port *localport,
Hannes Reinecke ea7077
 	newrec->remoteport.localport = &lport->localport;
Hannes Reinecke ea7077
 	newrec->dev = lport->dev;
Hannes Reinecke ea7077
 	newrec->lport = lport;
Hannes Reinecke ea7077
-	newrec->remoteport.private = &newrec[1];
Hannes Reinecke ea7077
+	if (lport->ops->remote_priv_sz)
Hannes Reinecke ea7077
+		newrec->remoteport.private = &newrec[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		newrec->remoteport.private = NULL;
Hannes Reinecke ea7077
 	newrec->remoteport.port_role = pinfo->port_role;
Hannes Reinecke ea7077
 	newrec->remoteport.node_name = pinfo->node_name;
Hannes Reinecke ea7077
 	newrec->remoteport.port_name = pinfo->port_name;
Hannes Reinecke ea7077
@@ -1152,18 +1158,23 @@ nvme_fc_connect_admin_queue(struct nvme_fc_ctrl *ctrl,
Hannes Reinecke ea7077
 	int ret, fcret = 0;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	lsop = kzalloc((sizeof(*lsop) +
Hannes Reinecke ea7077
-			 ctrl->lport->ops->lsrqst_priv_sz +
Hannes Reinecke ea7077
-			 sizeof(*assoc_rqst) + sizeof(*assoc_acc)), GFP_KERNEL);
Hannes Reinecke ea7077
+			 sizeof(*assoc_rqst) + sizeof(*assoc_acc) +
Hannes Reinecke ea7077
+			 ctrl->lport->ops->lsrqst_priv_sz), GFP_KERNEL);
Hannes Reinecke ea7077
 	if (!lsop) {
Hannes Reinecke ea7077
+		dev_info(ctrl->ctrl.device,
Hannes Reinecke ea7077
+			"NVME-FC{%d}: send Create Association failed: ENOMEM\n",
Hannes Reinecke ea7077
+			ctrl->cnum);
Hannes Reinecke ea7077
 		ret = -ENOMEM;
Hannes Reinecke ea7077
 		goto out_no_memory;
Hannes Reinecke ea7077
 	}
Hannes Reinecke ea7077
-	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
-	lsreq->private = (void *)&lsop[1];
Hannes Reinecke ea7077
-	assoc_rqst = (struct fcnvme_ls_cr_assoc_rqst *)
Hannes Reinecke ea7077
-			(lsreq->private + ctrl->lport->ops->lsrqst_priv_sz);
Hannes Reinecke ea7077
+	assoc_rqst = (struct fcnvme_ls_cr_assoc_rqst *)&lsop[1];
Hannes Reinecke ea7077
 	assoc_acc = (struct fcnvme_ls_cr_assoc_acc *)&assoc_rqst[1];
Hannes Reinecke ea7077
+	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
+	if (ctrl->lport->ops->lsrqst_priv_sz)
Hannes Reinecke ea7077
+		lsreq->private = &assoc_acc[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		lsreq->private = NULL;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	assoc_rqst->w0.ls_cmd = FCNVME_LS_CREATE_ASSOCIATION;
Hannes Reinecke ea7077
 	assoc_rqst->desc_list_len =
Hannes Reinecke ea7077
@@ -1261,18 +1272,23 @@ nvme_fc_connect_queue(struct nvme_fc_ctrl *ctrl, struct nvme_fc_queue *queue,
Hannes Reinecke ea7077
 	int ret, fcret = 0;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	lsop = kzalloc((sizeof(*lsop) +
Hannes Reinecke ea7077
-			 ctrl->lport->ops->lsrqst_priv_sz +
Hannes Reinecke ea7077
-			 sizeof(*conn_rqst) + sizeof(*conn_acc)), GFP_KERNEL);
Hannes Reinecke ea7077
+			 sizeof(*conn_rqst) + sizeof(*conn_acc) +
Hannes Reinecke ea7077
+			 ctrl->lport->ops->lsrqst_priv_sz), GFP_KERNEL);
Hannes Reinecke ea7077
 	if (!lsop) {
Hannes Reinecke ea7077
+		dev_info(ctrl->ctrl.device,
Hannes Reinecke ea7077
+			"NVME-FC{%d}: send Create Connection failed: ENOMEM\n",
Hannes Reinecke ea7077
+			ctrl->cnum);
Hannes Reinecke ea7077
 		ret = -ENOMEM;
Hannes Reinecke ea7077
 		goto out_no_memory;
Hannes Reinecke ea7077
 	}
Hannes Reinecke ea7077
-	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
-	lsreq->private = (void *)&lsop[1];
Hannes Reinecke ea7077
-	conn_rqst = (struct fcnvme_ls_cr_conn_rqst *)
Hannes Reinecke ea7077
-			(lsreq->private + ctrl->lport->ops->lsrqst_priv_sz);
Hannes Reinecke ea7077
+	conn_rqst = (struct fcnvme_ls_cr_conn_rqst *)&lsop[1];
Hannes Reinecke ea7077
 	conn_acc = (struct fcnvme_ls_cr_conn_acc *)&conn_rqst[1];
Hannes Reinecke ea7077
+	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
+	if (ctrl->lport->ops->lsrqst_priv_sz)
Hannes Reinecke ea7077
+		lsreq->private = (void *)&conn_acc[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		lsreq->private = NULL;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	conn_rqst->w0.ls_cmd = FCNVME_LS_CREATE_CONNECTION;
Hannes Reinecke ea7077
 	conn_rqst->desc_list_len = cpu_to_be32(
Hannes Reinecke ea7077
@@ -1386,19 +1402,23 @@ nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl)
Hannes Reinecke ea7077
 	int ret;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	lsop = kzalloc((sizeof(*lsop) +
Hannes Reinecke ea7077
-			 ctrl->lport->ops->lsrqst_priv_sz +
Hannes Reinecke ea7077
-			 sizeof(*discon_rqst) + sizeof(*discon_acc)),
Hannes Reinecke ea7077
-			GFP_KERNEL);
Hannes Reinecke ea7077
-	if (!lsop)
Hannes Reinecke ea7077
-		/* couldn't sent it... too bad */
Hannes Reinecke ea7077
+			sizeof(*discon_rqst) + sizeof(*discon_acc) +
Hannes Reinecke ea7077
+			ctrl->lport->ops->lsrqst_priv_sz), GFP_KERNEL);
Hannes Reinecke ea7077
+	if (!lsop) {
Hannes Reinecke ea7077
+		dev_info(ctrl->ctrl.device,
Hannes Reinecke ea7077
+			"NVME-FC{%d}: send Disconnect Association "
Hannes Reinecke ea7077
+			"failed: ENOMEM\n",
Hannes Reinecke ea7077
+			ctrl->cnum);
Hannes Reinecke ea7077
 		return;
Hannes Reinecke ea7077
+	}
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
-	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
-
Hannes Reinecke ea7077
-	lsreq->private = (void *)&lsop[1];
Hannes Reinecke ea7077
-	discon_rqst = (struct fcnvme_ls_disconnect_assoc_rqst *)
Hannes Reinecke ea7077
-			(lsreq->private + ctrl->lport->ops->lsrqst_priv_sz);
Hannes Reinecke ea7077
+	discon_rqst = (struct fcnvme_ls_disconnect_assoc_rqst *)&lsop[1];
Hannes Reinecke ea7077
 	discon_acc = (struct fcnvme_ls_disconnect_assoc_acc *)&discon_rqst[1];
Hannes Reinecke ea7077
+	lsreq = &lsop->ls_req;
Hannes Reinecke ea7077
+	if (ctrl->lport->ops->lsrqst_priv_sz)
Hannes Reinecke ea7077
+		lsreq->private = (void *)&discon_acc[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		lsreq->private = NULL;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	discon_rqst->w0.ls_cmd = FCNVME_LS_DISCONNECT_ASSOC;
Hannes Reinecke ea7077
 	discon_rqst->desc_list_len = cpu_to_be32(
Hannes Reinecke ea7077
@@ -1784,15 +1804,17 @@ nvme_fc_init_aen_ops(struct nvme_fc_ctrl *ctrl)
Hannes Reinecke ea7077
 	struct nvme_fc_fcp_op *aen_op;
Hannes Reinecke ea7077
 	struct nvme_fc_cmd_iu *cmdiu;
Hannes Reinecke ea7077
 	struct nvme_command *sqe;
Hannes Reinecke ea7077
-	void *private;
Hannes Reinecke ea7077
+	void *private = NULL;
Hannes Reinecke ea7077
 	int i, ret;
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	aen_op = ctrl->aen_ops;
Hannes Reinecke ea7077
 	for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) {
Hannes Reinecke ea7077
-		private = kzalloc(ctrl->lport->ops->fcprqst_priv_sz,
Hannes Reinecke ea7077
+		if (ctrl->lport->ops->fcprqst_priv_sz) {
Hannes Reinecke ea7077
+			private = kzalloc(ctrl->lport->ops->fcprqst_priv_sz,
Hannes Reinecke ea7077
 						GFP_KERNEL);
Hannes Reinecke ea7077
-		if (!private)
Hannes Reinecke ea7077
-			return -ENOMEM;
Hannes Reinecke ea7077
+			if (!private)
Hannes Reinecke ea7077
+				return -ENOMEM;
Hannes Reinecke ea7077
+		}
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 		cmdiu = &aen_op->cmd_iu;
Hannes Reinecke ea7077
 		sqe = &cmdiu->sqe;
Hannes Reinecke ea7077
@@ -1823,9 +1845,6 @@ nvme_fc_term_aen_ops(struct nvme_fc_ctrl *ctrl)
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	aen_op = ctrl->aen_ops;
Hannes Reinecke ea7077
 	for (i = 0; i < NVME_NR_AEN_COMMANDS; i++, aen_op++) {
Hannes Reinecke ea7077
-		if (!aen_op->fcp_req.private)
Hannes Reinecke ea7077
-			continue;
Hannes Reinecke ea7077
-
Hannes Reinecke ea7077
 		__nvme_fc_exit_request(ctrl, aen_op);
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 		kfree(aen_op->fcp_req.private);
Hannes Reinecke ea7077
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c
Hannes Reinecke ea7077
index 66de6bd8f4fd..66a60a218994 100644
Hannes Reinecke ea7077
--- a/drivers/nvme/target/fc.c
Hannes Reinecke ea7077
+++ b/drivers/nvme/target/fc.c
Hannes Reinecke ea7077
@@ -1047,7 +1047,10 @@ nvmet_fc_register_targetport(struct nvmet_fc_port_info *pinfo,
Hannes Reinecke ea7077
 
Hannes Reinecke ea7077
 	newrec->fc_target_port.node_name = pinfo->node_name;
Hannes Reinecke ea7077
 	newrec->fc_target_port.port_name = pinfo->port_name;
Hannes Reinecke ea7077
-	newrec->fc_target_port.private = &newrec[1];
Hannes Reinecke ea7077
+	if (template->target_priv_sz)
Hannes Reinecke ea7077
+		newrec->fc_target_port.private = &newrec[1];
Hannes Reinecke ea7077
+	else
Hannes Reinecke ea7077
+		newrec->fc_target_port.private = NULL;
Hannes Reinecke ea7077
 	newrec->fc_target_port.port_id = pinfo->port_id;
Hannes Reinecke ea7077
 	newrec->fc_target_port.port_num = idx;
Hannes Reinecke ea7077
 	INIT_LIST_HEAD(&newrec->tgt_list);
Hannes Reinecke ea7077
-- 
Hannes Reinecke ea7077
2.16.4
Hannes Reinecke ea7077