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: [PATCH v5 7/9] scsi: add starget_to_shost() specialization
Date: Sun, 19 Jul 2020 22:57:40 -0400 [thread overview]
Message-ID: <20200720025742.349296-8-dgilbert@interlog.com> (raw)
In-Reply-To: <20200720025742.349296-1-dgilbert@interlog.com>
In the SCSI mid-layer object tree the host level and the target
level under it can be separated by transport supplied objects.
For example the SCSI SAS transport inserts SAS port objects.
To cope with this is a generic way there is function called
dev_to_host() function that loops back up the 'device' object
hierarchy asking at each level: "Are you a shost object?".
It does the job but it is not particulary efficient in the case
where the given object is a SCSI target. This is because when
a SCSI target object is created it knows its SCSI host object
and can hold that pointer value. So as long as a SCSI target
cannot change its parent SCSI host object "midstream" then
following that pointer (which is what starget_to_shost() does)
is safe and faster.
Signed-off-by: Douglas Gilbert <dgilbert@interlog.com>
---
drivers/scsi/scsi.c | 2 +-
drivers/scsi/scsi_scan.c | 11 ++++++-----
drivers/scsi/scsi_sysfs.c | 2 +-
include/scsi/scsi_device.h | 8 ++++++++
include/scsi/scsi_transport.h | 2 +-
5 files changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index 296cecd61d3a..9d0ce5959866 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -761,7 +761,7 @@ struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget,
u64 lun)
{
struct scsi_device *sdev;
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 41818111808e..5f4b8ed31a76 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -217,7 +217,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
{
struct scsi_device *sdev;
int display_failure_msg = 1, ret;
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
sdev = kzalloc(sizeof(*sdev) + shost->transportt->device_size,
GFP_KERNEL);
@@ -305,7 +305,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
static void scsi_target_destroy(struct scsi_target *starget)
{
struct device *dev = &starget->dev;
- struct Scsi_Host *shost = dev_to_shost(dev->parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
unsigned long flags;
unsigned long tid = scsi_target_index(starget);
@@ -424,6 +424,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
device_initialize(dev);
kref_init(&starget->reap_ref);
dev->parent = get_device(parent);
+ starget->parent_shost = shost; /* redundant but faster */
dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
dev->bus = &scsi_bus_type;
dev->type = &scsi_target_type;
@@ -1055,7 +1056,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
unsigned char *result;
blist_flags_t bflags;
int res = SCSI_SCAN_NO_RESPONSE, result_len = 256;
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
/*
* The rescan flag is used as an optimization, the first scan of a
@@ -1205,7 +1206,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
{
uint max_dev_lun;
u64 sparse_lun, lun;
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
SCSI_LOG_SCAN_BUS(3, starget_printk(KERN_INFO, starget,
"scsi scan: Sequential scan\n"));
@@ -1303,7 +1304,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, blist_flags_t bflag
struct scsi_lun *lunp, *lun_data;
struct scsi_sense_hdr sshdr;
struct scsi_device *sdev;
- struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+ struct Scsi_Host *shost = starget_to_shost(starget);
int ret = 0;
/*
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
index e30a058c6b33..0b5ede1b8ebe 100644
--- a/drivers/scsi/scsi_sysfs.c
+++ b/drivers/scsi/scsi_sysfs.c
@@ -1477,7 +1477,7 @@ EXPORT_SYMBOL(scsi_remove_device);
static void __scsi_remove_target(struct scsi_target *starget)
{
- struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+ struct Scsi_Host *shost = starget_to_shost(starget);
unsigned long flags;
struct scsi_device *sdev, *sdev_next;
unsigned long lun_idx = 0;
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 390a150cdaca..5292787246ca 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -281,12 +281,14 @@ enum scsi_target_state {
* scsi_target: representation of a scsi target, for now, this is only
* used for single_lun devices. If no one has active IO to the target,
* starget_sdev_user is NULL, else it points to the active sdev.
+ * * Invariant: starg->parent_shost == dev_to_shost(starg->dev.parent)
*/
struct scsi_target {
struct scsi_device *starget_sdev_user;
struct list_head siblings;
struct xarray __devices;
struct device dev;
+ struct Scsi_Host *parent_shost; /* redundant but faster */
struct kref reap_ref; /* last put renders target invisible */
u16 channel;
u16 id; /* target id ... replace
@@ -326,6 +328,12 @@ static inline u32 scsi_target_index(struct scsi_target *starget)
return (starget->channel << 16) | (starget->id);
}
+/* This is faster that doing dev_to_shost(starg->dev.parent) */
+static inline struct Scsi_Host *starget_to_shost(struct scsi_target *starg)
+{
+ return starg->parent_shost;
+}
+
#define to_scsi_target(d) container_of(d, struct scsi_target, dev)
static inline struct scsi_target *scsi_target(struct scsi_device *sdev)
{
diff --git a/include/scsi/scsi_transport.h b/include/scsi/scsi_transport.h
index a0458bda3148..5a2337ded7b0 100644
--- a/include/scsi/scsi_transport.h
+++ b/include/scsi/scsi_transport.h
@@ -70,7 +70,7 @@ scsi_transport_reserve_device(struct scsi_transport_template * t, int space)
static inline void *
scsi_transport_target_data(struct scsi_target *starget)
{
- struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+ struct Scsi_Host *shost = starget_to_shost(starget);
return (u8 *)starget->starget_data
+ shost->transportt->target_private_offset;
--
2.25.1
next prev parent reply other threads:[~2020-07-20 2:58 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-20 2:57 [PATCH v5 0/9] scsi: use xarray for devices and targets Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 1/9] scsi: convert target lookup to xarray Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 2/9] target_core_pscsi: use __scsi_device_lookup() Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 3/9] scsi: move target device list to xarray Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 4/9] scsi: remove direct device lookup per host Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 5/9] scsi_error: use xarray lookup instead of wrappers Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 6/9] scsi: avoid pointless memory allocation in scsi_alloc_target() Douglas Gilbert
2020-07-20 2:57 ` Douglas Gilbert [this message]
2020-07-20 2:57 ` [PATCH v5 8/9] scsi: simplify scsi_target() inline Douglas Gilbert
2020-07-20 2:57 ` [PATCH v5 9/9] scsi_host: switch ida to idr to hold shost ptr 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=20200720025742.349296-8-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 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).