]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
Revert "scsi: libsas: direct call probe and destruct"
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Aug 2020 09:49:14 +0000 (11:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 7 Aug 2020 07:38:40 +0000 (09:38 +0200)
This reverts commit 3a156abd24346a3188eb7e88cf86386a409e0d02 which is
commit 0558f33c06bb910e2879e355192227a8e8f0219d upstream.

John writes:
This patch was one of a series from Jason to fix this WARN issue, below:

https://lore.kernel.org/linux-scsi/8f6e3763-2b04-23e8-f1ec-8ed3c58f55d3@huawei.com/

I'm doubtful that it should be taken in isolation. Maybe 1 or 2 other
patches are required.

The WARN was really annoying, so we could spend a bit of time to test a
backport of what is strictly required. Let us know.

Cc: Jason Yan <yanaijie@huawei.com>
CC: John Garry <john.garry@huawei.com>
CC: Johannes Thumshirn <jthumshirn@suse.de>
CC: Ewan Milne <emilne@redhat.com>
CC: Christoph Hellwig <hch@lst.de>
CC: Tomas Henzl <thenzl@redhat.com>
CC: Dan Williams <dan.j.williams@intel.com>
Cc: Hannes Reinecke <hare@suse.com>
Cc: Martin K. Petersen <martin.petersen@oracle.com>
Cc: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/scsi/libsas/sas_ata.c
drivers/scsi/libsas/sas_discover.c
drivers/scsi/libsas/sas_expander.c
drivers/scsi/libsas/sas_internal.h
drivers/scsi/libsas/sas_port.c
include/scsi/libsas.h
include/scsi/scsi_transport_sas.h

index 2b3637b40dde9b74d42fd521f854a541c7977e61..70be4425ae0be495c0d08d3408a20c3c7d90d6a7 100644 (file)
@@ -730,6 +730,7 @@ int sas_discover_sata(struct domain_device *dev)
        if (res)
                return res;
 
+       sas_discover_event(dev->port, DISCE_PROBE);
        return 0;
 }
 
index d6365e2fcc60376fadbd3aef683ca4b883f78f0e..b200edc665a58f83c560213175f3bc6e26a192d0 100644 (file)
@@ -221,9 +221,13 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev)
        }
 }
 
-static void sas_probe_devices(struct asd_sas_port *port)
+static void sas_probe_devices(struct work_struct *work)
 {
        struct domain_device *dev, *n;
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
+       struct asd_sas_port *port = ev->port;
+
+       clear_bit(DISCE_PROBE, &port->disc.pending);
 
        /* devices must be domain members before link recovery and probe */
        list_for_each_entry(dev, &port->disco_list, disco_list_node) {
@@ -299,6 +303,7 @@ int sas_discover_end_dev(struct domain_device *dev)
        res = sas_notify_lldd_dev_found(dev);
        if (res)
                return res;
+       sas_discover_event(dev->port, DISCE_PROBE);
 
        return 0;
 }
@@ -357,9 +362,13 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d
        sas_put_device(dev);
 }
 
-void sas_destruct_devices(struct asd_sas_port *port)
+static void sas_destruct_devices(struct work_struct *work)
 {
        struct domain_device *dev, *n;
+       struct sas_discovery_event *ev = to_sas_discovery_event(work);
+       struct asd_sas_port *port = ev->port;
+
+       clear_bit(DISCE_DESTRUCT, &port->disc.pending);
 
        list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) {
                list_del_init(&dev->disco_list_node);
@@ -370,16 +379,6 @@ void sas_destruct_devices(struct asd_sas_port *port)
        }
 }
 
-static void sas_destruct_ports(struct asd_sas_port *port)
-{
-       struct sas_port *sas_port, *p;
-
-       list_for_each_entry_safe(sas_port, p, &port->sas_port_del_list, del_list) {
-               list_del_init(&sas_port->del_list);
-               sas_port_delete(sas_port);
-       }
-}
-
 void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
 {
        if (!test_bit(SAS_DEV_DESTROY, &dev->state) &&
@@ -394,6 +393,7 @@ void sas_unregister_dev(struct asd_sas_port *port, struct domain_device *dev)
        if (!test_and_set_bit(SAS_DEV_DESTROY, &dev->state)) {
                sas_rphy_unlink(dev->rphy);
                list_move_tail(&dev->disco_list_node, &port->destroy_list);
+               sas_discover_event(dev->port, DISCE_DESTRUCT);
        }
 }
 
@@ -499,8 +499,6 @@ static void sas_discover_domain(struct work_struct *work)
                port->port_dev = NULL;
        }
 
-       sas_probe_devices(port);
-
        SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id,
                    task_pid_nr(current), error);
 }
@@ -534,10 +532,6 @@ static void sas_revalidate_domain(struct work_struct *work)
                    port->id, task_pid_nr(current), res);
  out:
        mutex_unlock(&ha->disco_mutex);
-
-       sas_destruct_devices(port);
-       sas_destruct_ports(port);
-       sas_probe_devices(port);
 }
 
 /* ---------- Events ---------- */
@@ -593,8 +587,10 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port)
        static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = {
                [DISCE_DISCOVER_DOMAIN] = sas_discover_domain,
                [DISCE_REVALIDATE_DOMAIN] = sas_revalidate_domain,
+               [DISCE_PROBE] = sas_probe_devices,
                [DISCE_SUSPEND] = sas_suspend_devices,
                [DISCE_RESUME] = sas_resume_devices,
+               [DISCE_DESTRUCT] = sas_destruct_devices,
        };
 
        disc->pending = 0;
index 84df6cf46760574972114d9e3fadf2beb5a02d1a..f77d72f01da91580c8d92500bb74906bd638eadb 100644 (file)
@@ -1946,8 +1946,7 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent,
                sas_port_delete_phy(phy->port, phy->phy);
                sas_device_set_phy(found, phy->port);
                if (phy->port->num_phys == 0)
-                       list_add_tail(&phy->port->del_list,
-                               &parent->port->sas_port_del_list);
+                       sas_port_delete(phy->port);
                phy->port = NULL;
        }
 }
@@ -2157,7 +2156,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev)
        struct domain_device *dev = NULL;
 
        res = sas_find_bcast_dev(port_dev, &dev);
-       if (res == 0 && dev) {
+       while (res == 0 && dev) {
                struct expander_device *ex = &dev->ex_dev;
                int i = 0, phy_id;
 
@@ -2169,6 +2168,9 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev)
                        res = sas_rediscover(dev, phy_id);
                        i = phy_id + 1;
                } while (i < ex->num_phys);
+
+               dev = NULL;
+               res = sas_find_bcast_dev(port_dev, &dev);
        }
        return res;
 }
index f3449fde9c5fb1543b9a4158ce94dd636aacdae1..c07e0813649153d609f52e166c39b51a032a9e49 100644 (file)
@@ -98,7 +98,6 @@ int sas_try_ata_reset(struct asd_sas_phy *phy);
 void sas_hae_reset(struct work_struct *work);
 
 void sas_free_device(struct kref *kref);
-void sas_destruct_devices(struct asd_sas_port *port);
 
 #ifdef CONFIG_SCSI_SAS_HOST_SMP
 extern void sas_smp_host_handler(struct bsg_job *job, struct Scsi_Host *shost);
index 5d3244c8f280121cb4ed6b8a4a646b54cb436db7..d3c5297c6c89e242d845d16142f7a309ed4ef773 100644 (file)
@@ -66,7 +66,6 @@ static void sas_resume_port(struct asd_sas_phy *phy)
                rc = sas_notify_lldd_dev_found(dev);
                if (rc) {
                        sas_unregister_dev(port, dev);
-                       sas_destruct_devices(port);
                        continue;
                }
 
@@ -220,7 +219,6 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone)
 
        if (port->num_phys == 1) {
                sas_unregister_domain_devices(port, gone);
-               sas_destruct_devices(port);
                sas_port_delete(port->port);
                port->port = NULL;
        } else {
@@ -325,7 +323,6 @@ static void sas_init_port(struct asd_sas_port *port,
        INIT_LIST_HEAD(&port->dev_list);
        INIT_LIST_HEAD(&port->disco_list);
        INIT_LIST_HEAD(&port->destroy_list);
-       INIT_LIST_HEAD(&port->sas_port_del_list);
        spin_lock_init(&port->phy_list_lock);
        INIT_LIST_HEAD(&port->phy_list);
        port->ha = sas_ha;
index 1b1cf9eff3b5a6777913a78f9478cc3a5df5dfad..a966d281dedc3bf7e68d9264e9b1b06b9b8bc75b 100644 (file)
@@ -87,8 +87,10 @@ enum discover_event {
        DISCE_DISCOVER_DOMAIN   = 0U,
        DISCE_REVALIDATE_DOMAIN = 1,
        DISCE_PORT_GONE         = 2,
+       DISCE_PROBE             = 3,
        DISCE_SUSPEND           = 4,
        DISCE_RESUME            = 5,
+       DISCE_DESTRUCT          = 6,
        DISC_NUM_EVENTS         = 7,
 };
 
@@ -267,7 +269,6 @@ struct asd_sas_port {
        struct list_head dev_list;
        struct list_head disco_list;
        struct list_head destroy_list;
-       struct list_head sas_port_del_list;
        enum   sas_linkrate linkrate;
 
        struct sas_work work;
index 05ec927a3c72988f62cfd5622aaf78dd74199fc0..62895b4059330d463d11ba33c9c0bbc3a4ae733a 100644 (file)
@@ -156,7 +156,6 @@ struct sas_port {
 
        struct mutex            phy_list_mutex;
        struct list_head        phy_list;
-       struct list_head        del_list; /* libsas only */
 };
 
 #define dev_to_sas_port(d) \