[PATCH v6 10/10] scsi_transport_sas: avoid dev_to_shost() walks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



While dev_to_shost() is a solid implementation of a runtime type
identification (RTTI) scheme, within the scope of a Scsi_Host
object (e.g. representing a HBA) the answer is always the same!
So cache the answer for the sas_phy and sas_rphy cases. This
should marginally improve the speed of about half the functions
defined in scsi_transport_sas.c .

Signed-off-by: Douglas Gilbert <dgilbert@xxxxxxxxxxxx>
---
 drivers/scsi/scsi_transport_sas.c | 40 +++++++++++++++----------------
 include/scsi/scsi_transport_sas.h |  8 +++++--
 2 files changed, 26 insertions(+), 22 deletions(-)

diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index c9abed8429c9..8d52de5d0957 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -171,7 +171,7 @@ static struct sas_end_device *sas_sdev_to_rdev(struct scsi_device *sdev)
 
 static int sas_smp_dispatch(struct bsg_job *job)
 {
-	struct Scsi_Host *shost = dev_to_shost(job->dev);
+	struct Scsi_Host *shost;
 	struct sas_rphy *rphy = NULL;
 
 	if (!scsi_is_host_device(job->dev))
@@ -183,6 +183,7 @@ static int sas_smp_dispatch(struct bsg_job *job)
 		return 0;
 	}
 
+	shost = rphy->shost;
 	to_sas_internal(shost->transportt)->f->smp_handler(job, shost, rphy);
 	return 0;
 }
@@ -462,7 +463,7 @@ store_sas_phy_##field(struct device *dev, 				\
 		      const char *buf,	size_t count)			\
 {									\
 	struct sas_phy *phy = transport_class_to_phy(dev);		\
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
+	struct Scsi_Host *shost = phy->shost;				\
 	struct sas_internal *i = to_sas_internal(shost->transportt);	\
 	u32 value;							\
 	struct sas_phy_linkrates rates = {0};				\
@@ -494,7 +495,7 @@ show_sas_phy_##field(struct device *dev, 				\
 		     struct device_attribute *attr, char *buf)		\
 {									\
 	struct sas_phy *phy = transport_class_to_phy(dev);		\
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);	\
+	struct Scsi_Host *shost = phy->shost;				\
 	struct sas_internal *i = to_sas_internal(shost->transportt);	\
 	int error;							\
 									\
@@ -525,7 +526,7 @@ static ssize_t do_sas_phy_enable(struct device *dev,
 		size_t count, int enable)
 {
 	struct sas_phy *phy = transport_class_to_phy(dev);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
+	struct Scsi_Host *shost = phy->shost;
 	struct sas_internal *i = to_sas_internal(shost->transportt);
 	int error;
 
@@ -573,8 +574,7 @@ static ssize_t
 do_sas_phy_reset(struct device *dev, size_t count, int hard_reset)
 {
 	struct sas_phy *phy = transport_class_to_phy(dev);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-	struct sas_internal *i = to_sas_internal(shost->transportt);
+	struct sas_internal *i = to_sas_internal(phy->shost->transportt);
 	int error;
 
 	error = i->f->phy_reset(phy, hard_reset);
@@ -621,8 +621,7 @@ static int sas_phy_setup(struct transport_container *tc, struct device *dev,
 			 struct device *cdev)
 {
 	struct sas_phy *phy = dev_to_phy(dev);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-	struct sas_internal *i = to_sas_internal(shost->transportt);
+	struct sas_internal *i = to_sas_internal(phy->shost->transportt);
 
 	if (i->f->phy_setup)
 		i->f->phy_setup(phy);
@@ -640,7 +639,7 @@ static int sas_phy_match(struct attribute_container *cont, struct device *dev)
 
 	if (!scsi_is_sas_phy(dev))
 		return 0;
-	shost = dev_to_shost(dev->parent);
+	shost = dev_to_phy(dev)->shost;
 
 	if (!shost->transportt)
 		return 0;
@@ -655,8 +654,7 @@ static int sas_phy_match(struct attribute_container *cont, struct device *dev)
 static void sas_phy_release(struct device *dev)
 {
 	struct sas_phy *phy = dev_to_phy(dev);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-	struct sas_internal *i = to_sas_internal(shost->transportt);
+	struct sas_internal *i = to_sas_internal(phy->shost->transportt);
 
 	if (i->f->phy_release)
 		i->f->phy_release(phy);
@@ -687,6 +685,7 @@ struct sas_phy *sas_phy_alloc(struct device *parent, int number)
 
 	phy->number = number;
 	phy->enabled = 1;
+	phy->shost = shost;
 
 	device_initialize(&phy->dev);
 	phy->dev.parent = get_device(parent);
@@ -806,6 +805,7 @@ static int sas_port_match(struct attribute_container *cont, struct device *dev)
 
 	if (!scsi_is_sas_port(dev))
 		return 0;
+	/* Could dev_to_sas_port(dev) and if port non-NULL use rphy->shost */
 	shost = dev_to_shost(dev->parent);
 
 	if (!shost->transportt)
@@ -1180,8 +1180,7 @@ show_sas_rphy_enclosure_identifier(struct device *dev,
 {
 	struct sas_rphy *rphy = transport_class_to_rphy(dev);
 	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-	struct sas_internal *i = to_sas_internal(shost->transportt);
+	struct sas_internal *i = to_sas_internal(phy->shost->transportt);
 	u64 identifier;
 	int error;
 
@@ -1200,8 +1199,7 @@ show_sas_rphy_bay_identifier(struct device *dev,
 {
 	struct sas_rphy *rphy = transport_class_to_rphy(dev);
 	struct sas_phy *phy = dev_to_phy(rphy->dev.parent);
-	struct Scsi_Host *shost = dev_to_shost(phy->dev.parent);
-	struct sas_internal *i = to_sas_internal(shost->transportt);
+	struct sas_internal *i = to_sas_internal(phy->shost->transportt);
 	int val;
 
 	val = i->f->get_bay_identifier(rphy);
@@ -1327,7 +1325,7 @@ static int sas_rphy_match(struct attribute_container *cont, struct device *dev)
 
 	if (!scsi_is_sas_rphy(dev))
 		return 0;
-	shost = dev_to_shost(dev->parent->parent);
+	shost = dev_to_rphy(dev)->shost;
 
 	if (!shost->transportt)
 		return 0;
@@ -1348,8 +1346,8 @@ static int sas_end_dev_match(struct attribute_container *cont,
 
 	if (!scsi_is_sas_rphy(dev))
 		return 0;
-	shost = dev_to_shost(dev->parent->parent);
 	rphy = dev_to_rphy(dev);
+	shost = rphy->shost;
 
 	if (!shost->transportt)
 		return 0;
@@ -1371,8 +1369,8 @@ static int sas_expander_match(struct attribute_container *cont,
 
 	if (!scsi_is_sas_rphy(dev))
 		return 0;
-	shost = dev_to_shost(dev->parent->parent);
 	rphy = dev_to_rphy(dev);
+	shost = rphy->shost;
 
 	if (!shost->transportt)
 		return 0;
@@ -1436,6 +1434,7 @@ struct sas_rphy *sas_end_device_alloc(struct sas_port *parent)
 	}
 
 	device_initialize(&rdev->rphy.dev);
+	rdev->rphy.shost = shost;
 	rdev->rphy.dev.parent = get_device(&parent->dev);
 	rdev->rphy.dev.release = sas_end_device_release;
 	if (scsi_is_sas_expander_device(parent->dev.parent)) {
@@ -1480,6 +1479,7 @@ struct sas_rphy *sas_expander_alloc(struct sas_port *parent,
 	}
 
 	device_initialize(&rdev->rphy.dev);
+	rdev->rphy.shost = shost;
 	rdev->rphy.dev.parent = get_device(&parent->dev);
 	rdev->rphy.dev.release = sas_expander_release;
 	mutex_lock(&sas_host->lock);
@@ -1504,7 +1504,7 @@ EXPORT_SYMBOL(sas_expander_alloc);
 int sas_rphy_add(struct sas_rphy *rphy)
 {
 	struct sas_port *parent = dev_to_sas_port(rphy->dev.parent);
-	struct Scsi_Host *shost = dev_to_shost(parent->dev.parent);
+	struct Scsi_Host *shost = rphy->shost;
 	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
 	struct sas_identify *identify = &rphy->identify;
 	int error;
@@ -1563,7 +1563,7 @@ EXPORT_SYMBOL(sas_rphy_add);
 void sas_rphy_free(struct sas_rphy *rphy)
 {
 	struct device *dev = &rphy->dev;
-	struct Scsi_Host *shost = dev_to_shost(rphy->dev.parent->parent);
+	struct Scsi_Host *shost = rphy->shost;
 	struct sas_host_attrs *sas_host = to_sas_host_attrs(shost);
 
 	mutex_lock(&sas_host->lock);
diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h
index 05ec927a3c72..9f4c50358f82 100644
--- a/include/scsi/scsi_transport_sas.h
+++ b/include/scsi/scsi_transport_sas.h
@@ -9,6 +9,7 @@
 #include <linux/bsg-lib.h>
 
 struct scsi_transport_template;
+struct Scsi_Host;
 struct sas_rphy;
 struct request;
 
@@ -80,6 +81,8 @@ struct sas_phy {
 	/* for the list of phys belonging to a port */
 	struct list_head	port_siblings;
 
+	struct Scsi_Host	*shost;		/* cache to avoid dev_to_shost() walks */
+
 	/* available to the lldd */
 	void			*hostdata;
 };
@@ -89,7 +92,7 @@ struct sas_phy {
 #define transport_class_to_phy(dev) \
 	dev_to_phy((dev)->parent)
 #define phy_to_shost(phy) \
-	dev_to_shost((phy)->dev.parent)
+	((phy)->shost)
 
 struct request_queue;
 struct sas_rphy {
@@ -97,6 +100,7 @@ struct sas_rphy {
 	struct sas_identify	identify;
 	struct list_head	list;
 	struct request_queue	*q;
+	struct Scsi_Host	*shost;		/* cache to avoid dev_to_shost() walks */
 	u32			scsi_target_id;
 };
 
@@ -105,7 +109,7 @@ struct sas_rphy {
 #define transport_class_to_rphy(dev) \
 	dev_to_rphy((dev)->parent)
 #define rphy_to_shost(rphy) \
-	dev_to_shost((rphy)->dev.parent)
+	((rphy)->shost)
 #define target_to_rphy(targ) \
 	dev_to_rphy((targ)->dev.parent)
 
-- 
2.25.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux