All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion
@ 2016-01-30  7:05 Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 01/14] target: Add target_alloc_session() helper function Nicholas A. Bellinger
                   ` (13 more replies)
  0 siblings, 14 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Hi all,

Here is -v3 series code for target_alloc_session() helper
support using existing percpu-ida tag pre-allocation, along
with a new (*callback)() for allowing fabric driver code
setup to complete ahead of transport_register_session()
completing I_T nexus setup.

This includes a tree-wide fabric driver conversion to use
use target_alloc_session() + associated (*callback)() with
common code.  It updates vhost/iscsi and tcm_qla2xxx code
to use the new callback to finish their internal driver
setup for se_session.

As per HCH, it also contains sbp-target, usb-gadget/tcm,
xen-scsiback, tcm_fc and ib_srpt driver percpu_ida tag
pre-allocation conversions, along with TARGET_SCF_ACK_KREF
changes for v4.6-rc code.

Please review.

--nab

v3 changes:

  - Add xen-scsiback wrapper for handling pending_req tag failure
  - Add tcm_fc conversion to TARGET_SCF_ACK_KREF
  - Add ib_srpt conversion to percpu_ida tag allocation

Christoph Hellwig (1):
  target: Convert demo-mode only drivers to target_alloc_session

Nicholas Bellinger (13):
  target: Add target_alloc_session() helper function
  vhost/scsi: Convert to target_alloc_session usage
  tcm_qla2xxx: Convert to target_alloc_session usage
  tcm_fc: Convert to target_alloc_session usage
  ib_srpt: Convert to target_alloc_session usage
  sbp-target: Conversion to percpu_ida tag pre-allocation
  sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs
  usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation
  usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs
  xen-scsiback: Convert to percpu_ida tag allocation
  xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
  tcm_fc: Convert to TARGET_SCF_ACK_KREF I/O + TMR krefs
  ib_srpt: Convert to percpu_ida tag allocation

 drivers/infiniband/ulp/srpt/ib_srpt.c  |  76 +++-------
 drivers/infiniband/ulp/srpt/ib_srpt.h  |   2 -
 drivers/scsi/qla2xxx/qla_target.c      |   8 +-
 drivers/scsi/qla2xxx/qla_target.h      |   2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c     |  79 +++++-----
 drivers/target/loopback/tcm_loop.c     |  35 +----
 drivers/target/sbp/sbp_target.c        |  97 ++++++------
 drivers/target/target_core_transport.c |  56 +++++++
 drivers/target/tcm_fc/tfc_cmd.c        |  15 +-
 drivers/target/tcm_fc/tfc_sess.c       |  44 +++---
 drivers/usb/gadget/function/f_tcm.c    | 181 ++++++++++------------
 drivers/vhost/scsi.c                   |  99 +++++-------
 drivers/xen/xen-scsiback.c             | 265 ++++++++++++++++-----------------
 include/target/target_core_fabric.h    |   6 +
 14 files changed, 467 insertions(+), 498 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH-v3 01/14] target: Add target_alloc_session() helper function
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 02/14] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Based on HCH's original patch, this adds a full version to
support percpu-ida tag pre-allocation and callback function
pointer into fabric driver code to complete session setup.

Reported-by: Christoph Hellwig <hch@lst.de>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Andy Grover <agrover@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_transport.c | 56 ++++++++++++++++++++++++++++++++++
 include/target/target_core_fabric.h    |  6 ++++
 2 files changed, 62 insertions(+)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 9f3608e..6becc94 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -281,6 +281,17 @@ struct se_session *transport_init_session_tags(unsigned int tag_num,
 	struct se_session *se_sess;
 	int rc;
 
+	if (tag_num != 0 && !tag_size) {
+		pr_err("init_session_tags called with percpu-ida tag_num:"
+		       " %u, but zero tag_size\n", tag_num);
+		return ERR_PTR(-EINVAL);
+	}
+	if (!tag_num && tag_size) {
+		pr_err("init_session_tags called with percpu-ida tag_size:"
+		       " %u, but zero tag_num\n", tag_size);
+		return ERR_PTR(-EINVAL);
+	}
+
 	se_sess = transport_init_session(sup_prot_ops);
 	if (IS_ERR(se_sess))
 		return se_sess;
@@ -374,6 +385,51 @@ void transport_register_session(
 }
 EXPORT_SYMBOL(transport_register_session);
 
+struct se_session *
+target_alloc_session(struct se_portal_group *tpg,
+		     unsigned int tag_num, unsigned int tag_size,
+		     enum target_prot_op prot_op,
+		     const char *initiatorname, void *private,
+		     int (*callback)(struct se_portal_group *,
+				     struct se_session *, void *))
+{
+	struct se_session *sess;
+
+	/*
+	 * If the fabric driver is using percpu-ida based pre allocation
+	 * of I/O descriptor tags, go ahead and perform that setup now..
+	 */
+	if (tag_num != 0)
+		sess = transport_init_session_tags(tag_num, tag_size, prot_op);
+	else
+		sess = transport_init_session(prot_op);
+
+	if (IS_ERR(sess))
+		return sess;
+
+	sess->se_node_acl = core_tpg_check_initiator_node_acl(tpg,
+					(unsigned char *)initiatorname);
+	if (!sess->se_node_acl) {
+		transport_free_session(sess);
+		return ERR_PTR(-EACCES);
+	}
+	/*
+	 * Go ahead and perform any remaining fabric setup that is
+	 * required before transport_register_session().
+	 */
+	if (callback != NULL) {
+		int rc = callback(tpg, sess, private);
+		if (rc) {
+			transport_free_session(sess);
+			return ERR_PTR(rc);
+		}
+	}
+
+	transport_register_session(tpg, sess->se_node_acl, sess, private);
+	return sess;
+}
+EXPORT_SYMBOL(target_alloc_session);
+
 static void target_release_session(struct kref *kref)
 {
 	struct se_session *se_sess = container_of(kref,
diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
index 5665340..685a51a 100644
--- a/include/target/target_core_fabric.h
+++ b/include/target/target_core_fabric.h
@@ -108,6 +108,12 @@ void target_unregister_template(const struct target_core_fabric_ops *fo);
 int target_depend_item(struct config_item *item);
 void target_undepend_item(struct config_item *item);
 
+struct se_session *target_alloc_session(struct se_portal_group *,
+		unsigned int, unsigned int, enum target_prot_op prot_op,
+		const char *, void *,
+		int (*callback)(struct se_portal_group *,
+				struct se_session *, void *));
+
 struct se_session *transport_init_session(enum target_prot_op);
 int transport_alloc_session_tags(struct se_session *, unsigned int,
 		unsigned int);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 02/14] target: Convert demo-mode only drivers to target_alloc_session
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 01/14] target: Add target_alloc_session() helper function Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 03/14] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot

From: Christoph Hellwig <hch@lst.de>

Acked-by: Juergen Gross <jgross@suse.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Cc: Chris Boot <bootc@bootc.net>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/loopback/tcm_loop.c  | 35 +++++--------------------
 drivers/target/sbp/sbp_target.c     | 33 ++++++------------------
 drivers/usb/gadget/function/f_tcm.c | 45 ++++++++++----------------------
 drivers/xen/xen-scsiback.c          | 51 ++++++++++---------------------------
 4 files changed, 42 insertions(+), 122 deletions(-)

diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index d41a5c3..0216c75 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -806,54 +806,33 @@ static int tcm_loop_make_nexus(
 	struct tcm_loop_tpg *tl_tpg,
 	const char *name)
 {
-	struct se_portal_group *se_tpg;
 	struct tcm_loop_hba *tl_hba = tl_tpg->tl_hba;
 	struct tcm_loop_nexus *tl_nexus;
-	int ret = -ENOMEM;
 
 	if (tl_tpg->tl_nexus) {
 		pr_debug("tl_tpg->tl_nexus already exists\n");
 		return -EEXIST;
 	}
-	se_tpg = &tl_tpg->tl_se_tpg;
 
 	tl_nexus = kzalloc(sizeof(struct tcm_loop_nexus), GFP_KERNEL);
 	if (!tl_nexus) {
 		pr_err("Unable to allocate struct tcm_loop_nexus\n");
 		return -ENOMEM;
 	}
-	/*
-	 * Initialize the struct se_session pointer
-	 */
-	tl_nexus->se_sess = transport_init_session(
-				TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS);
+
+	tl_nexus->se_sess = target_alloc_session(&tl_tpg->tl_se_tpg, 0, 0,
+					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
+					name, tl_nexus, NULL);
 	if (IS_ERR(tl_nexus->se_sess)) {
-		ret = PTR_ERR(tl_nexus->se_sess);
-		goto out;
-	}
-	/*
-	 * Since we are running in 'demo mode' this call with generate a
-	 * struct se_node_acl for the tcm_loop struct se_portal_group with the SCSI
-	 * Initiator port name of the passed configfs group 'name'.
-	 */
-	tl_nexus->se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
-				se_tpg, (unsigned char *)name);
-	if (!tl_nexus->se_sess->se_node_acl) {
-		transport_free_session(tl_nexus->se_sess);
-		goto out;
+		kfree(tl_nexus);
+		return PTR_ERR(tl_nexus->se_sess);
 	}
-	/* Now, register the I_T Nexus as active. */
-	transport_register_session(se_tpg, tl_nexus->se_sess->se_node_acl,
-			tl_nexus->se_sess, tl_nexus);
+
 	tl_tpg->tl_nexus = tl_nexus;
 	pr_debug("TCM_Loop_ConfigFS: Established I_T Nexus to emulated"
 		" %s Initiator Port: %s\n", tcm_loop_dump_proto_id(tl_hba),
 		name);
 	return 0;
-
-out:
-	kfree(tl_nexus);
-	return ret;
 }
 
 static int tcm_loop_drop_nexus(
diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 3072f1a..ddd3398 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -196,45 +196,28 @@ static struct sbp_session *sbp_session_create(
 	struct sbp_session *sess;
 	int ret;
 	char guid_str[17];
-	struct se_node_acl *se_nacl;
+
+	snprintf(guid_str, sizeof(guid_str), "%016llx", guid);
 
 	sess = kmalloc(sizeof(*sess), GFP_KERNEL);
 	if (!sess) {
 		pr_err("failed to allocate session descriptor\n");
 		return ERR_PTR(-ENOMEM);
 	}
+	spin_lock_init(&sess->lock);
+	INIT_LIST_HEAD(&sess->login_list);
+	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
+	sess->guid = guid;
 
-	sess->se_sess = transport_init_session(TARGET_PROT_NORMAL);
+	sess->se_sess = target_alloc_session(&tpg->se_tpg, 0, 0, TARGET_PROT_NORMAL,
+					     guid_str, sess, NULL);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
-
 		ret = PTR_ERR(sess->se_sess);
 		kfree(sess);
 		return ERR_PTR(ret);
 	}
 
-	snprintf(guid_str, sizeof(guid_str), "%016llx", guid);
-
-	se_nacl = core_tpg_check_initiator_node_acl(&tpg->se_tpg, guid_str);
-	if (!se_nacl) {
-		pr_warn("Node ACL not found for %s\n", guid_str);
-
-		transport_free_session(sess->se_sess);
-		kfree(sess);
-
-		return ERR_PTR(-EPERM);
-	}
-
-	sess->se_sess->se_node_acl = se_nacl;
-
-	spin_lock_init(&sess->lock);
-	INIT_LIST_HEAD(&sess->login_list);
-	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
-
-	sess->guid = guid;
-
-	transport_register_session(&tpg->se_tpg, se_nacl, sess->se_sess, sess);
-
 	return sess;
 }
 
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index bad007b5..2e8b91d 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1581,53 +1581,34 @@ out:
 
 static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 {
-	struct se_portal_group *se_tpg;
 	struct tcm_usbg_nexus *tv_nexus;
-	int ret;
+	int ret = 0;
 
 	mutex_lock(&tpg->tpg_mutex);
 	if (tpg->tpg_nexus) {
 		ret = -EEXIST;
 		pr_debug("tpg->tpg_nexus already exists\n");
-		goto err_unlock;
+		goto out_unlock;
 	}
-	se_tpg = &tpg->se_tpg;
 
-	ret = -ENOMEM;
 	tv_nexus = kzalloc(sizeof(*tv_nexus), GFP_KERNEL);
-	if (!tv_nexus)
-		goto err_unlock;
-	tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
-	if (IS_ERR(tv_nexus->tvn_se_sess))
-		goto err_free;
+	if (!tv_nexus) {
+		ret = -ENOMEM;
+		goto out_unlock;
+	}
 
-	/*
-	 * Since we are running in 'demo mode' this call with generate a
-	 * struct se_node_acl for the tcm_vhost struct se_portal_group with
-	 * the SCSI Initiator port name of the passed configfs group 'name'.
-	 */
-	tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
-			se_tpg, name);
-	if (!tv_nexus->tvn_se_sess->se_node_acl) {
+	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 0, 0,
+						     TARGET_PROT_NORMAL, name,
+						     tv_nexus, NULL);
+	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 #define MAKE_NEXUS_MSG "core_tpg_check_initiator_node_acl() failed for %s\n"
 		pr_debug(MAKE_NEXUS_MSG, name);
 #undef MAKE_NEXUS_MSG
-		goto err_session;
+		kfree(tv_nexus);
+		ret = PTR_ERR(tv_nexus->tvn_se_sess);
 	}
-	/*
-	 * Now register the TCM vHost virtual I_T Nexus as active.
-	 */
-	transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
-			tv_nexus->tvn_se_sess, tv_nexus);
-	tpg->tpg_nexus = tv_nexus;
-	mutex_unlock(&tpg->tpg_mutex);
-	return 0;
 
-err_session:
-	transport_free_session(tv_nexus->tvn_se_sess);
-err_free:
-	kfree(tv_nexus);
-err_unlock:
+out_unlock:
 	mutex_unlock(&tpg->tpg_mutex);
 	return ret;
 }
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index ad4eb10..a50b6e4 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -1485,58 +1485,35 @@ static struct configfs_attribute *scsiback_param_attrs[] = {
 static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 				const char *name)
 {
-	struct se_portal_group *se_tpg;
-	struct se_session *se_sess;
 	struct scsiback_nexus *tv_nexus;
+	int ret = 0;
 
 	mutex_lock(&tpg->tv_tpg_mutex);
 	if (tpg->tpg_nexus) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
 		pr_debug("tpg->tpg_nexus already exists\n");
-		return -EEXIST;
+		ret = -EEXIST;
+		goto out_unlock;
 	}
-	se_tpg = &tpg->se_tpg;
 
 	tv_nexus = kzalloc(sizeof(struct scsiback_nexus), GFP_KERNEL);
 	if (!tv_nexus) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto out_unlock;
 	}
-	/*
-	 * Initialize the struct se_session pointer
-	 */
-	tv_nexus->tvn_se_sess = transport_init_session(TARGET_PROT_NORMAL);
+
+	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 0, 0,
+						     TARGET_PROT_NORMAL, name,
+						     tv_nexus, NULL);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
 		kfree(tv_nexus);
-		return -ENOMEM;
-	}
-	se_sess = tv_nexus->tvn_se_sess;
-	/*
-	 * Since we are running in 'demo mode' this call with generate a
-	 * struct se_node_acl for the scsiback struct se_portal_group with
-	 * the SCSI Initiator port name of the passed configfs group 'name'.
-	 */
-	tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
-				se_tpg, (unsigned char *)name);
-	if (!tv_nexus->tvn_se_sess->se_node_acl) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
-		pr_debug("core_tpg_check_initiator_node_acl() failed for %s\n",
-			 name);
-		goto out;
+		ret = -ENOMEM;
+		goto out_unlock;
 	}
-	/* Now register the TCM pvscsi virtual I_T Nexus as active. */
-	transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
-			tv_nexus->tvn_se_sess, tv_nexus);
-	tpg->tpg_nexus = tv_nexus;
 
+	tpg->tpg_nexus = tv_nexus;
+out_unlock:
 	mutex_unlock(&tpg->tv_tpg_mutex);
-	return 0;
-
-out:
-	transport_free_session(se_sess);
-	kfree(tv_nexus);
-	return -ENOMEM;
+	return ret;
 }
 
 static int scsiback_drop_nexus(struct scsiback_tpg *tpg)
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 03/14] vhost/scsi: Convert to target_alloc_session usage
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 01/14] target: Add target_alloc_session() helper function Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 02/14] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 04/14] tcm_qla2xxx: " Nicholas A. Bellinger
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/vhost/scsi.c | 99 ++++++++++++++++++++++------------------------------
 1 file changed, 41 insertions(+), 58 deletions(-)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index 29cfc57..cd5f20f 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1664,8 +1664,7 @@ static void vhost_scsi_port_unlink(struct se_portal_group *se_tpg,
 	mutex_unlock(&vhost_scsi_mutex);
 }
 
-static void vhost_scsi_free_cmd_map_res(struct vhost_scsi_nexus *nexus,
-				       struct se_session *se_sess)
+static void vhost_scsi_free_cmd_map_res(struct se_session *se_sess)
 {
 	struct vhost_scsi_cmd *tv_cmd;
 	unsigned int i;
@@ -1721,98 +1720,82 @@ static struct configfs_attribute *vhost_scsi_tpg_attrib_attrs[] = {
 	NULL,
 };
 
-static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
-				const char *name)
+static int vhost_scsi_nexus_cb(struct se_portal_group *se_tpg,
+			       struct se_session *se_sess, void *p)
 {
-	struct se_portal_group *se_tpg;
-	struct se_session *se_sess;
-	struct vhost_scsi_nexus *tv_nexus;
 	struct vhost_scsi_cmd *tv_cmd;
 	unsigned int i;
 
-	mutex_lock(&tpg->tv_tpg_mutex);
-	if (tpg->tpg_nexus) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
-		pr_debug("tpg->tpg_nexus already exists\n");
-		return -EEXIST;
-	}
-	se_tpg = &tpg->se_tpg;
-
-	tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL);
-	if (!tv_nexus) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
-		pr_err("Unable to allocate struct vhost_scsi_nexus\n");
-		return -ENOMEM;
-	}
-	/*
-	 *  Initialize the struct se_session pointer and setup tagpool
-	 *  for struct vhost_scsi_cmd descriptors
-	 */
-	tv_nexus->tvn_se_sess = transport_init_session_tags(
-					VHOST_SCSI_DEFAULT_TAGS,
-					sizeof(struct vhost_scsi_cmd),
-					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS);
-	if (IS_ERR(tv_nexus->tvn_se_sess)) {
-		mutex_unlock(&tpg->tv_tpg_mutex);
-		kfree(tv_nexus);
-		return -ENOMEM;
-	}
-	se_sess = tv_nexus->tvn_se_sess;
 	for (i = 0; i < VHOST_SCSI_DEFAULT_TAGS; i++) {
 		tv_cmd = &((struct vhost_scsi_cmd *)se_sess->sess_cmd_map)[i];
 
 		tv_cmd->tvc_sgl = kzalloc(sizeof(struct scatterlist) *
 					VHOST_SCSI_PREALLOC_SGLS, GFP_KERNEL);
 		if (!tv_cmd->tvc_sgl) {
-			mutex_unlock(&tpg->tv_tpg_mutex);
 			pr_err("Unable to allocate tv_cmd->tvc_sgl\n");
 			goto out;
 		}
 
 		tv_cmd->tvc_upages = kzalloc(sizeof(struct page *) *
-					VHOST_SCSI_PREALLOC_UPAGES, GFP_KERNEL);
+				VHOST_SCSI_PREALLOC_UPAGES, GFP_KERNEL);
 		if (!tv_cmd->tvc_upages) {
-			mutex_unlock(&tpg->tv_tpg_mutex);
 			pr_err("Unable to allocate tv_cmd->tvc_upages\n");
 			goto out;
 		}
 
 		tv_cmd->tvc_prot_sgl = kzalloc(sizeof(struct scatterlist) *
-					VHOST_SCSI_PREALLOC_PROT_SGLS, GFP_KERNEL);
+				VHOST_SCSI_PREALLOC_PROT_SGLS, GFP_KERNEL);
 		if (!tv_cmd->tvc_prot_sgl) {
-			mutex_unlock(&tpg->tv_tpg_mutex);
 			pr_err("Unable to allocate tv_cmd->tvc_prot_sgl\n");
 			goto out;
 		}
 	}
+	return 0;
+out:
+	vhost_scsi_free_cmd_map_res(se_sess);
+	return -ENOMEM;
+}
+
+static int vhost_scsi_make_nexus(struct vhost_scsi_tpg *tpg,
+				const char *name)
+{
+	struct se_portal_group *se_tpg;
+	struct vhost_scsi_nexus *tv_nexus;
+
+	mutex_lock(&tpg->tv_tpg_mutex);
+	if (tpg->tpg_nexus) {
+		mutex_unlock(&tpg->tv_tpg_mutex);
+		pr_debug("tpg->tpg_nexus already exists\n");
+		return -EEXIST;
+	}
+	se_tpg = &tpg->se_tpg;
+
+	tv_nexus = kzalloc(sizeof(struct vhost_scsi_nexus), GFP_KERNEL);
+	if (!tv_nexus) {
+		mutex_unlock(&tpg->tv_tpg_mutex);
+		pr_err("Unable to allocate struct vhost_scsi_nexus\n");
+		return -ENOMEM;
+	}
 	/*
 	 * Since we are running in 'demo mode' this call with generate a
 	 * struct se_node_acl for the vhost_scsi struct se_portal_group with
 	 * the SCSI Initiator port name of the passed configfs group 'name'.
 	 */
-	tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl(
-				se_tpg, (unsigned char *)name);
-	if (!tv_nexus->tvn_se_sess->se_node_acl) {
+	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg,
+					VHOST_SCSI_DEFAULT_TAGS,
+					sizeof(struct vhost_scsi_cmd),
+					TARGET_PROT_DIN_PASS | TARGET_PROT_DOUT_PASS,
+					(unsigned char *)name, tv_nexus,
+					vhost_scsi_nexus_cb);
+	if (IS_ERR(tv_nexus->tvn_se_sess)) {
 		mutex_unlock(&tpg->tv_tpg_mutex);
-		pr_debug("core_tpg_check_initiator_node_acl() failed"
-				" for %s\n", name);
-		goto out;
+		kfree(tv_nexus);
+		return -ENOMEM;
 	}
-	/*
-	 * Now register the TCM vhost virtual I_T Nexus as active.
-	 */
-	transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl,
-			tv_nexus->tvn_se_sess, tv_nexus);
 	tpg->tpg_nexus = tv_nexus;
 
 	mutex_unlock(&tpg->tv_tpg_mutex);
 	return 0;
-
-out:
-	vhost_scsi_free_cmd_map_res(tv_nexus, se_sess);
-	transport_free_session(se_sess);
-	kfree(tv_nexus);
-	return -ENOMEM;
 }
 
 static int vhost_scsi_drop_nexus(struct vhost_scsi_tpg *tpg)
@@ -1853,7 +1836,7 @@ static int vhost_scsi_drop_nexus(struct vhost_scsi_tpg *tpg)
 		" %s Initiator Port: %s\n", vhost_scsi_dump_proto_id(tpg->tport),
 		tv_nexus->tvn_se_sess->se_node_acl->initiatorname);
 
-	vhost_scsi_free_cmd_map_res(tv_nexus, se_sess);
+	vhost_scsi_free_cmd_map_res(se_sess);
 	/*
 	 * Release the SCSI I_T Nexus to the emulated vhost Target Port
 	 */
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 04/14] tcm_qla2xxx: Convert to target_alloc_session usage
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (2 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 03/14] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 05/14] tcm_fc: " Nicholas A. Bellinger
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Himanshu Madhani, Quinn Tran

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
Cc: Quinn Tran <quinn.tran@qlogic.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/scsi/qla2xxx/qla_target.c  |  8 +---
 drivers/scsi/qla2xxx/qla_target.h  |  2 +-
 drivers/scsi/qla2xxx/tcm_qla2xxx.c | 79 +++++++++++++++++++-------------------
 3 files changed, 43 insertions(+), 46 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
index 8075a4c..905f431 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -879,7 +879,6 @@ static struct qla_tgt_sess *qlt_create_sess(
 	struct qla_hw_data *ha = vha->hw;
 	struct qla_tgt_sess *sess;
 	unsigned long flags;
-	unsigned char be_sid[3];
 
 	/* Check to avoid double sessions */
 	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
@@ -948,17 +947,14 @@ static struct qla_tgt_sess *qlt_create_sess(
 	    "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n",
 	    sess, vha->vha_tgt.qla_tgt);
 
-	be_sid[0] = sess->s_id.b.domain;
-	be_sid[1] = sess->s_id.b.area;
-	be_sid[2] = sess->s_id.b.al_pa;
 	/*
 	 * Determine if this fc_port->port_name is allowed to access
 	 * target mode using explict NodeACLs+MappedLUNs, or using
 	 * TPG demo mode.  If this is successful a target mode FC nexus
 	 * is created.
 	 */
-	if (ha->tgt.tgt_ops->check_initiator_node_acl(vha,
-	    &fcport->port_name[0], sess, &be_sid[0], fcport->loop_id) < 0) {
+	if (ha->tgt.tgt_ops->check_initiator_node_acl(vha, &fcport->port_name[0],
+						      sess)) {
 		kfree(sess);
 		return NULL;
 	}
diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
index 71b2865..409bd5f 100644
--- a/drivers/scsi/qla2xxx/qla_target.h
+++ b/drivers/scsi/qla2xxx/qla_target.h
@@ -731,7 +731,7 @@ struct qla_tgt_func_tmpl {
 	void (*free_session)(struct qla_tgt_sess *);
 
 	int (*check_initiator_node_acl)(struct scsi_qla_host *, unsigned char *,
-					void *, uint8_t *, uint16_t);
+					struct qla_tgt_sess *);
 	void (*update_sess)(struct qla_tgt_sess *, port_id_t, uint16_t, bool);
 	struct qla_tgt_sess *(*find_sess_by_loop_id)(struct scsi_qla_host *,
 						const uint16_t);
diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
index faf0a12..f982ae7 100644
--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
@@ -1336,6 +1336,39 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
 	transport_deregister_session(sess->se_sess);
 }
 
+static int tcm_qla2xxx_session_cb(struct se_portal_group *se_tpg,
+				  struct se_session *se_sess, void *p)
+{
+	struct tcm_qla2xxx_tpg *tpg = container_of(se_tpg,
+				struct tcm_qla2xxx_tpg, se_tpg);
+	struct tcm_qla2xxx_lport *lport = tpg->lport;
+	struct qla_hw_data *ha = lport->qla_vha->hw;
+	struct se_node_acl *se_nacl = se_sess->se_node_acl;
+	struct tcm_qla2xxx_nacl *nacl = container_of(se_nacl,
+				struct tcm_qla2xxx_nacl, se_node_acl);
+	struct qla_tgt_sess *qlat_sess = p;
+	uint16_t loop_id = qlat_sess->loop_id;
+	unsigned long flags;
+	unsigned char be_sid[3];
+
+	be_sid[0] = qlat_sess->s_id.b.domain;
+	be_sid[1] = qlat_sess->s_id.b.area;
+	be_sid[2] = qlat_sess->s_id.b.al_pa;
+
+	/*
+	 * And now setup se_nacl and session pointers into HW lport internal
+	 * mappings for fabric S_ID and LOOP_ID.
+	 */
+	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
+	tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl,
+				     se_sess, qlat_sess, be_sid);
+	tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl,
+					se_sess, qlat_sess, loop_id);
+	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
+
+	return 0;
+}
+
 /*
  * Called via qlt_create_sess():ha->qla2x_tmpl->check_initiator_node_acl()
  * to locate struct se_node_acl
@@ -1343,20 +1376,13 @@ static void tcm_qla2xxx_free_session(struct qla_tgt_sess *sess)
 static int tcm_qla2xxx_check_initiator_node_acl(
 	scsi_qla_host_t *vha,
 	unsigned char *fc_wwpn,
-	void *qla_tgt_sess,
-	uint8_t *s_id,
-	uint16_t loop_id)
+	struct qla_tgt_sess *qlat_sess)
 {
 	struct qla_hw_data *ha = vha->hw;
 	struct tcm_qla2xxx_lport *lport;
 	struct tcm_qla2xxx_tpg *tpg;
-	struct tcm_qla2xxx_nacl *nacl;
-	struct se_portal_group *se_tpg;
-	struct se_node_acl *se_nacl;
 	struct se_session *se_sess;
-	struct qla_tgt_sess *sess = qla_tgt_sess;
 	unsigned char port_name[36];
-	unsigned long flags;
 	int num_tags = (ha->cur_fw_xcb_count) ? ha->cur_fw_xcb_count :
 		       TCM_QLA2XXX_DEFAULT_TAGS;
 
@@ -1374,15 +1400,6 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 		pr_err("Unable to lcoate struct tcm_qla2xxx_lport->tpg_1\n");
 		return -EINVAL;
 	}
-	se_tpg = &tpg->se_tpg;
-
-	se_sess = transport_init_session_tags(num_tags,
-					      sizeof(struct qla_tgt_cmd),
-					      TARGET_PROT_ALL);
-	if (IS_ERR(se_sess)) {
-		pr_err("Unable to initialize struct se_session\n");
-		return PTR_ERR(se_sess);
-	}
 	/*
 	 * Format the FCP Initiator port_name into colon seperated values to
 	 * match the format by tcm_qla2xxx explict ConfigFS NodeACLs.
@@ -1393,28 +1410,12 @@ static int tcm_qla2xxx_check_initiator_node_acl(
 	 * Locate our struct se_node_acl either from an explict NodeACL created
 	 * via ConfigFS, or via running in TPG demo mode.
 	 */
-	se_sess->se_node_acl = core_tpg_check_initiator_node_acl(se_tpg,
-					port_name);
-	if (!se_sess->se_node_acl) {
-		transport_free_session(se_sess);
-		return -EINVAL;
-	}
-	se_nacl = se_sess->se_node_acl;
-	nacl = container_of(se_nacl, struct tcm_qla2xxx_nacl, se_node_acl);
-	/*
-	 * And now setup the new se_nacl and session pointers into our HW lport
-	 * mappings for fabric S_ID and LOOP_ID.
-	 */
-	spin_lock_irqsave(&ha->tgt.sess_lock, flags);
-	tcm_qla2xxx_set_sess_by_s_id(lport, se_nacl, nacl, se_sess,
-			qla_tgt_sess, s_id);
-	tcm_qla2xxx_set_sess_by_loop_id(lport, se_nacl, nacl, se_sess,
-			qla_tgt_sess, loop_id);
-	spin_unlock_irqrestore(&ha->tgt.sess_lock, flags);
-	/*
-	 * Finally register the new FC Nexus with TCM
-	 */
-	transport_register_session(se_nacl->se_tpg, se_nacl, se_sess, sess);
+	se_sess = target_alloc_session(&tpg->se_tpg, num_tags,
+				       sizeof(struct qla_tgt_cmd),
+				       TARGET_PROT_ALL, port_name,
+				       qlat_sess, tcm_qla2xxx_session_cb);
+	if (IS_ERR(se_sess))
+		return PTR_ERR(se_sess);
 
 	return 0;
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 05/14] tcm_fc: Convert to target_alloc_session usage
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (3 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 04/14] tcm_qla2xxx: " Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 06/14] ib_srpt: " Nicholas A. Bellinger
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vasu Dev

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Vasu Dev <vasu.dev@linux.intel.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/tcm_fc/tfc_sess.c | 44 ++++++++++++++++++++--------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/target/tcm_fc/tfc_sess.c b/drivers/target/tcm_fc/tfc_sess.c
index e19f4c5..d0c3e18 100644
--- a/drivers/target/tcm_fc/tfc_sess.c
+++ b/drivers/target/tcm_fc/tfc_sess.c
@@ -186,6 +186,20 @@ out:
 	return NULL;
 }
 
+static int ft_sess_alloc_cb(struct se_portal_group *se_tpg,
+			    struct se_session *se_sess, void *p)
+{
+	struct ft_sess *sess = p;
+	struct ft_tport *tport = sess->tport;
+	struct hlist_head *head = &tport->hash[ft_sess_hash(sess->port_id)];
+
+	pr_debug("port_id %x sess %p\n", sess->port_id, sess);
+	hlist_add_head_rcu(&sess->hash, head);
+	tport->sess_count++;
+
+	return 0;
+}
+
 /*
  * Allocate session and enter it in the hash for the local port.
  * Caller holds ft_lport_lock.
@@ -194,7 +208,6 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 				      struct fc_rport_priv *rdata)
 {
 	struct se_portal_group *se_tpg = &tport->tpg->se_tpg;
-	struct se_node_acl *se_acl;
 	struct ft_sess *sess;
 	struct hlist_head *head;
 	unsigned char initiatorname[TRANSPORT_IQN_LEN];
@@ -210,31 +223,18 @@ static struct ft_sess *ft_sess_create(struct ft_tport *tport, u32 port_id,
 	if (!sess)
 		return NULL;
 
-	sess->se_sess = transport_init_session_tags(TCM_FC_DEFAULT_TAGS,
-						    sizeof(struct ft_cmd),
-						    TARGET_PROT_NORMAL);
-	if (IS_ERR(sess->se_sess)) {
-		kfree(sess);
-		return NULL;
-	}
+	kref_init(&sess->kref); /* ref for table entry */
+	sess->tport = tport;
+	sess->port_id = port_id;
 
-	se_acl = core_tpg_get_initiator_node_acl(se_tpg, &initiatorname[0]);
-	if (!se_acl) {
-		transport_free_session(sess->se_sess);
+	sess->se_sess = target_alloc_session(se_tpg, TCM_FC_DEFAULT_TAGS,
+					     sizeof(struct ft_cmd),
+					     TARGET_PROT_NORMAL, &initiatorname[0],
+					     sess, ft_sess_alloc_cb);
+	if (IS_ERR(sess->se_sess)) {
 		kfree(sess);
 		return NULL;
 	}
-	sess->se_sess->se_node_acl = se_acl;
-	sess->tport = tport;
-	sess->port_id = port_id;
-	kref_init(&sess->kref);	/* ref for table entry */
-	hlist_add_head_rcu(&sess->hash, head);
-	tport->sess_count++;
-
-	pr_debug("port_id %x sess %p\n", port_id, sess);
-
-	transport_register_session(&tport->tpg->se_tpg, se_acl,
-				   sess->se_sess, sess);
 	return sess;
 }
 
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 06/14] ib_srpt: Convert to target_alloc_session usage
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (4 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 05/14] tcm_fc: " Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-02-04 22:14   ` Bart Van Assche
  2016-01-30  7:05 ` [PATCH-v3 07/14] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
                   ` (7 subsequent siblings)
  13 siblings, 1 reply; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vu Pham

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Vu Pham <vu@mellanox.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c | 23 ++++++-----------------
 1 file changed, 6 insertions(+), 17 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 0c37fee..72a671e 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2240,7 +2240,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 	struct srp_login_rej *rej;
 	struct ib_cm_rep_param *rep_param;
 	struct srpt_rdma_ch *ch, *tmp_ch;
-	struct se_node_acl *se_acl;
 	u32 it_iu_len;
 	int i, ret = 0;
 	unsigned char *p;
@@ -2406,19 +2405,12 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 	pr_debug("registering session %s\n", ch->sess_name);
 	p = &ch->sess_name[0];
 
-	ch->sess = transport_init_session(TARGET_PROT_NORMAL);
-	if (IS_ERR(ch->sess)) {
-		rej->reason = cpu_to_be32(
-				SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES);
-		pr_debug("Failed to create session\n");
-		goto destroy_ib;
-	}
-
 try_again:
-	se_acl = core_tpg_get_initiator_node_acl(&sport->port_tpg_1, p);
-	if (!se_acl) {
+	ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
+					TARGET_PROT_NORMAL, p, ch, NULL);
+	if (IS_ERR(ch->sess)) {
 		pr_info("Rejected login because no ACL has been"
-			" configured yet for initiator %s.\n", ch->sess_name);
+			" configured yet for initiator %s.\n", p);
 		/*
 		 * XXX: Hack to retry of ch->i_port_id without leading '0x'
 		 */
@@ -2426,14 +2418,11 @@ try_again:
 			p += 2;
 			goto try_again;
 		}
-		rej->reason = cpu_to_be32(
+		rej->reason = cpu_to_be32((PTR_ERR(ch->sess) == -ENOMEM) ?
+				SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES :
 				SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);
-		transport_free_session(ch->sess);
 		goto destroy_ib;
 	}
-	ch->sess->se_node_acl = se_acl;
-
-	transport_register_session(&sport->port_tpg_1, se_acl, ch->sess, ch);
 
 	pr_debug("Establish connection sess=%p name=%s cm_id=%p\n", ch->sess,
 		 ch->sess_name, ch->cm_id);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 07/14] sbp-target: Conversion to percpu_ida tag pre-allocation
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (5 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 06/14] ib_srpt: " Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 08/14] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Chris Boot <bootc@bootc.net>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/sbp/sbp_target.c | 38 +++++++++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index ddd3398..756e87f 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -209,8 +209,10 @@ static struct sbp_session *sbp_session_create(
 	INIT_DELAYED_WORK(&sess->maint_work, session_maintenance_work);
 	sess->guid = guid;
 
-	sess->se_sess = target_alloc_session(&tpg->se_tpg, 0, 0, TARGET_PROT_NORMAL,
-					     guid_str, sess, NULL);
+	sess->se_sess = target_alloc_session(&tpg->se_tpg, 128,
+					     sizeof(struct sbp_target_request),
+					     TARGET_PROT_NORMAL, guid_str,
+					     sess, NULL);
 	if (IS_ERR(sess->se_sess)) {
 		pr_err("failed to init se_session\n");
 		ret = PTR_ERR(sess->se_sess);
@@ -921,6 +923,24 @@ static inline bool tgt_agent_check_active(struct sbp_target_agent *agent)
 	return active;
 }
 
+static struct sbp_target_request *sbp_mgt_get_req(struct sbp_session *sess,
+	struct fw_card *card, u64 next_orb)
+{
+	struct se_session *se_sess = sess->se_sess;
+	struct sbp_target_request *req;
+	int tag;
+
+	tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC);
+	if (tag < 0)
+		return ERR_PTR(-ENOMEM);
+
+	req = &((struct sbp_target_request *)se_sess->sess_cmd_map)[tag];
+	req->se_cmd.map_tag = tag;
+	req->se_cmd.tag = next_orb;
+
+	return req;
+}
+
 static void tgt_agent_fetch_work(struct work_struct *work)
 {
 	struct sbp_target_agent *agent =
@@ -932,7 +952,7 @@ static void tgt_agent_fetch_work(struct work_struct *work)
 	u64 next_orb = agent->orb_pointer;
 
 	while (next_orb && tgt_agent_check_active(agent)) {
-		req = kzalloc(sizeof(*req), GFP_KERNEL);
+		req = sbp_mgt_get_req(sess, sess->card, next_orb);
 		if (!req) {
 			spin_lock_bh(&agent->lock);
 			agent->state = AGENT_STATE_DEAD;
@@ -1430,9 +1450,13 @@ static int sbp_send_sense(struct sbp_target_request *req)
 
 static void sbp_free_request(struct sbp_target_request *req)
 {
+	struct se_cmd *se_cmd = &req->se_cmd;
+	struct se_session *se_sess = se_cmd->se_sess;
+
 	kfree(req->pg_tbl);
 	kfree(req->cmd_buf);
-	kfree(req);
+
+	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
 
 static void sbp_mgt_agent_process(struct work_struct *work)
@@ -1592,8 +1616,12 @@ static void sbp_mgt_agent_rw(struct fw_card *card,
 			rcode = RCODE_CONFLICT_ERROR;
 			goto out;
 		}
-
+		// XXX:
+#if 0
+		req = sbp_mgt_get_req(agent->login->sess, card);
+#else
 		req = kzalloc(sizeof(*req), GFP_ATOMIC);
+#endif
 		if (!req) {
 			rcode = RCODE_CONFLICT_ERROR;
 			goto out;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 08/14] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (6 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 07/14] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 09/14] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Chris Boot <bootc@bootc.net>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/sbp/sbp_target.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/drivers/target/sbp/sbp_target.c b/drivers/target/sbp/sbp_target.c
index 756e87f..251d532 100644
--- a/drivers/target/sbp/sbp_target.c
+++ b/drivers/target/sbp/sbp_target.c
@@ -893,7 +893,6 @@ static void tgt_agent_process_work(struct work_struct *work)
 					STATUS_BLOCK_SBP_STATUS(
 						SBP_STATUS_REQ_TYPE_NOTSUPP));
 			sbp_send_status(req);
-			sbp_free_request(req);
 			return;
 		case 3: /* Dummy ORB */
 			req->status.status |= cpu_to_be32(
@@ -904,7 +903,6 @@ static void tgt_agent_process_work(struct work_struct *work)
 					STATUS_BLOCK_SBP_STATUS(
 						SBP_STATUS_DUMMY_ORB_COMPLETE));
 			sbp_send_status(req);
-			sbp_free_request(req);
 			return;
 		default:
 			BUG();
@@ -988,7 +986,6 @@ static void tgt_agent_fetch_work(struct work_struct *work)
 			spin_unlock_bh(&agent->lock);
 
 			sbp_send_status(req);
-			sbp_free_request(req);
 			return;
 		}
 
@@ -1235,7 +1232,7 @@ static void sbp_handle_command(struct sbp_target_request *req)
 	req->se_cmd.tag = req->orb_pointer;
 	if (target_submit_cmd(&req->se_cmd, sess->se_sess, req->cmd_buf,
 			      req->sense_buf, unpacked_lun, data_length,
-			      TCM_SIMPLE_TAG, data_dir, 0))
+			      TCM_SIMPLE_TAG, data_dir, TARGET_SCF_ACK_KREF))
 		goto err;
 
 	return;
@@ -1247,7 +1244,6 @@ err:
 		STATUS_BLOCK_LEN(1) |
 		STATUS_BLOCK_SBP_STATUS(SBP_STATUS_UNSPECIFIED_ERROR));
 	sbp_send_status(req);
-	sbp_free_request(req);
 }
 
 /*
@@ -1346,22 +1342,29 @@ static int sbp_rw_data(struct sbp_target_request *req)
 
 static int sbp_send_status(struct sbp_target_request *req)
 {
-	int ret, length;
+	int rc, ret = 0, length;
 	struct sbp_login_descriptor *login = req->login;
 
 	length = (((be32_to_cpu(req->status.status) >> 24) & 0x07) + 1) * 4;
 
-	ret = sbp_run_request_transaction(req, TCODE_WRITE_BLOCK_REQUEST,
+	rc = sbp_run_request_transaction(req, TCODE_WRITE_BLOCK_REQUEST,
 			login->status_fifo_addr, &req->status, length);
-	if (ret != RCODE_COMPLETE) {
-		pr_debug("sbp_send_status: write failed: 0x%x\n", ret);
-		return -EIO;
+	if (rc != RCODE_COMPLETE) {
+		pr_debug("sbp_send_status: write failed: 0x%x\n", rc);
+		ret = -EIO;
+		goto put_ref;
 	}
 
 	pr_debug("sbp_send_status: status write complete for ORB: 0x%llx\n",
 			req->orb_pointer);
-
-	return 0;
+	/*
+	 * Drop the extra ACK_KREF reference taken by target_submit_cmd()
+	 * ahead of sbp_check_stop_free() -> transport_generic_free_cmd()
+	 * final se_cmd->cmd_kref put.
+	 */
+put_ref:
+	target_put_sess_cmd(&req->se_cmd);
+	return ret;
 }
 
 static void sbp_sense_mangle(struct sbp_target_request *req)
@@ -1826,8 +1829,7 @@ static int sbp_check_stop_free(struct se_cmd *se_cmd)
 	struct sbp_target_request *req = container_of(se_cmd,
 			struct sbp_target_request, se_cmd);
 
-	transport_generic_free_cmd(&req->se_cmd, 0);
-	return 1;
+	return transport_generic_free_cmd(&req->se_cmd, 0);
 }
 
 static int sbp_count_se_tpg_luns(struct se_portal_group *tpg)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 09/14] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (7 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 08/14] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 10/14] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/usb/gadget/function/f_tcm.c | 95 ++++++++++++++++++++++---------------
 1 file changed, 56 insertions(+), 39 deletions(-)

diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 2e8b91d..8773572 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -1073,39 +1073,65 @@ out:
 	usbg_cleanup_cmd(cmd);
 }
 
+static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu,
+		struct tcm_usbg_nexus *tv_nexus, u32 scsi_tag)
+{
+	struct se_session *se_sess = tv_nexus->tvn_se_sess;
+	struct usbg_cmd *cmd;
+	int tag;
+
+	tag = percpu_ida_alloc(&se_sess->sess_tag_pool, GFP_ATOMIC);
+	if (tag < 0)
+		return ERR_PTR(-ENOMEM);
+
+	cmd = &((struct usbg_cmd *)se_sess->sess_cmd_map)[tag];
+	cmd->se_cmd.map_tag = tag;
+	cmd->se_cmd.tag = cmd->tag = scsi_tag;
+	cmd->fu = fu;
+
+	return cmd;
+}
+
+static void usbg_release_cmd(struct se_cmd *);
+
 static int usbg_submit_command(struct f_uas *fu,
 		void *cmdbuf, unsigned int len)
 {
 	struct command_iu *cmd_iu = cmdbuf;
 	struct usbg_cmd *cmd;
-	struct usbg_tpg *tpg;
-	struct tcm_usbg_nexus *tv_nexus;
+	struct usbg_tpg *tpg = fu->tpg;
+	struct tcm_usbg_nexus *tv_nexus = tpg->tpg_nexus;
 	u32 cmd_len;
+	u16 scsi_tag;
 
 	if (cmd_iu->iu_id != IU_ID_COMMAND) {
 		pr_err("Unsupported type %d\n", cmd_iu->iu_id);
 		return -EINVAL;
 	}
 
-	cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
-	if (!cmd)
-		return -ENOMEM;
+	tv_nexus = tpg->tpg_nexus;
+	if (!tv_nexus) {
+		pr_err("Missing nexus, ignoring command\n");
+		return -EINVAL;
+	}
 
-	cmd->fu = fu;
+	cmd_len = (cmd_iu->len & ~0x3) + 16;
+	if (cmd_len > USBG_MAX_CMD)
+		return -EINVAL;
+
+	scsi_tag = be16_to_cpup(&cmd_iu->tag);
+	cmd = usbg_get_cmd(fu, tv_nexus, scsi_tag);
+	if (IS_ERR(cmd)) {
+		pr_err("usbg_get_cmd failed\n");
+		return -ENOMEM;
+	}
 
 	/* XXX until I figure out why I can't free in on complete */
 	kref_init(&cmd->ref);
 	kref_get(&cmd->ref);
 
-	tpg = fu->tpg;
-	cmd_len = (cmd_iu->len & ~0x3) + 16;
-	if (cmd_len > USBG_MAX_CMD)
-		goto err;
-
 	memcpy(cmd->cmd_buf, cmd_iu->cdb, cmd_len);
 
-	cmd->tag = be16_to_cpup(&cmd_iu->tag);
-	cmd->se_cmd.tag = cmd->tag;
 	if (fu->flags & USBG_USE_STREAMS) {
 		if (cmd->tag > UASP_SS_EP_COMP_NUM_STREAMS)
 			goto err;
@@ -1117,12 +1143,6 @@ static int usbg_submit_command(struct f_uas *fu,
 		cmd->stream = &fu->stream[0];
 	}
 
-	tv_nexus = tpg->tpg_nexus;
-	if (!tv_nexus) {
-		pr_err("Missing nexus, ignoring command\n");
-		goto err;
-	}
-
 	switch (cmd_iu->prio_attr & 0x7) {
 	case UAS_HEAD_TAG:
 		cmd->prio_attr = TCM_HEAD_TAG;
@@ -1148,7 +1168,7 @@ static int usbg_submit_command(struct f_uas *fu,
 
 	return 0;
 err:
-	kfree(cmd);
+	usbg_release_cmd(&cmd->se_cmd);
 	return -EINVAL;
 }
 
@@ -1190,7 +1210,7 @@ static int bot_submit_command(struct f_uas *fu,
 {
 	struct bulk_cb_wrap *cbw = cmdbuf;
 	struct usbg_cmd *cmd;
-	struct usbg_tpg *tpg;
+	struct usbg_tpg *tpg = fu->tpg;
 	struct tcm_usbg_nexus *tv_nexus;
 	u32 cmd_len;
 
@@ -1207,28 +1227,25 @@ static int bot_submit_command(struct f_uas *fu,
 	if (cmd_len < 1 || cmd_len > 16)
 		return -EINVAL;
 
-	cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
-	if (!cmd)
-		return -ENOMEM;
+	tv_nexus = tpg->tpg_nexus;
+	if (!tv_nexus) {
+		pr_err("Missing nexus, ignoring command\n");
+		return -ENODEV;
+	}
 
-	cmd->fu = fu;
+	cmd = usbg_get_cmd(fu, tv_nexus, cbw->Tag);
+	if (IS_ERR(cmd)) {
+		pr_err("usbg_get_cmd failed\n");
+		return -ENOMEM;
+	}
 
 	/* XXX until I figure out why I can't free in on complete */
 	kref_init(&cmd->ref);
 	kref_get(&cmd->ref);
 
-	tpg = fu->tpg;
-
 	memcpy(cmd->cmd_buf, cbw->CDB, cmd_len);
 
 	cmd->bot_tag = cbw->Tag;
-
-	tv_nexus = tpg->tpg_nexus;
-	if (!tv_nexus) {
-		pr_err("Missing nexus, ignoring command\n");
-		goto err;
-	}
-
 	cmd->prio_attr = TCM_SIMPLE_TAG;
 	cmd->unpacked_lun = cbw->Lun;
 	cmd->is_read = cbw->Flags & US_BULK_FLAG_IN ? 1 : 0;
@@ -1239,9 +1256,6 @@ static int bot_submit_command(struct f_uas *fu,
 	queue_work(tpg->workqueue, &cmd->work);
 
 	return 0;
-err:
-	kfree(cmd);
-	return -EINVAL;
 }
 
 /* Start fabric.c code */
@@ -1294,8 +1308,10 @@ static void usbg_release_cmd(struct se_cmd *se_cmd)
 {
 	struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
 			se_cmd);
+	struct se_session *se_sess = se_cmd->se_sess;
+
 	kfree(cmd->data_buf);
-	kfree(cmd);
+	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
 
 static int usbg_shutdown_session(struct se_session *se_sess)
@@ -1597,7 +1613,8 @@ static int tcm_usbg_make_nexus(struct usbg_tpg *tpg, char *name)
 		goto out_unlock;
 	}
 
-	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 0, 0,
+	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 128,
+						     sizeof(struct usbg_cmd),
 						     TARGET_PROT_NORMAL, name,
 						     tv_nexus, NULL);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 10/14] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (8 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 09/14] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 11/14] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger

From: Nicholas Bellinger <nab@linux-iscsi.org>

This patch drops struct usbg_cmd->kref internal kref-erence
usage, for proper TARGET_SCF_ACK_KREF conversion.

Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/usb/gadget/function/f_tcm.c | 51 ++++++++-----------------------------
 1 file changed, 11 insertions(+), 40 deletions(-)

diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c
index 8773572..7276a73 100644
--- a/drivers/usb/gadget/function/f_tcm.c
+++ b/drivers/usb/gadget/function/f_tcm.c
@@ -41,13 +41,6 @@ static inline struct f_uas *to_f_uas(struct usb_function *f)
 	return container_of(f, struct f_uas, function);
 }
 
-static void usbg_cmd_release(struct kref *);
-
-static inline void usbg_cleanup_cmd(struct usbg_cmd *cmd)
-{
-	kref_put(&cmd->ref, usbg_cmd_release);
-}
-
 /* Start bot.c code */
 
 static int bot_enqueue_cmd_cbw(struct f_uas *fu)
@@ -68,7 +61,7 @@ static void bot_status_complete(struct usb_ep *ep, struct usb_request *req)
 	struct usbg_cmd *cmd = req->context;
 	struct f_uas *fu = cmd->fu;
 
-	usbg_cleanup_cmd(cmd);
+	transport_generic_free_cmd(&cmd->se_cmd, 0);
 	if (req->status < 0) {
 		pr_err("ERR %s(%d)\n", __func__, __LINE__);
 		return;
@@ -605,7 +598,7 @@ static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
 		break;
 
 	case UASP_QUEUE_COMMAND:
-		usbg_cleanup_cmd(cmd);
+		transport_generic_free_cmd(&cmd->se_cmd, 0);
 		usb_ep_queue(fu->ep_cmd, fu->cmd.req, GFP_ATOMIC);
 		break;
 
@@ -615,7 +608,7 @@ static void uasp_status_data_cmpl(struct usb_ep *ep, struct usb_request *req)
 	return;
 
 cleanup:
-	usbg_cleanup_cmd(cmd);
+	transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
 static int uasp_send_status_response(struct usbg_cmd *cmd)
@@ -977,7 +970,7 @@ static void usbg_data_write_cmpl(struct usb_ep *ep, struct usb_request *req)
 	return;
 
 cleanup:
-	usbg_cleanup_cmd(cmd);
+	transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
 static int usbg_prepare_w_request(struct usbg_cmd *cmd, struct usb_request *req)
@@ -1046,7 +1039,7 @@ static void usbg_cmd_work(struct work_struct *work)
 	struct se_cmd *se_cmd;
 	struct tcm_usbg_nexus *tv_nexus;
 	struct usbg_tpg *tpg;
-	int dir;
+	int dir, flags = (TARGET_SCF_UNKNOWN_SIZE | TARGET_SCF_ACK_KREF);
 
 	se_cmd = &cmd->se_cmd;
 	tpg = cmd->fu->tpg;
@@ -1060,9 +1053,9 @@ static void usbg_cmd_work(struct work_struct *work)
 		goto out;
 	}
 
-	if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess,
-			cmd->cmd_buf, cmd->sense_iu.sense, cmd->unpacked_lun,
-			0, cmd->prio_attr, dir, TARGET_SCF_UNKNOWN_SIZE) < 0)
+	if (target_submit_cmd(se_cmd, tv_nexus->tvn_se_sess, cmd->cmd_buf,
+			      cmd->sense_iu.sense, cmd->unpacked_lun, 0,
+			      cmd->prio_attr, dir, flags) < 0)
 		goto out;
 
 	return;
@@ -1070,7 +1063,7 @@ static void usbg_cmd_work(struct work_struct *work)
 out:
 	transport_send_check_condition_and_sense(se_cmd,
 			TCM_UNSUPPORTED_SCSI_OPCODE, 1);
-	usbg_cleanup_cmd(cmd);
+	transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
 static struct usbg_cmd *usbg_get_cmd(struct f_uas *fu,
@@ -1125,11 +1118,6 @@ static int usbg_submit_command(struct f_uas *fu,
 		pr_err("usbg_get_cmd failed\n");
 		return -ENOMEM;
 	}
-
-	/* XXX until I figure out why I can't free in on complete */
-	kref_init(&cmd->ref);
-	kref_get(&cmd->ref);
-
 	memcpy(cmd->cmd_buf, cmd_iu->cdb, cmd_len);
 
 	if (fu->flags & USBG_USE_STREAMS) {
@@ -1202,7 +1190,7 @@ static void bot_cmd_work(struct work_struct *work)
 out:
 	transport_send_check_condition_and_sense(se_cmd,
 				TCM_UNSUPPORTED_SCSI_OPCODE, 1);
-	usbg_cleanup_cmd(cmd);
+	transport_generic_free_cmd(&cmd->se_cmd, 0);
 }
 
 static int bot_submit_command(struct f_uas *fu,
@@ -1238,11 +1226,6 @@ static int bot_submit_command(struct f_uas *fu,
 		pr_err("usbg_get_cmd failed\n");
 		return -ENOMEM;
 	}
-
-	/* XXX until I figure out why I can't free in on complete */
-	kref_init(&cmd->ref);
-	kref_get(&cmd->ref);
-
 	memcpy(cmd->cmd_buf, cbw->CDB, cmd_len);
 
 	cmd->bot_tag = cbw->Tag;
@@ -1296,14 +1279,6 @@ static u32 usbg_tpg_get_inst_index(struct se_portal_group *se_tpg)
 	return 1;
 }
 
-static void usbg_cmd_release(struct kref *ref)
-{
-	struct usbg_cmd *cmd = container_of(ref, struct usbg_cmd,
-			ref);
-
-	transport_generic_free_cmd(&cmd->se_cmd, 0);
-}
-
 static void usbg_release_cmd(struct se_cmd *se_cmd)
 {
 	struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
@@ -1733,11 +1708,7 @@ static void usbg_port_unlink(struct se_portal_group *se_tpg,
 
 static int usbg_check_stop_free(struct se_cmd *se_cmd)
 {
-	struct usbg_cmd *cmd = container_of(se_cmd, struct usbg_cmd,
-			se_cmd);
-
-	kref_put(&cmd->ref, usbg_cmd_release);
-	return 1;
+	return target_put_sess_cmd(se_cmd);
 }
 
 static const struct target_core_fabric_ops usbg_ops = {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 11/14] xen-scsiback: Convert to percpu_ida tag allocation
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (9 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 10/14] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, David Vrabel

From: Nicholas Bellinger <nab@linux-iscsi.org>

(Add wrapper for handling pending_req tag failure - Juergen)

Cc: Juergen Gross <jgross@suse.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/xen/xen-scsiback.c | 160 ++++++++++++++++++++++++---------------------
 1 file changed, 86 insertions(+), 74 deletions(-)

diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index a50b6e4..ea3b822 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -190,7 +190,6 @@ module_param_named(max_buffer_pages, scsiback_max_buffer_pages, int, 0644);
 MODULE_PARM_DESC(max_buffer_pages,
 "Maximum number of free pages to keep in backend buffer");
 
-static struct kmem_cache *scsiback_cachep;
 static DEFINE_SPINLOCK(free_pages_lock);
 static int free_pages_num;
 static LIST_HEAD(scsiback_free_pages);
@@ -321,11 +320,11 @@ static void scsiback_free_translation_entry(struct kref *kref)
 	kfree(entry);
 }
 
-static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
-			uint32_t resid, struct vscsibk_pend *pending_req)
+static void scsiback_send_response(struct vscsibk_info *info,
+			char *sense_buffer, int32_t result, uint32_t resid,
+			uint16_t rqid)
 {
 	struct vscsiif_response *ring_res;
-	struct vscsibk_info *info = pending_req->info;
 	int notify;
 	struct scsi_sense_hdr sshdr;
 	unsigned long flags;
@@ -337,7 +336,7 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
 	info->ring.rsp_prod_pvt++;
 
 	ring_res->rslt   = result;
-	ring_res->rqid   = pending_req->rqid;
+	ring_res->rqid   = rqid;
 
 	if (sense_buffer != NULL &&
 	    scsi_normalize_sense(sense_buffer, VSCSIIF_SENSE_BUFFERSIZE,
@@ -357,6 +356,13 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
 
 	if (notify)
 		notify_remote_via_irq(info->irq);
+}
+
+static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
+			uint32_t resid, struct vscsibk_pend *pending_req)
+{
+	scsiback_send_response(pending_req->info, sense_buffer, result,
+			       resid, pending_req->rqid);
 
 	if (pending_req->v2p)
 		kref_put(&pending_req->v2p->kref,
@@ -616,15 +622,13 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
 	err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
 		SUCCESS : FAILED;
 
+	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
+	transport_generic_free_cmd(&pending_req->se_cmd, 1);
+	return;
 out:
-	if (tmr) {
-		transport_generic_free_cmd(&pending_req->se_cmd, 1);
+	if (tmr)
 		kfree(tmr);
-	}
-
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
-
-	kmem_cache_free(scsiback_cachep, pending_req);
 }
 
 /*
@@ -653,15 +657,53 @@ out:
 	return entry;
 }
 
-static int prepare_pending_reqs(struct vscsibk_info *info,
-				struct vscsiif_request *ring_req,
-				struct vscsibk_pend *pending_req)
+static struct vscsibk_pend *scsiback_get_pend_req(struct vscsiif_back_ring *ring,
+				struct v2p_entry *v2p)
+{
+	struct scsiback_tpg *tpg = v2p->tpg;
+	struct scsiback_nexus *nexus = tpg->tpg_nexus;
+	struct se_session *se_sess = nexus->tvn_se_sess;
+	struct vscsibk_pend *req;
+	int tag, i;
+
+	tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
+	if (tag < 0) {
+		pr_err("Unable to obtain tag for vscsiif_request\n");
+		return ERR_PTR(-ENOMEM);
+	}
+
+	req = &((struct vscsibk_pend *)se_sess->sess_cmd_map)[tag];
+	memset(req, 0, sizeof(*req));
+	req->se_cmd.map_tag = tag;
+
+	for (i = 0; i < VSCSI_MAX_GRANTS; i++)
+		req->grant_handles[i] = SCSIBACK_INVALID_HANDLE;
+
+	return req;
+}
+
+static struct vscsibk_pend *prepare_pending_reqs(struct vscsibk_info *info,
+				struct vscsiif_back_ring *ring,
+				struct vscsiif_request *ring_req)
 {
+	struct vscsibk_pend *pending_req;
 	struct v2p_entry *v2p;
 	struct ids_tuple vir;
 
-	pending_req->rqid       = ring_req->rqid;
-	pending_req->info       = info;
+	/* request range check from frontend */
+	if ((ring_req->sc_data_direction != DMA_BIDIRECTIONAL) &&
+		(ring_req->sc_data_direction != DMA_TO_DEVICE) &&
+		(ring_req->sc_data_direction != DMA_FROM_DEVICE) &&
+		(ring_req->sc_data_direction != DMA_NONE)) {
+		pr_debug("invalid parameter data_dir = %d\n",
+			ring_req->sc_data_direction);
+		return ERR_PTR(-EINVAL);
+	}
+	if (ring_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) {
+		pr_debug("invalid parameter cmd_len = %d\n",
+			ring_req->cmd_len);
+		return ERR_PTR(-EINVAL);
+	}
 
 	vir.chn = ring_req->channel;
 	vir.tgt = ring_req->id;
@@ -669,33 +711,24 @@ static int prepare_pending_reqs(struct vscsibk_info *info,
 
 	v2p = scsiback_do_translation(info, &vir);
 	if (!v2p) {
-		pending_req->v2p = NULL;
 		pr_debug("the v2p of (chn:%d, tgt:%d, lun:%d) doesn't exist.\n",
-			vir.chn, vir.tgt, vir.lun);
-		return -ENODEV;
+			 vir.chn, vir.tgt, vir.lun);
+		return ERR_PTR(-ENODEV);
 	}
-	pending_req->v2p = v2p;
 
-	/* request range check from frontend */
-	pending_req->sc_data_direction = ring_req->sc_data_direction;
-	if ((pending_req->sc_data_direction != DMA_BIDIRECTIONAL) &&
-		(pending_req->sc_data_direction != DMA_TO_DEVICE) &&
-		(pending_req->sc_data_direction != DMA_FROM_DEVICE) &&
-		(pending_req->sc_data_direction != DMA_NONE)) {
-		pr_debug("invalid parameter data_dir = %d\n",
-			pending_req->sc_data_direction);
-		return -EINVAL;
+	pending_req = scsiback_get_pend_req(ring, v2p);
+	if (IS_ERR(pending_req)) {
+		kref_put(&v2p->kref, scsiback_free_translation_entry);
+		return ERR_PTR(-ENOMEM);
 	}
-
+	pending_req->rqid = ring_req->rqid;
+	pending_req->info = info;
+	pending_req->v2p = v2p;
+	pending_req->sc_data_direction = ring_req->sc_data_direction;
 	pending_req->cmd_len = ring_req->cmd_len;
-	if (pending_req->cmd_len > VSCSIIF_MAX_COMMAND_SIZE) {
-		pr_debug("invalid parameter cmd_len = %d\n",
-			pending_req->cmd_len);
-		return -EINVAL;
-	}
 	memcpy(pending_req->cmnd, ring_req->cmnd, pending_req->cmd_len);
 
-	return 0;
+	return pending_req;
 }
 
 static int scsiback_do_cmd_fn(struct vscsibk_info *info)
@@ -704,7 +737,7 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 	struct vscsiif_request ring_req;
 	struct vscsibk_pend *pending_req;
 	RING_IDX rc, rp;
-	int err, more_to_do;
+	int more_to_do;
 	uint32_t result;
 
 	rc = ring->req_cons;
@@ -722,16 +755,13 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 	while ((rc != rp)) {
 		if (RING_REQUEST_CONS_OVERFLOW(ring, rc))
 			break;
-		pending_req = kmem_cache_alloc(scsiback_cachep, GFP_KERNEL);
-		if (!pending_req)
-			return 1;
 
 		RING_COPY_REQUEST(ring, rc, &ring_req);
 		ring->req_cons = ++rc;
 
-		err = prepare_pending_reqs(info, &ring_req, pending_req);
-		if (err) {
-			switch (err) {
+		pending_req = prepare_pending_reqs(info, ring, &ring_req);
+		if (IS_ERR(pending_req)) {
+			switch (PTR_ERR(pending_req)) {
 			case -ENODEV:
 				result = DID_NO_CONNECT;
 				break;
@@ -739,9 +769,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 				result = DRIVER_ERROR;
 				break;
 			}
-			scsiback_do_resp_with_sense(NULL, result << 24, 0,
-						    pending_req);
-			kmem_cache_free(scsiback_cachep, pending_req);
+			scsiback_send_response(info, NULL, result << 24, 0,
+					       ring_req.rqid);
 			return 1;
 		}
 
@@ -750,8 +779,8 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 			if (scsiback_gnttab_data_map(&ring_req, pending_req)) {
 				scsiback_fast_flush_area(pending_req);
 				scsiback_do_resp_with_sense(NULL,
-					DRIVER_ERROR << 24, 0, pending_req);
-				kmem_cache_free(scsiback_cachep, pending_req);
+						DRIVER_ERROR << 24, 0, pending_req);
+				transport_generic_free_cmd(&pending_req->se_cmd, 0);
 			} else {
 				scsiback_cmd_exec(pending_req);
 			}
@@ -765,9 +794,9 @@ static int scsiback_do_cmd_fn(struct vscsibk_info *info)
 			break;
 		default:
 			pr_err_ratelimited("invalid request\n");
-			scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24,
-						    0, pending_req);
-			kmem_cache_free(scsiback_cachep, pending_req);
+			scsiback_do_resp_with_sense(NULL, DRIVER_ERROR << 24, 0,
+						    pending_req);
+			transport_generic_free_cmd(&pending_req->se_cmd, 0);
 			break;
 		}
 
@@ -1355,10 +1384,9 @@ static int scsiback_check_stop_free(struct se_cmd *se_cmd)
 
 static void scsiback_release_cmd(struct se_cmd *se_cmd)
 {
-	struct vscsibk_pend *pending_req = container_of(se_cmd,
-				struct vscsibk_pend, se_cmd);
+	struct se_session *se_sess = se_cmd->se_sess;
 
-	kmem_cache_free(scsiback_cachep, pending_req);
+	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
 
 static int scsiback_shutdown_session(struct se_session *se_sess)
@@ -1501,7 +1529,8 @@ static int scsiback_make_nexus(struct scsiback_tpg *tpg,
 		goto out_unlock;
 	}
 
-	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 0, 0,
+	tv_nexus->tvn_se_sess = target_alloc_session(&tpg->se_tpg, 128,
+						     sizeof(struct vscsibk_pend),
 						     TARGET_PROT_NORMAL, name,
 						     tv_nexus, NULL);
 	if (IS_ERR(tv_nexus->tvn_se_sess)) {
@@ -1831,16 +1860,6 @@ static struct xenbus_driver scsiback_driver = {
 	.otherend_changed	= scsiback_frontend_changed
 };
 
-static void scsiback_init_pend(void *p)
-{
-	struct vscsibk_pend *pend = p;
-	int i;
-
-	memset(pend, 0, sizeof(*pend));
-	for (i = 0; i < VSCSI_MAX_GRANTS; i++)
-		pend->grant_handles[i] = SCSIBACK_INVALID_HANDLE;
-}
-
 static int __init scsiback_init(void)
 {
 	int ret;
@@ -1851,14 +1870,9 @@ static int __init scsiback_init(void)
 	pr_debug("xen-pvscsi: fabric module %s on %s/%s on "UTS_RELEASE"\n",
 		 VSCSI_VERSION, utsname()->sysname, utsname()->machine);
 
-	scsiback_cachep = kmem_cache_create("vscsiif_cache",
-		sizeof(struct vscsibk_pend), 0, 0, scsiback_init_pend);
-	if (!scsiback_cachep)
-		return -ENOMEM;
-
 	ret = xenbus_register_backend(&scsiback_driver);
 	if (ret)
-		goto out_cache_destroy;
+		goto out;
 
 	ret = target_register_template(&scsiback_ops);
 	if (ret)
@@ -1868,8 +1882,7 @@ static int __init scsiback_init(void)
 
 out_unregister_xenbus:
 	xenbus_unregister_driver(&scsiback_driver);
-out_cache_destroy:
-	kmem_cache_destroy(scsiback_cachep);
+out:
 	pr_err("%s: error %d\n", __func__, ret);
 	return ret;
 }
@@ -1885,7 +1898,6 @@ static void __exit scsiback_exit(void)
 	}
 	target_unregister_template(&scsiback_ops);
 	xenbus_unregister_driver(&scsiback_driver);
-	kmem_cache_destroy(scsiback_cachep);
 }
 
 module_init(scsiback_init);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (10 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 11/14] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-02-02 16:31   ` Juergen Gross
  2016-01-30  7:05 ` [PATCH-v3 13/14] tcm_fc: Convert to TARGET_SCF_ACK_KREF I/O + TMR krefs Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation Nicholas A. Bellinger
  13 siblings, 1 reply; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, David Vrabel

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Juergen Gross <jgross@suse.com>
Cc: Hannes Reinecke <hare@suse.de>
Cc: David Vrabel <david.vrabel@citrix.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/xen/xen-scsiback.c | 56 +++++++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index ea3b822..eaf9e21 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -386,6 +386,12 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
 	scsiback_fast_flush_area(pending_req);
 	scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
 	scsiback_put(info);
+	/*
+	 * Drop the extra KREF_ACK reference taken by target_submit_cmd_map_sgls()
+	 * ahead of scsiback_check_stop_free() ->  transport_generic_free_cmd()
+	 * final se_cmd->cmd_kref put.
+	 */
+	target_put_sess_cmd(&pending_req->se_cmd);
 }
 
 static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
@@ -403,7 +409,7 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
 	rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd,
 			pending_req->sense_buffer, pending_req->v2p->lun,
 			pending_req->data_len, 0,
-			pending_req->sc_data_direction, 0,
+			pending_req->sc_data_direction, TARGET_SCF_ACK_KREF,
 			pending_req->sgl, pending_req->n_sg,
 			NULL, 0, NULL, 0);
 	if (rc < 0) {
@@ -592,31 +598,28 @@ static void scsiback_disconnect(struct vscsibk_info *info)
 static void scsiback_device_action(struct vscsibk_pend *pending_req,
 	enum tcm_tmreq_table act, int tag)
 {
-	int rc, err = FAILED;
 	struct scsiback_tpg *tpg = pending_req->v2p->tpg;
+	struct scsiback_nexus *nexus = tpg->tpg_nexus;
 	struct se_cmd *se_cmd = &pending_req->se_cmd;
 	struct scsiback_tmr *tmr;
+	u64 unpacked_lun = pending_req->v2p->lun;
+	int rc, err = FAILED;
 
 	tmr = kzalloc(sizeof(struct scsiback_tmr), GFP_KERNEL);
-	if (!tmr)
-		goto out;
+	if (!tmr) {
+		target_put_sess_cmd(se_cmd);
+		goto err;
+	}
 
 	init_waitqueue_head(&tmr->tmr_wait);
 
-	transport_init_se_cmd(se_cmd, tpg->se_tpg.se_tpg_tfo,
-		tpg->tpg_nexus->tvn_se_sess, 0, DMA_NONE, TCM_SIMPLE_TAG,
-		&pending_req->sense_buffer[0]);
-
-	rc = core_tmr_alloc_req(se_cmd, tmr, act, GFP_KERNEL);
-	if (rc < 0)
-		goto out;
-
-	se_cmd->se_tmr_req->ref_task_tag = tag;
-
-	if (transport_lookup_tmr_lun(se_cmd, pending_req->v2p->lun) < 0)
-		goto out;
+	rc = target_submit_tmr(&pending_req->se_cmd, nexus->tvn_se_sess,
+			       &pending_req->sense_buffer[0],
+			       unpacked_lun, tmr, act, GFP_KERNEL,
+			       tag, TARGET_SCF_ACK_KREF);
+	if (rc)
+		goto err;
 
-	transport_generic_handle_tmr(se_cmd);
 	wait_event(tmr->tmr_wait, atomic_read(&tmr->tmr_complete));
 
 	err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
@@ -625,7 +628,7 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
 	transport_generic_free_cmd(&pending_req->se_cmd, 1);
 	return;
-out:
+err:
 	if (tmr)
 		kfree(tmr);
 	scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
@@ -1370,21 +1373,18 @@ static u32 scsiback_tpg_get_inst_index(struct se_portal_group *se_tpg)
 
 static int scsiback_check_stop_free(struct se_cmd *se_cmd)
 {
-	/*
-	 * Do not release struct se_cmd's containing a valid TMR pointer.
-	 * These will be released directly in scsiback_device_action()
-	 * with transport_generic_free_cmd().
-	 */
-	if (se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
-		return 0;
-
-	transport_generic_free_cmd(se_cmd, 0);
-	return 1;
+	return transport_generic_free_cmd(se_cmd, 0);
 }
 
 static void scsiback_release_cmd(struct se_cmd *se_cmd)
 {
 	struct se_session *se_sess = se_cmd->se_sess;
+	struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
+
+	if (se_tmr && se_cmd->se_cmd_flags & SCF_SCSI_TMR_CDB) {
+		struct scsiback_tmr *tmr = se_tmr->fabric_tmr_ptr;
+		kfree(tmr);
+	}
 
 	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 13/14] tcm_fc: Convert to TARGET_SCF_ACK_KREF I/O + TMR krefs
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (11 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-01-30  7:05 ` [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation Nicholas A. Bellinger
  13 siblings, 0 replies; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vasu Dev

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Vasu Dev <vasu.dev@linux.intel.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/tcm_fc/tfc_cmd.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
index 064d6df..768aec3 100644
--- a/drivers/target/tcm_fc/tfc_cmd.c
+++ b/drivers/target/tcm_fc/tfc_cmd.c
@@ -107,8 +107,7 @@ void ft_release_cmd(struct se_cmd *se_cmd)
 
 int ft_check_stop_free(struct se_cmd *se_cmd)
 {
-	transport_generic_free_cmd(se_cmd, 0);
-	return 1;
+	return transport_generic_free_cmd(se_cmd, 0);
 }
 
 /*
@@ -179,6 +178,12 @@ int ft_queue_status(struct se_cmd *se_cmd)
 		return -ENOMEM;
 	}
 	lport->tt.exch_done(cmd->seq);
+	/*
+	 * Drop the extra ACK_KREF reference taken by target_submit_cmd()
+	 * ahead of ft_check_stop_free() -> transport_generic_free_cmd()
+	 * final se_cmd->cmd_kref put.
+	 */
+	target_put_sess_cmd(&cmd->se_cmd);
 	return 0;
 }
 
@@ -422,6 +427,12 @@ void ft_queue_tm_resp(struct se_cmd *se_cmd)
 	pr_debug("tmr fn %d resp %d fcp code %d\n",
 		  tmr->function, tmr->response, code);
 	ft_send_resp_code(cmd, code);
+	/*
+	 * Drop the extra ACK_KREF reference taken by target_submit_tmr()
+	 * ahead of ft_check_stop_free() -> transport_generic_free_cmd()
+	 * final se_cmd->cmd_kref put.
+	 */
+	target_put_sess_cmd(&cmd->se_cmd);
 }
 
 void ft_aborted_task(struct se_cmd *se_cmd)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation
  2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
                   ` (12 preceding siblings ...)
  2016-01-30  7:05 ` [PATCH-v3 13/14] tcm_fc: Convert to TARGET_SCF_ACK_KREF I/O + TMR krefs Nicholas A. Bellinger
@ 2016-01-30  7:05 ` Nicholas A. Bellinger
  2016-02-04 22:23   ` Bart Van Assche
  13 siblings, 1 reply; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-30  7:05 UTC (permalink / raw)
  To: target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vu Pham, Bart Van Assche

From: Nicholas Bellinger <nab@linux-iscsi.org>

Cc: Vu Pham <vu@mellanox.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/infiniband/ulp/srpt/ib_srpt.c | 55 +++++++++++------------------------
 drivers/infiniband/ulp/srpt/ib_srpt.h |  2 --
 2 files changed, 17 insertions(+), 40 deletions(-)

diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 72a671e..b0707a7 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -1261,40 +1261,26 @@ free_mem:
  */
 static struct srpt_send_ioctx *srpt_get_send_ioctx(struct srpt_rdma_ch *ch)
 {
+	struct se_session *se_sess;
 	struct srpt_send_ioctx *ioctx;
-	unsigned long flags;
+	int tag;
 
 	BUG_ON(!ch);
+	se_sess = ch->sess;
 
-	ioctx = NULL;
-	spin_lock_irqsave(&ch->spinlock, flags);
-	if (!list_empty(&ch->free_list)) {
-		ioctx = list_first_entry(&ch->free_list,
-					 struct srpt_send_ioctx, free_list);
-		list_del(&ioctx->free_list);
+	tag = percpu_ida_alloc(&se_sess->sess_tag_pool, TASK_RUNNING);
+	if (tag < 0) {
+		pr_err("Unable to obtain tag for srpt_send_ioctx\n");
+		return NULL;
 	}
-	spin_unlock_irqrestore(&ch->spinlock, flags);
-
-	if (!ioctx)
-		return ioctx;
-
-	BUG_ON(ioctx->ch != ch);
+	ioctx = &((struct srpt_send_ioctx *)se_sess->sess_cmd_map)[tag];
+	memset(ioctx, 0, sizeof(struct srpt_send_ioctx));
+	ioctx->ch = ch;
 	spin_lock_init(&ioctx->spinlock);
 	ioctx->state = SRPT_STATE_NEW;
-	ioctx->n_rbuf = 0;
-	ioctx->rbufs = NULL;
-	ioctx->n_rdma = 0;
-	ioctx->n_rdma_wrs = 0;
-	ioctx->rdma_wrs = NULL;
-	ioctx->mapped_sg_count = 0;
 	init_completion(&ioctx->tx_done);
-	ioctx->queue_status_only = false;
-	/*
-	 * transport_init_se_cmd() does not initialize all fields, so do it
-	 * here.
-	 */
-	memset(&ioctx->cmd, 0, sizeof(ioctx->cmd));
-	memset(&ioctx->sense_data, 0, sizeof(ioctx->sense_data));
+
+	ioctx->cmd.map_tag = tag;
 
 	return ioctx;
 }
@@ -2241,7 +2227,7 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 	struct ib_cm_rep_param *rep_param;
 	struct srpt_rdma_ch *ch, *tmp_ch;
 	u32 it_iu_len;
-	int i, ret = 0;
+	int ret = 0;
 	unsigned char *p;
 
 	WARN_ON_ONCE(irqs_disabled());
@@ -2370,12 +2356,6 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 	if (!ch->ioctx_ring)
 		goto free_ch;
 
-	INIT_LIST_HEAD(&ch->free_list);
-	for (i = 0; i < ch->rq_size; i++) {
-		ch->ioctx_ring[i]->ch = ch;
-		list_add_tail(&ch->ioctx_ring[i]->free_list, &ch->free_list);
-	}
-
 	ret = srpt_create_ch_ib(ch);
 	if (ret) {
 		rej->reason = cpu_to_be32(
@@ -2406,7 +2386,8 @@ static int srpt_cm_req_recv(struct ib_cm_id *cm_id,
 	p = &ch->sess_name[0];
 
 try_again:
-	ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
+	ch->sess = target_alloc_session(&sport->port_tpg_1, ch->rq_size,
+					sizeof(struct srpt_send_ioctx),
 					TARGET_PROT_NORMAL, p, ch, NULL);
 	if (IS_ERR(ch->sess)) {
 		pr_info("Rejected login because no ACL has been"
@@ -3194,7 +3175,7 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
 	struct srpt_send_ioctx *ioctx = container_of(se_cmd,
 				struct srpt_send_ioctx, cmd);
 	struct srpt_rdma_ch *ch = ioctx->ch;
-	unsigned long flags;
+	struct se_session *se_sess = ch->sess;
 
 	WARN_ON(ioctx->state != SRPT_STATE_DONE);
 	WARN_ON(ioctx->mapped_sg_count != 0);
@@ -3205,9 +3186,7 @@ static void srpt_release_cmd(struct se_cmd *se_cmd)
 		ioctx->n_rbuf = 0;
 	}
 
-	spin_lock_irqsave(&ch->spinlock, flags);
-	list_add(&ioctx->free_list, &ch->free_list);
-	spin_unlock_irqrestore(&ch->spinlock, flags);
+	percpu_ida_free(&se_sess->sess_tag_pool, se_cmd->map_tag);
 }
 
 /**
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.h b/drivers/infiniband/ulp/srpt/ib_srpt.h
index 09037f2..6fbb6e7 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.h
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.h
@@ -179,7 +179,6 @@ struct srpt_recv_ioctx {
  * struct srpt_send_ioctx - SRPT send I/O context.
  * @ioctx:       See above.
  * @ch:          Channel pointer.
- * @free_list:   Node in srpt_rdma_ch.free_list.
  * @n_rbuf:      Number of data buffers in the received SRP command.
  * @rbufs:       Pointer to SRP data buffer array.
  * @single_rbuf: SRP data buffer if the command has only a single buffer.
@@ -202,7 +201,6 @@ struct srpt_send_ioctx {
 	struct srp_direct_buf	*rbufs;
 	struct srp_direct_buf	single_rbuf;
 	struct scatterlist	*sg;
-	struct list_head	free_list;
 	spinlock_t		spinlock;
 	enum srpt_command_state	state;
 	struct se_cmd		cmd;
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-01-30  7:05 ` [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-02-02 16:31   ` Juergen Gross
  2016-02-03  5:03     ` Nicholas A. Bellinger
  0 siblings, 1 reply; 20+ messages in thread
From: Juergen Gross @ 2016-02-02 16:31 UTC (permalink / raw)
  To: Nicholas A. Bellinger, target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Andrzej Pietrasiewicz, Chris Boot, Nicholas Bellinger,
	David Vrabel

[-- Attachment #1: Type: text/plain, Size: 599 bytes --]

On 30/01/16 08:05, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <nab@linux-iscsi.org>
> 
> Cc: Juergen Gross <jgross@suse.com>
> Cc: Hannes Reinecke <hare@suse.de>
> Cc: David Vrabel <david.vrabel@citrix.com>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

Sorry, with your patches applied xen-scsiback isn't working any more.
I've tried multiple times with and without your patches. Without the
patches everything is fine, while with the patches applied I get the
warnings shown in the attached log. I just passed through a DVD drive
and did "eject" in the domain.


Juergen


[-- Attachment #2: dom0.log --]
[-- Type: text/plain, Size: 6394 bytes --]

[10984.266570] ------------[ cut here ]------------
[10984.266597] WARNING: CPU: 0 PID: 0 at drivers/target/target_core_transport.c:717 target_complete_cmd+0x1cb/0x200 [target_core_mod]()
[10984.266601] Modules linked in: xt_physdev br_netfilter iptable_filter ip_tables x_tables loop target_core_pscsi target_core_file target_core_iblock iscsi_target_mod tcm_loop xen_scsiback bridge stp llc iscsi_ibft iscsi_boot_sysfs tun arc4 iwldvm mac80211 joydev iwlwifi uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core snd_hda_codec_realtek cfg80211 snd_hda_codec_hdmi snd_hda_codec_generic videodev intel_rapl x86_pkg_temp_thermal e1000e intel_powerclamp snd_hda_intel media snd_hda_codec coretemp crct10dif_pclmul iTCO_wdt snd_hda_core crc32_pclmul iTCO_vendor_support dell_laptop crc32c_intel sdhci_pci rfkill ghash_clmulni_intel ptp snd_hwdep hmac i2c_hid drbg snd_pcm ansi_cprng hid dell_wmi ppdev snd_timer sparse_keymap dcdbas dell_smm_hwmon parport_pc parport snd 
 i2c_designware_platform
[10984.266670]  i2c_designware_core thermal tpm_tis xhci_pci tpm evdev mei_me xhci_hcd aesni_intel mei aes_x86_64 psmouse shpchp lrw lpc_ich gf128mul i2c_i801 soundcore mfd_core pps_core ac glue_helper ablk_helper battery serio_raw pcspkr cryptd wmi target_core_mod xenfs xen_privcmd configfs dm_mod ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom i915 ehci_pci ehci_hcd i2c_algo_bit drm_kms_helper ahci libahci libata usbcore usb_common drm sdhci_acpi video sdhci mmc_core button xen_acpi_processor xen_pciback xen_netback xen_blkback xen_gntalloc xen_gntdev xen_evtchn sg scsi_mod autofs4
[10984.266735] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W       4.5.0-rc1-pv+ #1
[10984.266739] Hardware name: Dell Inc. Latitude E6440/0159N7, BIOS A07 06/26/2014
[10984.266742]  ffffffffa0422408 ffffffff812e8bb4 0000000000000000 ffffffff8106e95c
[10984.266748]  ffff8800d2e007d0 ffff8800d2e008e0 0000000000000001 ffffffffa08c3150
[10984.266753]  0000000000000000 ffffffffa04091ab ffff8800da13ea20 ffff88000294f7c0
[10984.266758] Call Trace:
[10984.266761]  <IRQ>  [<ffffffff812e8bb4>] ? dump_stack+0x40/0x5c
[10984.266776]  [<ffffffff8106e95c>] ? warn_slowpath_common+0x7c/0xb0
[10984.266784]  [<ffffffffa08c3150>] ? pscsi_bi_endio+0x10/0x10 [target_core_pscsi]
[10984.266794]  [<ffffffffa04091ab>] ? target_complete_cmd+0x1cb/0x200 [target_core_mod]
[10984.266799]  [<ffffffffa08c30f5>] ? pscsi_req_done+0x85/0xd0 [target_core_pscsi]
[10984.266811]  [<ffffffffa00125c7>] ? scsi_end_request+0xf7/0x1a0 [scsi_mod]
[10984.266820]  [<ffffffffa001481a>] ? scsi_io_completion+0xfa/0x5f0 [scsi_mod]
[10984.266830]  [<ffffffff812c4833>] ? blk_done_softirq+0x73/0x90
[10984.266836]  [<ffffffff81072b5c>] ? __do_softirq+0xcc/0x240
[10984.266842]  [<ffffffff81072eb6>] ? irq_exit+0x86/0x90
[10984.266852]  [<ffffffff8139c8bc>] ? xen_evtchn_do_upcall+0x2c/0x40
[10984.266862]  [<ffffffff8158772e>] ? xen_do_hypervisor_callback+0x1e/0x40
[10984.266864]  <EOI>  [<ffffffff810013aa>] ? xen_hypercall_sched_op+0xa/0x20
[10984.266874]  [<ffffffff810013aa>] ? xen_hypercall_sched_op+0xa/0x20
[10984.266882]  [<ffffffff8100afdc>] ? xen_safe_halt+0xc/0x20
[10984.266891]  [<ffffffff8101edd3>] ? default_idle+0x13/0x90
[10984.266898]  [<ffffffff810a92fd>] ? cpu_startup_entry+0x25d/0x2f0
[10984.266903]  [<ffffffff8190a06a>] ? start_kernel+0x471/0x47c
[10984.266907]  [<ffffffff81909a00>] ? set_init_arg+0x50/0x50
[10984.266912]  [<ffffffff8190c324>] ? xen_start_kernel+0x522/0x52c
[10984.266916] ---[ end trace 07ad307d0cb62aa4 ]---

[10984.266940] ------------[ cut here ]------------
[10984.266953] WARNING: CPU: 0 PID: 2448 at drivers/target/target_core_transport.c:2120 target_complete_ok_work+0x291/0x2e0 [target_core_mod]()
[10984.266955] Modules linked in: xt_physdev br_netfilter iptable_filter ip_tables x_tables loop target_core_pscsi target_core_file target_core_iblock iscsi_target_mod tcm_loop xen_scsiback bridge stp llc iscsi_ibft iscsi_boot_sysfs tun arc4 iwldvm mac80211 joydev iwlwifi uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core snd_hda_codec_realtek cfg80211 snd_hda_codec_hdmi snd_hda_codec_generic videodev intel_rapl x86_pkg_temp_thermal e1000e intel_powerclamp snd_hda_intel media snd_hda_codec coretemp crct10dif_pclmul iTCO_wdt snd_hda_core crc32_pclmul iTCO_vendor_support dell_laptop crc32c_intel sdhci_pci rfkill ghash_clmulni_intel ptp snd_hwdep hmac i2c_hid drbg snd_pcm ansi_cprng hid dell_wmi ppdev snd_timer sparse_keymap dcdbas dell_smm_hwmon parport_pc parport snd 
 i2c_designware_platform
[10984.267013]  i2c_designware_core thermal tpm_tis xhci_pci tpm evdev mei_me xhci_hcd aesni_intel mei aes_x86_64 psmouse shpchp lrw lpc_ich gf128mul i2c_i801 soundcore mfd_core pps_core ac glue_helper ablk_helper battery serio_raw pcspkr cryptd wmi target_core_mod xenfs xen_privcmd configfs dm_mod ext4 crc16 mbcache jbd2 sd_mod sr_mod cdrom i915 ehci_pci ehci_hcd i2c_algo_bit drm_kms_helper ahci libahci libata usbcore usb_common drm sdhci_acpi video sdhci mmc_core button xen_acpi_processor xen_pciback xen_netback xen_blkback xen_gntalloc xen_gntdev xen_evtchn sg scsi_mod autofs4
[10984.267067] CPU: 0 PID: 2448 Comm: kworker/0:0 Tainted: G        W       4.5.0-rc1-pv+ #1
[10984.267070] Hardware name: Dell Inc. Latitude E6440/0159N7, BIOS A07 06/26/2014
[10984.267081] Workqueue: target_completion target_complete_ok_work [target_core_mod]
[10984.267084]  ffffffffa0422408 ffffffff812e8bb4 0000000000000000 ffffffff8106e95c
[10984.267089]  ffff8800d2e00908 ffff8800d2e007d0 0000000000000903 ffffe8ffffc0af00
[10984.267094]  0000000000000000 ffffffffa040c831 0000000000000000 ffff8800d2e00908
[10984.267099] Call Trace:
[10984.267103]  [<ffffffff812e8bb4>] ? dump_stack+0x40/0x5c
[10984.267108]  [<ffffffff8106e95c>] ? warn_slowpath_common+0x7c/0xb0
[10984.267117]  [<ffffffffa040c831>] ? target_complete_ok_work+0x291/0x2e0 [target_core_mod]
[10984.267124]  [<ffffffff81084709>] ? process_one_work+0x149/0x3b0
[10984.267128]  [<ffffffff81084dcd>] ? worker_thread+0x11d/0x4a0
[10984.267133]  [<ffffffff81084cb0>] ? rescuer_thread+0x340/0x340
[10984.267140]  [<ffffffff8108a068>] ? kthread+0xb8/0xd0
[10984.267146]  [<ffffffff81089fb0>] ? kthread_park+0x50/0x50
[10984.267152]  [<ffffffff81585d4f>] ? ret_from_fork+0x3f/0x70
[10984.267158]  [<ffffffff81089fb0>] ? kthread_park+0x50/0x50
[10984.267161] ---[ end trace 07ad307d0cb62aa5 ]---


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-02-02 16:31   ` Juergen Gross
@ 2016-02-03  5:03     ` Nicholas A. Bellinger
  2016-02-04  8:22       ` Juergen Gross
  0 siblings, 1 reply; 20+ messages in thread
From: Nicholas A. Bellinger @ 2016-02-03  5:03 UTC (permalink / raw)
  To: Juergen Gross
  Cc: Nicholas A. Bellinger, target-devel, linux-scsi,
	Christoph Hellwig, Hannes Reinecke, Mike Christie, Sagi Grimberg,
	Andy Grover, Sebastian Andrzej Siewior, Andrzej Pietrasiewicz,
	Chris Boot, David Vrabel

Hi Juergen,

On Tue, 2016-02-02 at 17:31 +0100, Juergen Gross wrote:
> On 30/01/16 08:05, Nicholas A. Bellinger wrote:
> > From: Nicholas Bellinger <nab@linux-iscsi.org>
> > 
> > Cc: Juergen Gross <jgross@suse.com>
> > Cc: Hannes Reinecke <hare@suse.de>
> > Cc: David Vrabel <david.vrabel@citrix.com>
> > Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
> 
> Sorry, with your patches applied xen-scsiback isn't working any more.
> I've tried multiple times with and without your patches. Without the
> patches everything is fine, while with the patches applied I get the
> warnings shown in the attached log. I just passed through a DVD drive
> and did "eject" in the domain.
> 

Thanks for testing.  :)

So it looks like a left-over memset of pending_req->se_cmd memory in
scsiback_cmd_exec() was clobbering the saved percpu_ida map_tag from
scsiback_get_pend_req(), resulting in a use-after-free.

Please verify with the following:

diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index eaf9e21..c3f55a2 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -400,10 +400,6 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
        struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess;
        int rc;
 
-       memset(pending_req->sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE);
-
-       memset(se_cmd, 0, sizeof(*se_cmd));
-
        scsiback_get(pending_req->info);
        se_cmd->tag = pending_req->rqid;
        rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd,

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
  2016-02-03  5:03     ` Nicholas A. Bellinger
@ 2016-02-04  8:22       ` Juergen Gross
  0 siblings, 0 replies; 20+ messages in thread
From: Juergen Gross @ 2016-02-04  8:22 UTC (permalink / raw)
  To: Nicholas A. Bellinger
  Cc: Nicholas A. Bellinger, target-devel, linux-scsi,
	Christoph Hellwig, Hannes Reinecke, Mike Christie, Sagi Grimberg,
	Andy Grover, Sebastian Andrzej Siewior, Andrzej Pietrasiewicz,
	Chris Boot, David Vrabel

On 03/02/16 06:03, Nicholas A. Bellinger wrote:
> Hi Juergen,
> 
> On Tue, 2016-02-02 at 17:31 +0100, Juergen Gross wrote:
>> On 30/01/16 08:05, Nicholas A. Bellinger wrote:
>>> From: Nicholas Bellinger <nab@linux-iscsi.org>
>>>
>>> Cc: Juergen Gross <jgross@suse.com>
>>> Cc: Hannes Reinecke <hare@suse.de>
>>> Cc: David Vrabel <david.vrabel@citrix.com>
>>> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
>>
>> Sorry, with your patches applied xen-scsiback isn't working any more.
>> I've tried multiple times with and without your patches. Without the
>> patches everything is fine, while with the patches applied I get the
>> warnings shown in the attached log. I just passed through a DVD drive
>> and did "eject" in the domain.
>>
> 
> Thanks for testing.  :)

You're welcome. :-)

> 
> So it looks like a left-over memset of pending_req->se_cmd memory in
> scsiback_cmd_exec() was clobbering the saved percpu_ida map_tag from
> scsiback_get_pend_req(), resulting in a use-after-free.
> 
> Please verify with the following:

Thanks, is working now!

With that change you can add my:

Acked-by: Juergen Gross <jgross@suse.com>
Tested-by: Juergen Gross <jgross@suse.com>

to the xen-scsiback related patches.


Juergen

> 
> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> index eaf9e21..c3f55a2 100644
> --- a/drivers/xen/xen-scsiback.c
> +++ b/drivers/xen/xen-scsiback.c
> @@ -400,10 +400,6 @@ static void scsiback_cmd_exec(struct vscsibk_pend *pending_req)
>         struct se_session *sess = pending_req->v2p->tpg->tpg_nexus->tvn_se_sess;
>         int rc;
>  
> -       memset(pending_req->sense_buffer, 0, VSCSIIF_SENSE_BUFFERSIZE);
> -
> -       memset(se_cmd, 0, sizeof(*se_cmd));
> -
>         scsiback_get(pending_req->info);
>         se_cmd->tag = pending_req->rqid;
>         rc = target_submit_cmd_map_sgls(se_cmd, sess, pending_req->cmnd,
> 
> 
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH-v3 06/14] ib_srpt: Convert to target_alloc_session usage
  2016-01-30  7:05 ` [PATCH-v3 06/14] ib_srpt: " Nicholas A. Bellinger
@ 2016-02-04 22:14   ` Bart Van Assche
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Van Assche @ 2016-02-04 22:14 UTC (permalink / raw)
  To: Nicholas A. Bellinger, target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vu Pham

On 01/29/2016 11:05 PM, Nicholas A. Bellinger wrote:
>   try_again:
> -	se_acl = core_tpg_get_initiator_node_acl(&sport->port_tpg_1, p);
> -	if (!se_acl) {
> +	ch->sess = target_alloc_session(&sport->port_tpg_1, 0, 0,
> +					TARGET_PROT_NORMAL, p, ch, NULL);
> +	if (IS_ERR(ch->sess)) {
>   		pr_info("Rejected login because no ACL has been"
> -			" configured yet for initiator %s.\n", ch->sess_name);
> +			" configured yet for initiator %s.\n", p);
>   		/*
>   		 * XXX: Hack to retry of ch->i_port_id without leading '0x'
>   		 */
> @@ -2426,14 +2418,11 @@ try_again:
>   			p += 2;
>   			goto try_again;
>   		}
> -		rej->reason = cpu_to_be32(
> +		rej->reason = cpu_to_be32((PTR_ERR(ch->sess) == -ENOMEM) ?
> +				SRP_LOGIN_REJ_INSUFFICIENT_RESOURCES :
>   				SRP_LOGIN_REJ_CHANNEL_LIMIT_REACHED);

Hello Nic,

The "no ACL has been configured yet" error message will be printed for 
initator ACLs that do not start with "0x" even if the second lookup 
succeeds. This will confuse users. Otherwise this patch looks fine to me.

Bart.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation
  2016-01-30  7:05 ` [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation Nicholas A. Bellinger
@ 2016-02-04 22:23   ` Bart Van Assche
  0 siblings, 0 replies; 20+ messages in thread
From: Bart Van Assche @ 2016-02-04 22:23 UTC (permalink / raw)
  To: Nicholas A. Bellinger, target-devel
  Cc: linux-scsi, Christoph Hellwig, Hannes Reinecke, Mike Christie,
	Sagi Grimberg, Andy Grover, Sebastian Andrzej Siewior,
	Juergen Gross, Andrzej Pietrasiewicz, Chris Boot,
	Nicholas Bellinger, Vu Pham

On 01/29/2016 11:05 PM, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <nab@linux-iscsi.org>
>
> Cc: Vu Pham <vu@mellanox.com>
> Cc: Sagi Grimberg <sagig@mellanox.com>
> Cc: Bart Van Assche <bvanassche@acm.org>
> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

Hello Nic,

A patch description should not only explain what has been changed but 
also why that change is considered useful. That last part is missing 
from the description of this patch. Is the purpose of this patch perhaps 
to improve performance ? If so then you should provide measurement data 
that shows that this patch really improves performance. Personally I 
doubt this patch improves performance because in the ib_srpt driver all 
ioctx allocations happen on the same CPU core, namely the CPU core the 
completion interrupt has been assigned to.

Bart.

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2016-02-04 22:24 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-30  7:05 [PATCH-v3 00/14] target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 01/14] target: Add target_alloc_session() helper function Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 02/14] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 03/14] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 04/14] tcm_qla2xxx: " Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 05/14] tcm_fc: " Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 06/14] ib_srpt: " Nicholas A. Bellinger
2016-02-04 22:14   ` Bart Van Assche
2016-01-30  7:05 ` [PATCH-v3 07/14] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 08/14] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 09/14] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 10/14] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 11/14] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 12/14] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-02-02 16:31   ` Juergen Gross
2016-02-03  5:03     ` Nicholas A. Bellinger
2016-02-04  8:22       ` Juergen Gross
2016-01-30  7:05 ` [PATCH-v3 13/14] tcm_fc: Convert to TARGET_SCF_ACK_KREF I/O + TMR krefs Nicholas A. Bellinger
2016-01-30  7:05 ` [PATCH-v3 14/14] ib_srpt: Convert to percpu_ida tag allocation Nicholas A. Bellinger
2016-02-04 22:23   ` Bart Van Assche

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.