* [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion
@ 2016-01-25 8:10 Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 01/12] target: Add target_alloc_session() helper function Nicholas A. Bellinger
` (11 more replies)
0 siblings, 12 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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 folks,
Here is -v2 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
to complete ahead of transport_register_session() finishing
I_T nexus setup.
This includes a tree-wide fabric driver conversion to use
use target_alloc_session() + associated (*callback)() with
common code.
Also as per HCH, it contains sbp-target, usb-gadget/tcm
and xen-scsiback driver percpu_ida tag pre-allocation
conversions, along with initial TARGET_SCF_ACK_KREF
support for v4.6-rc code.
Please review.
--nab
Christoph Hellwig (1):
target: Convert demo-mode only drivers to target_alloc_session
Nicholas Bellinger (11):
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
drivers/infiniband/ulp/srpt/ib_srpt.c | 23 +--
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_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 +
12 files changed, 437 insertions(+), 458 deletions(-)
--
1.9.1
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH-v2 01/12] target: Add target_alloc_session() helper function
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
@ 2016-01-25 8:10 ` Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
` (10 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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 6235067..5609f91 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] 22+ messages in thread
* [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 01/12] target: Add target_alloc_session() helper function Nicholas A. Bellinger
@ 2016-01-25 8:10 ` Nicholas A. Bellinger
2016-01-26 9:45 ` Juergen Gross
2016-01-25 8:10 ` [PATCH-v2 03/12] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
` (9 subsequent siblings)
11 siblings, 1 reply; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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>
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>
Cc: Juergen Gross <jgross@suse.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 43bcae8..594f8a7 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] 22+ messages in thread
* [PATCH-v2 03/12] vhost/scsi: Convert to target_alloc_session usage
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 01/12] target: Add target_alloc_session() helper function Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
@ 2016-01-25 8:10 ` Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 04/12] tcm_qla2xxx: " Nicholas A. Bellinger
` (8 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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] 22+ messages in thread
* [PATCH-v2 04/12] tcm_qla2xxx: Convert to target_alloc_session usage
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (2 preceding siblings ...)
2016-01-25 8:10 ` [PATCH-v2 03/12] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
@ 2016-01-25 8:10 ` Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 05/12] tcm_fc: " Nicholas A. Bellinger
` (7 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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 2c71305..a2da314 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 b44f397..bf73c6f 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] 22+ messages in thread
* [PATCH-v2 05/12] tcm_fc: Convert to target_alloc_session usage
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (3 preceding siblings ...)
2016-01-25 8:10 ` [PATCH-v2 04/12] tcm_qla2xxx: " Nicholas A. Bellinger
@ 2016-01-25 8:10 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 06/12] ib_srpt: " Nicholas A. Bellinger
` (6 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:10 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] 22+ messages in thread
* [PATCH-v2 06/12] ib_srpt: Convert to target_alloc_session usage
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (4 preceding siblings ...)
2016-01-25 8:10 ` [PATCH-v2 05/12] tcm_fc: " Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 07/12] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
` (5 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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 bc5470c..5a35c1f 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -2387,7 +2387,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;
@@ -2553,19 +2552,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'
*/
@@ -2573,14 +2565,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] 22+ messages in thread
* [PATCH-v2 07/12] sbp-target: Conversion to percpu_ida tag pre-allocation
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (5 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 06/12] ib_srpt: " Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 08/12] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
` (4 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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] 22+ messages in thread
* [PATCH-v2 08/12] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (6 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 07/12] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 09/12] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
` (3 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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] 22+ messages in thread
* [PATCH-v2 09/12] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (7 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 08/12] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 10/12] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
` (2 subsequent siblings)
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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] 22+ messages in thread
* [PATCH-v2 10/12] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (8 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 09/12] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
11 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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] 22+ messages in thread
* [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (9 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 10/12] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-25 15:42 ` Juergen Gross
2016-01-26 9:45 ` Juergen Gross
2016-01-25 8:11 ` [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
11 siblings, 2 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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 | 163 ++++++++++++++++++++++++---------------------
1 file changed, 87 insertions(+), 76 deletions(-)
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 594f8a7..640fb22 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);
@@ -322,7 +321,8 @@ static void scsiback_free_translation_entry(struct kref *kref)
}
static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
- uint32_t resid, struct vscsibk_pend *pending_req)
+ uint32_t resid, struct vscsibk_pend *pending_req,
+ uint16_t rqid)
{
struct vscsiif_response *ring_res;
struct vscsibk_info *info = pending_req->info;
@@ -337,7 +337,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,
@@ -358,7 +358,7 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
if (notify)
notify_remote_via_irq(info->irq);
- if (pending_req->v2p)
+ if (pending_req && pending_req->v2p)
kref_put(&pending_req->v2p->kref,
scsiback_free_translation_entry);
}
@@ -378,7 +378,8 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
scsiback_print_status(sense_buffer, errors, pending_req);
scsiback_fast_flush_area(pending_req);
- scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
+ scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req,
+ pending_req->rqid);
scsiback_put(info);
}
@@ -616,15 +617,15 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
SUCCESS : FAILED;
-out:
- if (tmr) {
- transport_generic_free_cmd(&pending_req->se_cmd, 1);
+ scsiback_do_resp_with_sense(NULL, err, 0, pending_req,
+ pending_req->rqid);
+ transport_generic_free_cmd(&pending_req->se_cmd, 1);
+ return;
+err:
+ if (tmr)
kfree(tmr);
- }
-
- scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
-
- kmem_cache_free(scsiback_cachep, pending_req);
+ scsiback_do_resp_with_sense(NULL, err, 0, pending_req,
+ pending_req->rqid);
}
/*
@@ -653,15 +654,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 +708,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 +734,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 +752,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_req = *RING_GET_REQUEST(ring, rc);
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 +766,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_do_resp_with_sense(NULL, result << 24, 0, NULL,
+ ring_req.rqid);
return 1;
}
@@ -750,8 +776,9 @@ 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,
+ pending_req->rqid);
+ transport_generic_free_cmd(&pending_req->se_cmd, 0);
} else {
scsiback_cmd_exec(pending_req);
}
@@ -765,9 +792,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, pending_req->rqid);
+ transport_generic_free_cmd(&pending_req->se_cmd, 0);
break;
}
@@ -1355,10 +1382,10 @@ 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;
+ struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
- 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 +1528,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 +1859,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 +1869,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 +1881,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 +1897,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] 22+ messages in thread
* [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
` (10 preceding siblings ...)
2016-01-25 8:11 ` [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
@ 2016-01-25 8:11 ` Nicholas A. Bellinger
2016-01-26 9:49 ` Juergen Gross
11 siblings, 1 reply; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-25 8:11 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 | 53 +++++++++++++++++++++++-----------------------
1 file changed, 26 insertions(+), 27 deletions(-)
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index 640fb22..a10e5f1 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -381,6 +381,12 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req,
pending_req->rqid);
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)
@@ -398,7 +404,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) {
@@ -587,31 +593,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;
+ 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;
- if (transport_lookup_tmr_lun(se_cmd, pending_req->v2p->lun) < 0)
- goto out;
-
- 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) ?
@@ -1368,16 +1371,7 @@ 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)
@@ -1385,6 +1379,11 @@ 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] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-25 8:11 ` [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
@ 2016-01-25 15:42 ` Juergen Gross
2016-01-26 5:15 ` Nicholas A. Bellinger
2016-01-26 9:45 ` Juergen Gross
1 sibling, 1 reply; 22+ messages in thread
From: Juergen Gross @ 2016-01-25 15:42 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
On 25/01/16 09:11, 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>
Could you please rebase to current version? The patch won't apply.
Juergen
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-25 15:42 ` Juergen Gross
@ 2016-01-26 5:15 ` Nicholas A. Bellinger
0 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-26 5:15 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
On Mon, 2016-01-25 at 16:42 +0100, Juergen Gross wrote:
> On 25/01/16 09:11, 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>
>
> Could you please rebase to current version? The patch won't apply.
>
Yep, will be updating target-pending/queue-next to v4.5-rc1 over the
next days.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-25 8:11 ` [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
2016-01-25 15:42 ` Juergen Gross
@ 2016-01-26 9:45 ` Juergen Gross
2016-01-27 6:28 ` Nicholas A. Bellinger
1 sibling, 1 reply; 22+ messages in thread
From: Juergen Gross @ 2016-01-26 9:45 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
On 25/01/16 09:11, 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>
> ---
> drivers/xen/xen-scsiback.c | 163 ++++++++++++++++++++++++---------------------
> 1 file changed, 87 insertions(+), 76 deletions(-)
>
> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> index 594f8a7..640fb22 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);
> @@ -322,7 +321,8 @@ static void scsiback_free_translation_entry(struct kref *kref)
> }
>
> static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
> - uint32_t resid, struct vscsibk_pend *pending_req)
> + uint32_t resid, struct vscsibk_pend *pending_req,
> + uint16_t rqid)
> {
> struct vscsiif_response *ring_res;
> struct vscsibk_info *info = pending_req->info;
pending_req might be NULL now, so this will panic the system.
Juergen
> @@ -337,7 +337,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,
> @@ -358,7 +358,7 @@ static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
> if (notify)
> notify_remote_via_irq(info->irq);
>
> - if (pending_req->v2p)
> + if (pending_req && pending_req->v2p)
> kref_put(&pending_req->v2p->kref,
> scsiback_free_translation_entry);
> }
> @@ -378,7 +378,8 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
> scsiback_print_status(sense_buffer, errors, pending_req);
>
> scsiback_fast_flush_area(pending_req);
> - scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req);
> + scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req,
> + pending_req->rqid);
> scsiback_put(info);
> }
>
> @@ -616,15 +617,15 @@ static void scsiback_device_action(struct vscsibk_pend *pending_req,
> err = (se_cmd->se_tmr_req->response == TMR_FUNCTION_COMPLETE) ?
> SUCCESS : FAILED;
>
> -out:
> - if (tmr) {
> - transport_generic_free_cmd(&pending_req->se_cmd, 1);
> + scsiback_do_resp_with_sense(NULL, err, 0, pending_req,
> + pending_req->rqid);
> + transport_generic_free_cmd(&pending_req->se_cmd, 1);
> + return;
> +err:
> + if (tmr)
> kfree(tmr);
> - }
> -
> - scsiback_do_resp_with_sense(NULL, err, 0, pending_req);
> -
> - kmem_cache_free(scsiback_cachep, pending_req);
> + scsiback_do_resp_with_sense(NULL, err, 0, pending_req,
> + pending_req->rqid);
> }
>
> /*
> @@ -653,15 +654,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 +708,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 +734,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 +752,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_req = *RING_GET_REQUEST(ring, rc);
> 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 +766,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_do_resp_with_sense(NULL, result << 24, 0, NULL,
> + ring_req.rqid);
> return 1;
> }
>
> @@ -750,8 +776,9 @@ 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,
> + pending_req->rqid);
> + transport_generic_free_cmd(&pending_req->se_cmd, 0);
> } else {
> scsiback_cmd_exec(pending_req);
> }
> @@ -765,9 +792,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, pending_req->rqid);
> + transport_generic_free_cmd(&pending_req->se_cmd, 0);
> break;
> }
>
> @@ -1355,10 +1382,10 @@ 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;
> + struct se_tmr_req *se_tmr = se_cmd->se_tmr_req;
>
> - 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 +1528,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 +1859,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 +1869,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 +1881,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 +1897,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);
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session
2016-01-25 8:10 ` [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
@ 2016-01-26 9:45 ` Juergen Gross
0 siblings, 0 replies; 22+ messages in thread
From: Juergen Gross @ 2016-01-26 9:45 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
On 25/01/16 09:10, Nicholas A. Bellinger wrote:
> From: Christoph Hellwig <hch@lst.de>
>
> 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>
> Cc: Juergen Gross <jgross@suse.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(-)
Regarding drivers/xen/xen-scsiback.c:
Acked-by: Juergen Gross <jgross@suse.com>
>
> 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 43bcae8..594f8a7 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)
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
2016-01-25 8:11 ` [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
@ 2016-01-26 9:49 ` Juergen Gross
2016-01-27 6:29 ` Nicholas A. Bellinger
0 siblings, 1 reply; 22+ messages in thread
From: Juergen Gross @ 2016-01-26 9:49 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
On 25/01/16 09:11, 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>
> ---
> drivers/xen/xen-scsiback.c | 53 +++++++++++++++++++++++-----------------------
> 1 file changed, 26 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> index 640fb22..a10e5f1 100644
> --- a/drivers/xen/xen-scsiback.c
> +++ b/drivers/xen/xen-scsiback.c
> @@ -381,6 +381,12 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
> scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req,
> pending_req->rqid);
> 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)
> @@ -398,7 +404,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) {
> @@ -587,31 +593,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;
Sure? I think this should still be "goto out;"?
> + }
>
> 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;
> + 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;
Again.
Juergen
>
> - if (transport_lookup_tmr_lun(se_cmd, pending_req->v2p->lun) < 0)
> - goto out;
> -
> - 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) ?
> @@ -1368,16 +1371,7 @@ 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)
> @@ -1385,6 +1379,11 @@ 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);
> }
>
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-26 9:45 ` Juergen Gross
@ 2016-01-27 6:28 ` Nicholas A. Bellinger
2016-01-27 10:57 ` Juergen Gross
0 siblings, 1 reply; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-27 6:28 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
On Tue, 2016-01-26 at 10:45 +0100, Juergen Gross wrote:
> On 25/01/16 09:11, 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>
> > ---
> > drivers/xen/xen-scsiback.c | 163 ++++++++++++++++++++++++---------------------
> > 1 file changed, 87 insertions(+), 76 deletions(-)
> >
> > diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> > index 594f8a7..640fb22 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);
> > @@ -322,7 +321,8 @@ static void scsiback_free_translation_entry(struct kref *kref)
> > }
> >
> > static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
> > - uint32_t resid, struct vscsibk_pend *pending_req)
> > + uint32_t resid, struct vscsibk_pend *pending_req,
> > + uint16_t rqid)
> > {
> > struct vscsiif_response *ring_res;
> > struct vscsibk_info *info = pending_req->info;
>
> pending_req might be NULL now, so this will panic the system.
>
Thanks for the review.
Added the following to propagate up original *info into
scsiback_do_resp_with_sense() to address the early pending_req
failure case.
https://git.kernel.org/cgit/linux/kernel/git/nab/target-pending.git/commit/?h=queue-next&id=5873f22a9b7c7aa16ff9a85074a07b739f1d06a5
Will plan to fold into the original for -v3 code.
Thanks Juergen!
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs
2016-01-26 9:49 ` Juergen Gross
@ 2016-01-27 6:29 ` Nicholas A. Bellinger
0 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-27 6:29 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
On Tue, 2016-01-26 at 10:49 +0100, Juergen Gross wrote:
> On 25/01/16 09:11, 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>
> > ---
> > drivers/xen/xen-scsiback.c | 53 +++++++++++++++++++++++-----------------------
> > 1 file changed, 26 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> > index 640fb22..a10e5f1 100644
> > --- a/drivers/xen/xen-scsiback.c
> > +++ b/drivers/xen/xen-scsiback.c
> > @@ -381,6 +381,12 @@ static void scsiback_cmd_done(struct vscsibk_pend *pending_req)
> > scsiback_do_resp_with_sense(sense_buffer, errors, resid, pending_req,
> > pending_req->rqid);
> > 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)
> > @@ -398,7 +404,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) {
> > @@ -587,31 +593,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;
>
> Sure? I think this should still be "goto out;"?
>
> > + }
> >
> > 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;
> > + 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;
>
> Again.
>
Whoops, bisect breakage here..
Fixed up this in latest target-pending/queue-next.
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-27 6:28 ` Nicholas A. Bellinger
@ 2016-01-27 10:57 ` Juergen Gross
2016-01-28 5:13 ` Nicholas A. Bellinger
0 siblings, 1 reply; 22+ messages in thread
From: Juergen Gross @ 2016-01-27 10:57 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 27/01/16 07:28, Nicholas A. Bellinger wrote:
> On Tue, 2016-01-26 at 10:45 +0100, Juergen Gross wrote:
>> On 25/01/16 09:11, 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>
>>> ---
>>> drivers/xen/xen-scsiback.c | 163 ++++++++++++++++++++++++---------------------
>>> 1 file changed, 87 insertions(+), 76 deletions(-)
>>>
>>> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
>>> index 594f8a7..640fb22 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);
>>> @@ -322,7 +321,8 @@ static void scsiback_free_translation_entry(struct kref *kref)
>>> }
>>>
>>> static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
>>> - uint32_t resid, struct vscsibk_pend *pending_req)
>>> + uint32_t resid, struct vscsibk_pend *pending_req,
>>> + uint16_t rqid)
>>> {
>>> struct vscsiif_response *ring_res;
>>> struct vscsibk_info *info = pending_req->info;
>>
>> pending_req might be NULL now, so this will panic the system.
>>
>
> Thanks for the review.
>
> Added the following to propagate up original *info into
> scsiback_do_resp_with_sense() to address the early pending_req
> failure case.
>
> https://git.kernel.org/cgit/linux/kernel/git/nab/target-pending.git/commit/?h=queue-next&id=5873f22a9b7c7aa16ff9a85074a07b739f1d06a5
Hmm, wouldn't it make more sense to split scsiback_do_resp_with_sense()
into two functions now? Something like:
diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
index ad4eb10..0d71467 100644
--- a/drivers/xen/xen-scsiback.c
+++ b/drivers/xen/xen-scsiback.c
@@ -321,11 +321,10 @@ 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,
And then call scsiback_send_response() directly in case pending_req
is NULL.
Juergen
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation
2016-01-27 10:57 ` Juergen Gross
@ 2016-01-28 5:13 ` Nicholas A. Bellinger
0 siblings, 0 replies; 22+ messages in thread
From: Nicholas A. Bellinger @ 2016-01-28 5:13 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
On Wed, 2016-01-27 at 11:57 +0100, Juergen Gross wrote:
> On 27/01/16 07:28, Nicholas A. Bellinger wrote:
> > On Tue, 2016-01-26 at 10:45 +0100, Juergen Gross wrote:
> >> On 25/01/16 09:11, 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>
> >>> ---
> >>> drivers/xen/xen-scsiback.c | 163 ++++++++++++++++++++++++---------------------
> >>> 1 file changed, 87 insertions(+), 76 deletions(-)
> >>>
> >>> diff --git a/drivers/xen/xen-scsiback.c b/drivers/xen/xen-scsiback.c
> >>> index 594f8a7..640fb22 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);
> >>> @@ -322,7 +321,8 @@ static void scsiback_free_translation_entry(struct kref *kref)
> >>> }
> >>>
> >>> static void scsiback_do_resp_with_sense(char *sense_buffer, int32_t result,
> >>> - uint32_t resid, struct vscsibk_pend *pending_req)
> >>> + uint32_t resid, struct vscsibk_pend *pending_req,
> >>> + uint16_t rqid)
> >>> {
> >>> struct vscsiif_response *ring_res;
> >>> struct vscsibk_info *info = pending_req->info;
> >>
> >> pending_req might be NULL now, so this will panic the system.
> >>
> >
> > Thanks for the review.
> >
> > Added the following to propagate up original *info into
> > scsiback_do_resp_with_sense() to address the early pending_req
> > failure case.
> >
> > https://git.kernel.org/cgit/linux/kernel/git/nab/target-pending.git/commit/?h=queue-next&id=5873f22a9b7c7aa16ff9a85074a07b739f1d06a5
>
> Hmm, wouldn't it make more sense to split scsiback_do_resp_with_sense()
> into two functions now? Something like:
>
<SNIP>
> And then call scsiback_send_response() directly in case pending_req
> is NULL.
>
That makes alot more sense.
Just updated the series in queue-next, and folded your change into the
original patch.
Thanks Juergen.
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2016-01-28 5:13 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-25 8:10 [PATCH-v2 00/12] target: target_alloc_session w/ percpu_ida+ACK_KREF conversion Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 01/12] target: Add target_alloc_session() helper function Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 02/12] target: Convert demo-mode only drivers to target_alloc_session Nicholas A. Bellinger
2016-01-26 9:45 ` Juergen Gross
2016-01-25 8:10 ` [PATCH-v2 03/12] vhost/scsi: Convert to target_alloc_session usage Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 04/12] tcm_qla2xxx: " Nicholas A. Bellinger
2016-01-25 8:10 ` [PATCH-v2 05/12] tcm_fc: " Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 06/12] ib_srpt: " Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 07/12] sbp-target: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 08/12] sbp-target: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 09/12] usb-gadget/tcm: Conversion to percpu_ida tag pre-allocation Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 10/12] usb-gadget/tcm: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 11/12] xen-scsiback: Convert to percpu_ida tag allocation Nicholas A. Bellinger
2016-01-25 15:42 ` Juergen Gross
2016-01-26 5:15 ` Nicholas A. Bellinger
2016-01-26 9:45 ` Juergen Gross
2016-01-27 6:28 ` Nicholas A. Bellinger
2016-01-27 10:57 ` Juergen Gross
2016-01-28 5:13 ` Nicholas A. Bellinger
2016-01-25 8:11 ` [PATCH-v2 12/12] xen-scsiback: Convert to TARGET_SCF_ACK_KREF I/O krefs Nicholas A. Bellinger
2016-01-26 9:49 ` Juergen Gross
2016-01-27 6:29 ` Nicholas A. Bellinger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).