Patch "scsi: scsi_dh_alua: Avoid crash during alua_bus_detach()" has been added to the 4.9-stable tree

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

 



This is a note to let you know that I've just added the patch titled

    scsi: scsi_dh_alua: Avoid crash during alua_bus_detach()

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     scsi-scsi_dh_alua-avoid-crash-during-alua_bus_detach.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 8a3cc8c8ecab314f8bcff1e204b9c2f76b6fd938
Author: Hannes Reinecke <hare@xxxxxxx>
Date:   Thu Sep 24 12:45:59 2020 +0200

    scsi: scsi_dh_alua: Avoid crash during alua_bus_detach()
    
    [ Upstream commit 5faf50e9e9fdc2117c61ff7e20da49cd6a29e0ca ]
    
    alua_bus_detach() might be running concurrently with alua_rtpg_work(), so
    we might trip over h->sdev == NULL and call BUG_ON().  The correct way of
    handling it is to not set h->sdev to NULL in alua_bus_detach(), and call
    rcu_synchronize() before the final delete to ensure that all concurrent
    threads have left the critical section.  Then we can get rid of the
    BUG_ON() and replace it with a simple if condition.
    
    Link: https://lore.kernel.org/r/1600167537-12509-1-git-send-email-jitendra.khasdev@xxxxxxxxxx
    Link: https://lore.kernel.org/r/20200924104559.26753-1-hare@xxxxxxx
    Cc: Brian Bunker <brian@xxxxxxxxxxxxxxx>
    Acked-by: Brian Bunker <brian@xxxxxxxxxxxxxxx>
    Tested-by: Jitendra Khasdev <jitendra.khasdev@xxxxxxxxxx>
    Reviewed-by: Jitendra Khasdev <jitendra.khasdev@xxxxxxxxxx>
    Signed-off-by: Hannes Reinecke <hare@xxxxxxx>
    Signed-off-by: Martin K. Petersen <martin.petersen@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 60c288526355a..2bc3dc6244a5e 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -657,8 +657,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
 					rcu_read_lock();
 					list_for_each_entry_rcu(h,
 						&tmp_pg->dh_list, node) {
-						/* h->sdev should always be valid */
-						BUG_ON(!h->sdev);
+						if (!h->sdev)
+							continue;
 						h->sdev->access_state = desc[0];
 					}
 					rcu_read_unlock();
@@ -704,7 +704,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg)
 			pg->expiry = 0;
 			rcu_read_lock();
 			list_for_each_entry_rcu(h, &pg->dh_list, node) {
-				BUG_ON(!h->sdev);
+				if (!h->sdev)
+					continue;
 				h->sdev->access_state =
 					(pg->state & SCSI_ACCESS_STATE_MASK);
 				if (pg->pref)
@@ -1149,7 +1150,6 @@ static void alua_bus_detach(struct scsi_device *sdev)
 	spin_lock(&h->pg_lock);
 	pg = h->pg;
 	rcu_assign_pointer(h->pg, NULL);
-	h->sdev = NULL;
 	spin_unlock(&h->pg_lock);
 	if (pg) {
 		spin_lock_irq(&pg->lock);
@@ -1158,6 +1158,7 @@ static void alua_bus_detach(struct scsi_device *sdev)
 		kref_put(&pg->kref, release_port_group);
 	}
 	sdev->handler_data = NULL;
+	synchronize_rcu();
 	kfree(h);
 }
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux