mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
To: Christoph Hellwig <hch@lst.de>
Cc: "Nicholas A. Bellinger" <nab@daterainc.com>,
	target-devel <target-devel@vger.kernel.org>,
	linux-scsi <linux-scsi@vger.kernel.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Hannes Reinecke <hare@suse.de>,
	Sagi Grimberg <sagig@mellanox.com>
Subject: Re: [PATCH 01/12] target: Convert se_node_acl->device_list[] to RCU hlist
Date: Mon, 18 May 2015 00:17:24 -0700	[thread overview]
Message-ID: <1431933444.24645.7.camel@haakon3.risingtidesystems.com> (raw)
In-Reply-To: <20150517165142.GA17217@lst.de>

On Sun, 2015-05-17 at 18:51 +0200, Christoph Hellwig wrote:
> On Wed, May 13, 2015 at 01:46:11AM -0700, Nicholas A. Bellinger wrote:
> > Updated to use a mirror lun->lun_rtpi, with the assignment from sep_rtpi
> > occuring in core_dev_export() code.
> 
> From looking at your current tree I suspect freeing the se_port structure
> using kfree_rcu might be a better idea.  Together with dropping the references
> to the se_device from call_rcu context this basically means all pointers
> in struct se_lun are rcu protected which is much safer if you want
> to access struct se_lun under rcu protection, as this avoids having to
> deal with special cases.  Additionally that basically allows you to
> replace lun_sep_lock with rcu_read_lock for anything remotely like
> a fast path.

Here's a first pass at this along with kref + completion conversion for
the special case PR ALL_TGT_PT=1 pointer dereference.

Thanks HCH.

>From 3a6e7fffe13050a0d8cb0c668e122e16e0a8b17d Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab@linux-iscsi.org>
Date: Sun, 17 May 2015 23:00:31 -0700
Subject: [PATCH] target: Convert se_lun->lun_sep updater + readers to RCU

Reported-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
 drivers/target/target_core_device.c    |  51 +++----
 drivers/target/target_core_internal.h  |   1 +
 drivers/target/target_core_pr.c        |   8 +-
 drivers/target/target_core_stat.c      | 268 ++++++++++-----------------------
 drivers/target/target_core_transport.c |  48 +++---
 include/target/target_core_base.h      |   4 +-
 6 files changed, 135 insertions(+), 245 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 2f4c8fa..88dad15 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -452,6 +452,8 @@ static struct se_port *core_alloc_port(struct se_device *dev)
 	atomic_set(&port->sep_tg_pt_secondary_offline, 0);
 	spin_lock_init(&port->sep_alua_lock);
 	mutex_init(&port->sep_tg_pt_md_mutex);
+	kref_init(&port->sep_tg_pt_ref);
+	init_completion(&port->sep_tg_pt_comp);
 
 	spin_lock(&dev->se_port_lock);
 	if (dev->dev_port_count == 0x0000ffff) {
@@ -502,7 +504,7 @@ static void core_export_port(
 	spin_lock(&lun->lun_sep_lock);
 	port->sep_tpg = tpg;
 	port->sep_lun = lun;
-	lun->lun_sep = port;
+	rcu_assign_pointer(lun->lun_sep, port);
 	spin_unlock(&lun->lun_sep_lock);
 
 	list_add_tail(&port->sep_list, &dev->dev_sep_list);
@@ -529,28 +531,6 @@ static void core_export_port(
 	port->sep_index = port->sep_rtpi; /* RELATIVE TARGET PORT IDENTIFIER */
 }
 
-/*
- *	Called with struct se_device->se_port_lock spinlock held.
- */
-static void core_release_port(struct se_device *dev, struct se_port *port)
-	__releases(&dev->se_port_lock) __acquires(&dev->se_port_lock)
-{
-	/*
-	 * Wait for any port reference for PR ALL_TG_PT=1 operation
-	 * to complete in __core_scsi3_alloc_registration()
-	 */
-	spin_unlock(&dev->se_port_lock);
-	if (atomic_read(&port->sep_tg_pt_ref_cnt))
-		cpu_relax();
-	spin_lock(&dev->se_port_lock);
-
-	core_alua_free_tg_pt_gp_mem(port);
-
-	list_del(&port->sep_list);
-	dev->dev_port_count--;
-	kfree(port);
-}
-
 int core_dev_export(
 	struct se_device *dev,
 	struct se_portal_group *tpg,
@@ -574,31 +554,46 @@ int core_dev_export(
 	return 0;
 }
 
+void target_port_kref_release(struct kref *kref)
+{
+	struct se_port *port = container_of(kref, struct se_port, sep_tg_pt_ref);
+
+	complete(&port->sep_tg_pt_comp);
+}
+
 void core_dev_unexport(
 	struct se_device *dev,
 	struct se_portal_group *tpg,
 	struct se_lun *lun)
 {
 	struct se_hba *hba = dev->se_hba;
-	struct se_port *port = lun->lun_sep;
+	struct se_port *port;
 
 	spin_lock(&lun->lun_sep_lock);
-	if (lun->lun_se_dev == NULL) {
+	port = lun->lun_sep;
+	if (!port) {
 		spin_unlock(&lun->lun_sep_lock);
 		return;
 	}
+	rcu_assign_pointer(lun->lun_sep, NULL);
+	lun->lun_se_dev = NULL;
 	spin_unlock(&lun->lun_sep_lock);
 
+	kref_put(&port->sep_tg_pt_ref, target_port_kref_release);
+	wait_for_completion(&port->sep_tg_pt_comp);
+
+	core_alua_free_tg_pt_gp_mem(port);
+
 	spin_lock(&dev->se_port_lock);
-	core_release_port(dev, port);
+	list_del(&port->sep_list);
+	dev->dev_port_count--;
 	spin_unlock(&dev->se_port_lock);
 
 	spin_lock(&hba->device_lock);
 	dev->export_count--;
 	spin_unlock(&hba->device_lock);
 
-	lun->lun_sep = NULL;
-	lun->lun_se_dev = NULL;
+	kfree_rcu(port, sep_rcu);
 }
 
 static void se_release_vpd_for_dev(struct se_device *dev)
diff --git a/drivers/target/target_core_internal.h b/drivers/target/target_core_internal.h
index beb1c3e..21e5f9e 100644
--- a/drivers/target/target_core_internal.h
+++ b/drivers/target/target_core_internal.h
@@ -23,6 +23,7 @@ extern struct list_head g_device_list;
 
 struct se_dev_entry *core_get_se_deve_from_rtpi(struct se_node_acl *, u16);
 void	target_pr_kref_release(struct kref *);
+void	target_port_kref_release(struct kref *);
 void	core_free_device_list_for_node(struct se_node_acl *,
 		struct se_portal_group *);
 void	core_update_device_list_access(u32, u32, struct se_node_acl *);
diff --git a/drivers/target/target_core_pr.c b/drivers/target/target_core_pr.c
index cee2b31..c53b66c 100644
--- a/drivers/target/target_core_pr.c
+++ b/drivers/target/target_core_pr.c
@@ -702,7 +702,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 	 */
 	spin_lock(&dev->se_port_lock);
 	list_for_each_entry_safe(port, port_tmp, &dev->dev_sep_list, sep_list) {
-		atomic_inc_mb(&port->sep_tg_pt_ref_cnt);
+		kref_get(&port->sep_tg_pt_ref);
 		spin_unlock(&dev->se_port_lock);
 
 		spin_lock_bh(&port->sep_alua_lock);
@@ -748,7 +748,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 			if (ret < 0) {
 				pr_err("core_scsi3_lunacl_depend"
 						"_item() failed\n");
-				atomic_dec_mb(&port->sep_tg_pt_ref_cnt);
+				kref_put(&port->sep_tg_pt_ref, target_port_kref_release);
 				kref_put(&deve_tmp->pr_kref, target_pr_kref_release);
 				goto out;
 			}
@@ -764,7 +764,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 						deve_tmp, deve_tmp->mapped_lun,
 						NULL, sa_res_key, all_tg_pt, aptpl);
 			if (!pr_reg_atp) {
-				atomic_dec_mb(&port->sep_tg_pt_ref_cnt);
+				kref_put(&port->sep_tg_pt_ref, target_port_kref_release);
 				core_scsi3_lunacl_undepend_item(deve_tmp);
 				goto out;
 			}
@@ -776,7 +776,7 @@ static struct t10_pr_registration *__core_scsi3_alloc_registration(
 		spin_unlock_bh(&port->sep_alua_lock);
 
 		spin_lock(&dev->se_port_lock);
-		atomic_dec_mb(&port->sep_tg_pt_ref_cnt);
+		kref_put(&port->sep_tg_pt_ref, target_port_kref_release);
 	}
 	spin_unlock(&dev->se_port_lock);
 
diff --git a/drivers/target/target_core_stat.c b/drivers/target/target_core_stat.c
index 7b7b524..7af692c 100644
--- a/drivers/target/target_core_stat.c
+++ b/drivers/target/target_core_stat.c
@@ -542,21 +542,9 @@ static ssize_t target_stat_scsi_port_show_attr_inst(
 	struct se_port_stat_grps *pgrps, char *page)
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
-	struct se_port *sep;
 	struct se_device *dev = lun->lun_se_dev;
-	struct se_hba *hba;
-	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	hba = dev->se_hba;
-	ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", dev->se_hba->hba_index);
 }
 DEV_STAT_SCSI_PORT_ATTR_RO(inst);
 
@@ -564,19 +552,9 @@ static ssize_t target_stat_scsi_port_show_attr_dev(
 	struct se_port_stat_grps *pgrps, char *page)
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
-	struct se_port *sep;
 	struct se_device *dev = lun->lun_se_dev;
-	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
 }
 DEV_STAT_SCSI_PORT_ATTR_RO(dev);
 
@@ -587,14 +565,15 @@ static ssize_t target_stat_scsi_port_show_attr_indx(
 	struct se_port *sep;
 	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
 	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
+		rcu_read_unlock();
 		return -ENODEV;
 	}
 	ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index);
-	spin_unlock(&lun->lun_sep_lock);
+	rcu_read_unlock();
+
 	return ret;
 }
 DEV_STAT_SCSI_PORT_ATTR_RO(indx);
@@ -604,41 +583,16 @@ static ssize_t target_stat_scsi_port_show_attr_role(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_device *dev = lun->lun_se_dev;
-	struct se_port *sep;
-	ssize_t ret;
 
-	if (!dev)
-		return -ENODEV;
-
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	ret = snprintf(page, PAGE_SIZE, "%s%u\n", "Device", dev->dev_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%s%u\n", "Device", dev->dev_index);
 }
 DEV_STAT_SCSI_PORT_ATTR_RO(role);
 
 static ssize_t target_stat_scsi_port_show_attr_busy_count(
 	struct se_port_stat_grps *pgrps, char *page)
 {
-	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
-	struct se_port *sep;
-	ssize_t ret;
-
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
 	/* FIXME: scsiPortBusyStatuses  */
-	ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
 DEV_STAT_SCSI_PORT_ATTR_RO(busy_count);
 
@@ -686,20 +640,8 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_inst(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_device *dev = lun->lun_se_dev;
-	struct se_port *sep;
-	struct se_hba *hba;
-	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	hba = dev->se_hba;
-	ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", dev->se_hba->hba_index);
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(inst);
 
@@ -708,18 +650,8 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_dev(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_device *dev = lun->lun_se_dev;
-	struct se_port *sep;
-	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	ret = snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", dev->dev_index);
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(dev);
 
@@ -728,16 +660,14 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_indx(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-	ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index);
-	spin_unlock(&lun->lun_sep_lock);
+	if (sep)
+		ret = snprintf(page, PAGE_SIZE, "%u\n", sep->sep_index);
+	rcu_read_unlock();
+
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(indx);
@@ -748,19 +678,17 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_name(
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
 	struct se_portal_group *tpg;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
+	if (sep) {
+		tpg = sep->sep_tpg;
+		ret = snprintf(page, PAGE_SIZE, "%sPort#%u\n",
+			tpg->se_tpg_tfo->get_fabric_name(), sep->sep_index);
 	}
-	tpg = sep->sep_tpg;
+	rcu_read_unlock();
 
-	ret = snprintf(page, PAGE_SIZE, "%sPort#%u\n",
-		tpg->se_tpg_tfo->get_fabric_name(), sep->sep_index);
-	spin_unlock(&lun->lun_sep_lock);
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(name);
@@ -771,20 +699,18 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_port_index(
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
 	struct se_portal_group *tpg;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
+	if (sep) {
+		tpg = sep->sep_tpg;
+		ret = snprintf(page, PAGE_SIZE, "%s%s%d\n",
+			tpg->se_tpg_tfo->tpg_get_wwn(tpg), "+t+",
+			tpg->se_tpg_tfo->tpg_get_tag(tpg));
 	}
-	tpg = sep->sep_tpg;
+	rcu_read_unlock();
 
-	ret = snprintf(page, PAGE_SIZE, "%s%s%d\n",
-		tpg->se_tpg_tfo->tpg_get_wwn(tpg), "+t+",
-		tpg->se_tpg_tfo->tpg_get_tag(tpg));
-	spin_unlock(&lun->lun_sep_lock);
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(port_index);
@@ -794,17 +720,14 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_in_cmds(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
+	if (sep)
+		ret = snprintf(page, PAGE_SIZE, "%llu\n", sep->sep_stats.cmd_pdus);
+	rcu_read_unlock();
 
-	ret = snprintf(page, PAGE_SIZE, "%llu\n", sep->sep_stats.cmd_pdus);
-	spin_unlock(&lun->lun_sep_lock);
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(in_cmds);
@@ -814,18 +737,15 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_write_mbytes(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
+	if (sep)
+		ret = snprintf(page, PAGE_SIZE, "%u\n",
+				(u32)(sep->sep_stats.rx_data_octets >> 20));
+	rcu_read_unlock();
 
-	ret = snprintf(page, PAGE_SIZE, "%u\n",
-			(u32)(sep->sep_stats.rx_data_octets >> 20));
-	spin_unlock(&lun->lun_sep_lock);
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(write_mbytes);
@@ -837,16 +757,13 @@ static ssize_t target_stat_scsi_tgt_port_show_attr_read_mbytes(
 	struct se_port *sep;
 	ssize_t ret;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
+	if (sep)
+		ret = snprintf(page, PAGE_SIZE, "%u\n",
+				(u32)(sep->sep_stats.tx_data_octets >> 20));
+	rcu_read_unlock();
 
-	ret = snprintf(page, PAGE_SIZE, "%u\n",
-			(u32)(sep->sep_stats.tx_data_octets >> 20));
-	spin_unlock(&lun->lun_sep_lock);
 	return ret;
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(read_mbytes);
@@ -854,21 +771,8 @@ DEV_STAT_SCSI_TGT_PORT_ATTR_RO(read_mbytes);
 static ssize_t target_stat_scsi_tgt_port_show_attr_hs_in_cmds(
 	struct se_port_stat_grps *pgrps, char *page)
 {
-	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
-	struct se_port *sep;
-	ssize_t ret;
-
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
-
 	/* FIXME: scsiTgtPortHsInCommands */
-	ret = snprintf(page, PAGE_SIZE, "%u\n", 0);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", 0);
 }
 DEV_STAT_SCSI_TGT_PORT_ATTR_RO(hs_in_cmds);
 
@@ -922,21 +826,8 @@ static ssize_t target_stat_scsi_transport_show_attr_inst(
 {
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_device *dev = lun->lun_se_dev;
-	struct se_port *sep;
-	struct se_hba *hba;
-	ssize_t ret;
-
-	spin_lock(&lun->lun_sep_lock);
-	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
-	}
 
-	hba = dev->se_hba;
-	ret = snprintf(page, PAGE_SIZE, "%u\n", hba->hba_index);
-	spin_unlock(&lun->lun_sep_lock);
-	return ret;
+	return snprintf(page, PAGE_SIZE, "%u\n", dev->se_hba->hba_index);
 }
 DEV_STAT_SCSI_TRANSPORT_ATTR_RO(inst);
 
@@ -946,19 +837,18 @@ static ssize_t target_stat_scsi_transport_show_attr_device(
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
 	struct se_portal_group *tpg;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
+	if (sep) {
+		tpg = sep->sep_tpg;
+		/* scsiTransportType */
+		ret = snprintf(page, PAGE_SIZE, "scsiTransport%s\n",
+				tpg->se_tpg_tfo->get_fabric_name());
 	}
-	tpg = sep->sep_tpg;
-	/* scsiTransportType */
-	ret = snprintf(page, PAGE_SIZE, "scsiTransport%s\n",
-			tpg->se_tpg_tfo->get_fabric_name());
-	spin_unlock(&lun->lun_sep_lock);
+	rcu_read_unlock();
+
 	return ret;
 }
 DEV_STAT_SCSI_TRANSPORT_ATTR_RO(device);
@@ -969,18 +859,17 @@ static ssize_t target_stat_scsi_transport_show_attr_indx(
 	struct se_lun *lun = container_of(pgrps, struct se_lun, port_stat_grps);
 	struct se_port *sep;
 	struct se_portal_group *tpg;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
+	if (sep) {
+		tpg = sep->sep_tpg;
+		ret = snprintf(page, PAGE_SIZE, "%u\n",
+				tpg->se_tpg_tfo->tpg_get_inst_index(tpg));
 	}
-	tpg = sep->sep_tpg;
-	ret = snprintf(page, PAGE_SIZE, "%u\n",
-			tpg->se_tpg_tfo->tpg_get_inst_index(tpg));
-	spin_unlock(&lun->lun_sep_lock);
+	rcu_read_unlock();
+
 	return ret;
 }
 DEV_STAT_SCSI_TRANSPORT_ATTR_RO(indx);
@@ -993,22 +882,21 @@ static ssize_t target_stat_scsi_transport_show_attr_dev_name(
 	struct se_port *sep;
 	struct se_portal_group *tpg;
 	struct t10_wwn *wwn;
-	ssize_t ret;
+	ssize_t ret = 0;
 
-	spin_lock(&lun->lun_sep_lock);
+	rcu_read_lock();
 	sep = lun->lun_sep;
-	if (!sep) {
-		spin_unlock(&lun->lun_sep_lock);
-		return -ENODEV;
+	if (sep) {
+		tpg = sep->sep_tpg;
+		wwn = &dev->t10_wwn;
+		/* scsiTransportDevName */
+		ret = snprintf(page, PAGE_SIZE, "%s+%s\n",
+				tpg->se_tpg_tfo->tpg_get_wwn(tpg),
+				(strlen(wwn->unit_serial)) ? wwn->unit_serial :
+				wwn->vendor);
 	}
-	tpg = sep->sep_tpg;
-	wwn = &dev->t10_wwn;
-	/* scsiTransportDevName */
-	ret = snprintf(page, PAGE_SIZE, "%s+%s\n",
-			tpg->se_tpg_tfo->tpg_get_wwn(tpg),
-			(strlen(wwn->unit_serial)) ? wwn->unit_serial :
-			wwn->vendor);
-	spin_unlock(&lun->lun_sep_lock);
+	rcu_read_unlock();
+
 	return ret;
 }
 DEV_STAT_SCSI_TRANSPORT_ATTR_RO(dev_name);
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 2b9f41a..0de29d8 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -1213,6 +1213,7 @@ sense_reason_t
 target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
 {
 	struct se_device *dev = cmd->se_dev;
+	struct se_port *sep;
 	sense_reason_t ret;
 
 	/*
@@ -1276,10 +1277,12 @@ target_setup_cmd_from_cdb(struct se_cmd *cmd, unsigned char *cdb)
 
 	cmd->se_cmd_flags |= SCF_SUPPORTED_SAM_OPCODE;
 
-	spin_lock(&cmd->se_lun->lun_sep_lock);
-	if (cmd->se_lun->lun_sep)
-		cmd->se_lun->lun_sep->sep_stats.cmd_pdus++;
-	spin_unlock(&cmd->se_lun->lun_sep_lock);
+	rcu_read_lock();
+	sep = cmd->se_lun->lun_sep;
+	if (sep)
+		sep->sep_stats.cmd_pdus++;
+	rcu_read_unlock();
+
 	return 0;
 }
 EXPORT_SYMBOL(target_setup_cmd_from_cdb);
@@ -2016,6 +2019,7 @@ static bool target_read_prot_action(struct se_cmd *cmd)
 static void target_complete_ok_work(struct work_struct *work)
 {
 	struct se_cmd *cmd = container_of(work, struct se_cmd, work);
+	struct se_port *sep;
 	int ret;
 
 	/*
@@ -2076,12 +2080,12 @@ static void target_complete_ok_work(struct work_struct *work)
 queue_rsp:
 	switch (cmd->data_direction) {
 	case DMA_FROM_DEVICE:
-		spin_lock(&cmd->se_lun->lun_sep_lock);
-		if (cmd->se_lun->lun_sep) {
-			cmd->se_lun->lun_sep->sep_stats.tx_data_octets +=
-					cmd->data_length;
-		}
-		spin_unlock(&cmd->se_lun->lun_sep_lock);
+		rcu_read_lock();
+		sep = cmd->se_lun->lun_sep;
+		if (sep)
+			sep->sep_stats.tx_data_octets += cmd->data_length;
+		rcu_read_unlock();
+
 		/*
 		 * Perform READ_STRIP of PI using software emulation when
 		 * backend had PI enabled, if the transport will not be
@@ -2104,22 +2108,22 @@ queue_rsp:
 			goto queue_full;
 		break;
 	case DMA_TO_DEVICE:
-		spin_lock(&cmd->se_lun->lun_sep_lock);
-		if (cmd->se_lun->lun_sep) {
-			cmd->se_lun->lun_sep->sep_stats.rx_data_octets +=
-				cmd->data_length;
-		}
-		spin_unlock(&cmd->se_lun->lun_sep_lock);
+		rcu_read_lock();
+		sep = cmd->se_lun->lun_sep;
+		if (sep)
+			sep->sep_stats.rx_data_octets += cmd->data_length;
+		rcu_read_unlock();
+
 		/*
 		 * Check if we need to send READ payload for BIDI-COMMAND
 		 */
 		if (cmd->se_cmd_flags & SCF_BIDI) {
-			spin_lock(&cmd->se_lun->lun_sep_lock);
-			if (cmd->se_lun->lun_sep) {
-				cmd->se_lun->lun_sep->sep_stats.tx_data_octets +=
-					cmd->data_length;
-			}
-			spin_unlock(&cmd->se_lun->lun_sep_lock);
+			rcu_read_lock();
+			sep = cmd->se_lun->lun_sep;
+			if (sep)
+				sep->sep_stats.tx_data_octets += cmd->data_length;
+			rcu_read_unlock();
+
 			ret = cmd->se_tfo->queue_data_in(cmd);
 			if (ret == -EAGAIN || ret == -ENOMEM)
 				goto queue_full;
diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
index 86c0c5c..01f2d91 100644
--- a/include/target/target_core_base.h
+++ b/include/target/target_core_base.h
@@ -845,7 +845,8 @@ struct se_port {
 	/* Used for ALUA Target Port Groups membership */
 	atomic_t	sep_tg_pt_secondary_offline;
 	/* Used for PR ALL_TG_PT=1 */
-	atomic_t	sep_tg_pt_ref_cnt;
+	struct kref	sep_tg_pt_ref;
+	struct completion sep_tg_pt_comp;
 	spinlock_t	sep_alua_lock;
 	struct mutex	sep_tg_pt_md_mutex;
 	struct t10_alua_tg_pt_gp_member *sep_alua_tg_pt_gp_mem;
@@ -853,6 +854,7 @@ struct se_port {
 	struct se_portal_group *sep_tpg;
 	struct list_head sep_alua_list;
 	struct list_head sep_list;
+	struct rcu_head	sep_rcu;
 };
 
 struct se_tpg_np {
-- 
1.9.1


  reply	other threads:[~2015-05-18  7:18 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-12  9:25 [PATCH 00/12] target: TPG/NodeACL LUN table conversion " Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 01/12] target: Convert se_node_acl->device_list[] " Nicholas A. Bellinger
2015-05-12 20:58   ` Andy Grover
2015-05-13  5:08     ` Nicholas A. Bellinger
2015-05-13  5:32       ` Christoph Hellwig
2015-05-13  5:41         ` Nicholas A. Bellinger
2015-05-13  5:46   ` Christoph Hellwig
2015-05-13  6:20     ` Nicholas A. Bellinger
2015-05-13  6:48       ` Christoph Hellwig
2015-05-13  6:35   ` Christoph Hellwig
2015-05-13  8:46     ` Nicholas A. Bellinger
2015-05-17 16:51       ` Christoph Hellwig
2015-05-18  7:17         ` Nicholas A. Bellinger [this message]
2015-05-18  7:41           ` Christoph Hellwig
2015-05-18  8:01             ` Christoph Hellwig
2015-05-19  6:05               ` Nicholas A. Bellinger
2015-05-19  6:22                 ` Christoph Hellwig
2015-05-21 17:03                   ` Christoph Hellwig
2015-05-21 18:10                     ` Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 02/12] target: Convert REPORT_LUN + MODE_SENSE to RCU reader Nicholas A. Bellinger
2015-05-13  5:47   ` Christoph Hellwig
2015-05-13  8:10     ` Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 03/12] target/configfs: Convert mappedlun + SCSI MIBs " Nicholas A. Bellinger
2015-05-12 20:58   ` Andy Grover
2015-05-13  5:09     ` Nicholas A. Bellinger
2015-05-13  5:49       ` Christoph Hellwig
2015-05-12  9:25 ` [PATCH 04/12] target: Convert UNIT_ATTENTION logic " Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 05/12] target: Convert transport_lookup_*_lun " Nicholas A. Bellinger
2015-05-13  5:55   ` Christoph Hellwig
2015-05-13  7:42     ` Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 06/12] target/pr: Convert se_dev_entry to kref for RCU Nicholas A. Bellinger
2015-05-13  5:59   ` Christoph Hellwig
2015-05-12  9:25 ` [PATCH 07/12] target/pr: Convert registration check to RCU pointer Nicholas A. Bellinger
2015-05-13  6:13   ` Christoph Hellwig
2015-05-12  9:25 ` [PATCH 08/12] target/pr: Change alloc_registration to avoid pr_reg_tg_pt_lun Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 09/12] target: Convert se_portal_group->tpg_lun_list[] to RCU hlist Nicholas A. Bellinger
2015-05-13  6:24   ` Christoph Hellwig
2015-05-13  7:22     ` Juergen Gross
2015-05-13  7:53       ` Christoph Hellwig
2015-05-19  6:46   ` Christoph Hellwig
2015-05-12  9:25 ` [PATCH 10/12] target: Convert se_tpg->acl_node_lock to ->acl_node_mutex Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 11/12] target: Convert core_tpg_deregister to use list splice Nicholas A. Bellinger
2015-05-12  9:25 ` [PATCH 12/12] target: Drop unused se_lun->lun_acl_list Nicholas A. Bellinger
2015-05-13  6:29 ` [PATCH 00/12] target: TPG/NodeACL LUN table conversion to RCU hlist Christoph Hellwig

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1431933444.24645.7.camel@haakon3.risingtidesystems.com \
    --to=nab@linux-iscsi.org \
    --cc=hare@suse.de \
    --cc=hch@lst.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-scsi@vger.kernel.org \
    --cc=nab@daterainc.com \
    --cc=sagig@mellanox.com \
    --cc=target-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®