All of lore.kernel.org
 help / color / mirror / Atom feed
From: Douglas Gilbert <dgilbert@interlog.com>
To: linux-scsi@vger.kernel.org
Cc: martin.petersen@oracle.com, jejb@linux.vnet.ibm.com, hare@suse.de
Subject: [RFC v2 5/6] scsi: add __scsi_target_lookup
Date: Sun, 24 May 2020 11:58:13 -0400	[thread overview]
Message-ID: <20200524155814.5895-6-dgilbert@interlog.com> (raw)
In-Reply-To: <20200524155814.5895-1-dgilbert@interlog.com>

Hides the xarray based lookup of a target given the channel and target
identifiers within a shost. Use this and __sstarg_for_each_device()
where useful.

Break the pattern when deleting to jump back and restart the iteration
as that seems to be a linked list quirk. May change semantics if
elements can be added in the newly created holes in the xarray at the
same time as the ongoing deletion.

Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
 drivers/scsi/scsi.c        | 24 ++++++++++++++++++++++++
 drivers/scsi/scsi_error.c  | 34 +++++++++++++++++-----------------
 drivers/scsi/scsi_lib.c    |  8 +++-----
 drivers/scsi/scsi_scan.c   |  4 ++--
 drivers/scsi/scsi_sysfs.c  |  8 +++-----
 include/scsi/scsi_device.h |  2 ++
 6 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 9e7658aebdb7..1b1fc8d4e5c2 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -667,6 +667,30 @@ struct scsi_device *__scsi_target_iterate_devices(struct scsi_target *starg,
 }
 EXPORT_SYMBOL(__scsi_target_iterate_devices);
 
+/**
+ * __scsi_target_lookup  -  helper to find target given channel and target_id
+ * @shost:	host to search within
+ * @chan:	channel number
+ * @t_id:	target identifier
+ *
+ * No locks or references taken. Returns NULL if not found.
+ */
+struct scsi_target *__scsi_target_lookup(struct Scsi_Host *shost,
+					 uint chan, uint t_id)
+{
+	unsigned long l_idx;
+	struct scsi_target *starg = NULL;
+
+	if (shost) {
+		xa_for_each(&shost->__targets, l_idx, starg) {
+			if (chan == starg->channel && t_id == starg->id)
+				break;
+		}
+	}
+	return starg;
+}
+EXPORT_SYMBOL(__scsi_target_lookup);
+
 /**
  * starget_for_each_device  -  helper to walk all devices of a target
  * @starg:	target whose devices we want to iterate over.
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 978be1602f71..b2dbfa5f73a0 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -644,6 +644,7 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
 {
 	struct scsi_host_template *sht = sdev->host->hostt;
 	struct scsi_device *tmp_sdev;
+	struct scsi_target *starg = scsi_target(sdev);
 
 	if (!sht->track_queue_depth ||
 	    sdev->queue_depth >= sdev->max_queue_depth)
@@ -658,13 +659,10 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
 		return;
 
 	/*
-	 * Walk all devices of a target and do
-	 * ramp up on them.
+	 * Walk all devices of a target and do ramp up on them.
 	 */
-	shost_for_each_device(tmp_sdev, sdev->host) {
-		if (tmp_sdev->channel != sdev->channel ||
-		    tmp_sdev->id != sdev->id ||
-		    tmp_sdev->queue_depth == sdev->max_queue_depth)
+	sstarg_for_each_device(tmp_sdev, starg) {
+		if (tmp_sdev->queue_depth == sdev->max_queue_depth)
 			continue;
 
 		scsi_change_queue_depth(tmp_sdev, tmp_sdev->queue_depth + 1);
@@ -672,25 +670,26 @@ static void scsi_handle_queue_ramp_up(struct scsi_device *sdev)
 	}
 }
 
+/*
+ * queue_full corresponds to the SCSI status: "Task Set Full". Its scope is
+ * at the SCSI taret device level.
+ */
 static void scsi_handle_queue_full(struct scsi_device *sdev)
 {
 	struct scsi_host_template *sht = sdev->host->hostt;
 	struct scsi_device *tmp_sdev;
+	struct scsi_target *starg = scsi_target(sdev);
 
 	if (!sht->track_queue_depth)
 		return;
 
-	shost_for_each_device(tmp_sdev, sdev->host) {
-		if (tmp_sdev->channel != sdev->channel ||
-		    tmp_sdev->id != sdev->id)
-			continue;
+	sstarg_for_each_device(tmp_sdev, starg)
 		/*
 		 * We do not know the number of commands that were at
-		 * the device when we got the queue full so we start
+		 * the target when we got the queue full so we start
 		 * from the highest possible value and work our way down.
 		 */
 		scsi_track_queue_full(tmp_sdev, tmp_sdev->queue_depth - 1);
-	}
 }
 
 /**
@@ -2305,12 +2304,13 @@ EXPORT_SYMBOL(scsi_report_bus_reset);
 void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 {
 	struct scsi_device *sdev;
+	struct scsi_target *starg = __scsi_target_lookup(shost, channel,
+							 target);
 
-	__shost_for_each_device(sdev, shost) {
-		if (channel == sdev_channel(sdev) &&
-		    target == sdev_id(sdev))
-			__scsi_report_device_reset(sdev, NULL);
-	}
+	if (!starg)
+		return;
+	__sstarg_for_each_device(sdev, starg)
+		__scsi_report_device_reset(sdev, NULL);
 }
 EXPORT_SYMBOL(scsi_report_device_reset);
 
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index f484bf2b5d7d..034ec2e57d1c 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -374,7 +374,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
 	struct Scsi_Host *shost = current_sdev->host;
 	struct scsi_device *sdev;
 	struct scsi_target *starget = scsi_target(current_sdev);
-	unsigned long flags, l_idx;
+	unsigned long flags;
 
 	spin_lock_irqsave(shost->host_lock, flags);
 	starget->starget_sdev_user = NULL;
@@ -392,7 +392,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
 	if (starget->starget_sdev_user)
 		goto out;
 	/* XARRAY: was list_for_each_entry_safe(); is this safe ? */
-	xa_for_each(&starget->devices, l_idx, sdev) {
+	__sstarg_for_each_device(sdev, starget) {
 		if (sdev == current_sdev)
 			continue;
 		if (scsi_device_get(sdev))
@@ -2217,14 +2217,12 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries,
 }
 EXPORT_SYMBOL(scsi_test_unit_ready);
 
-/* Assume host_lock taken and that xahp->xa_lock is the same lock. */
 static inline void
 scsi_adjust_non_sdev_del_mark(struct scsi_device *sdev,
 			      enum scsi_device_state old_state,
 			      enum scsi_device_state new_state)
 {
-	struct xarray *xatp =
-			&to_scsi_target(sdev->sdev_gendev.parent)->devices;
+	struct xarray *xatp = &scsi_target(sdev)->devices;
 	struct xarray *xahp = &sdev->host->__devices;
 
 	if (old_state == new_state)
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index f5a5e48ca5ae..c055ee083ea9 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1880,13 +1880,13 @@ void scsi_forget_host(struct Scsi_Host *shost)
 	struct scsi_device *sdev;
 	unsigned long flags, l_idx;
 
- restart:
 	spin_lock_irqsave(shost->host_lock, flags);
 	xa_for_each_marked(&shost->__devices, l_idx, sdev,
 			   SCSI_XA_NON_SDEV_DEL) {
 		spin_unlock_irqrestore(shost->host_lock, flags);
 		__scsi_remove_device(sdev);
-		goto restart;
+		/* XARRAY: was a goto to before first line */
+		spin_lock_irqsave(shost->host_lock, flags);
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
 }
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index 6fdd4648f374..394230d69afd 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1480,7 +1480,6 @@ static void __scsi_remove_target(struct scsi_target *starget)
 	unsigned long flags, l_idx;
 
 	spin_lock_irqsave(shost->host_lock, flags);
- restart:
 	xa_for_each_marked(&starget->devices, l_idx, sdev,
 			   SCSI_XA_NON_SDEV_DEL) {
 		/*
@@ -1496,8 +1495,7 @@ static void __scsi_remove_target(struct scsi_target *starget)
 		scsi_remove_device(sdev);
 		put_device(&sdev->sdev_gendev);
 		spin_lock_irqsave(shost->host_lock, flags);
-		/* XARRAY: is this goto start of loop correct ? */
-		goto restart;
+		/* XARRAY: was a goto to restart loop */
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
 }
@@ -1516,7 +1514,6 @@ void scsi_remove_target(struct device *dev)
 	struct scsi_target *starget;
 	unsigned long flags, l_idx;
 
-restart:
 	spin_lock_irqsave(shost->host_lock, flags);
 	xa_for_each(&shost->__targets, l_idx, starget) {
 		if (starget->state == STARGET_DEL ||
@@ -1532,7 +1529,8 @@ void scsi_remove_target(struct device *dev)
 			spin_unlock_irqrestore(shost->host_lock, flags);
 			__scsi_remove_target(starget);
 			scsi_target_reap(starget);
-			goto restart;
+			/* XARRAY: was a goto to before first line */
+			spin_lock_irqsave(shost->host_lock, flags);
 		}
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 23bf686cbabc..e019621416d5 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -362,6 +362,8 @@ extern struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *,
 							u64);
 extern struct scsi_device *__scsi_device_lookup_by_target(struct scsi_target *,
 							  u64);
+extern struct scsi_target *__scsi_target_lookup(struct Scsi_Host *shost,
+						uint chan, uint t_id);
 /* XARRAY: these visitor names too close to sstarg_for_each_device macros? */
 extern void starget_for_each_device(struct scsi_target *, void *,
 		     void (*fn)(struct scsi_device *, void *));
-- 
2.25.1


  parent reply	other threads:[~2020-05-24 15:58 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-24 15:58 [RFC v2 0/6] scsi: rework mid-layer with xarrays Douglas Gilbert
2020-05-24 15:58 ` [RFC v2 1/6] scsi: xarray hctl Douglas Gilbert
2020-05-25  6:57   ` Hannes Reinecke
2020-05-25 16:30     ` Douglas Gilbert
2020-05-25 17:40       ` Matthew Wilcox
2020-05-26  2:01         ` Douglas Gilbert
2020-05-26  3:01           ` Matthew Wilcox
2020-05-26  7:24           ` Hannes Reinecke
2020-05-26  6:21         ` Hannes Reinecke
2020-05-26 14:27           ` Matthew Wilcox
2020-05-26 17:53             ` Hannes Reinecke
2020-05-26 18:39               ` Matthew Wilcox
2020-05-26 19:28                 ` James Bottomley
2020-05-26 19:10               ` Douglas Gilbert
2020-05-26 20:27                 ` Douglas Gilbert
2020-05-27  2:53                   ` Douglas Gilbert
2020-05-24 15:58 ` [RFC v2 2/6] scsi: xarray, iterations on scsi_target Douglas Gilbert
2020-05-25  7:06   ` Hannes Reinecke
2020-05-24 15:58 ` [RFC v2 3/6] scsi: xarray mark sdev_del state Douglas Gilbert
2020-05-25  7:00   ` Hannes Reinecke
2020-05-25 16:47     ` Douglas Gilbert
2020-05-24 15:58 ` [RFC v2 4/6] scsi: improve scsi_device_lookup Douglas Gilbert
2020-05-25  7:07   ` Hannes Reinecke
2020-05-24 15:58 ` Douglas Gilbert [this message]
2020-05-24 15:58 ` [RFC v2 6/6] scsi: count number of targets Douglas Gilbert

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=20200524155814.5895-6-dgilbert@interlog.com \
    --to=dgilbert@interlog.com \
    --cc=hare@suse.de \
    --cc=jejb@linux.vnet.ibm.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.