aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libfc/fc_rport.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-09-30 11:01:15 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2016-11-08 17:29:46 -0500
commita407c593398c886db4fa1fc5c6fec55e61187a09 (patch)
tree5428a0f043492514d1d3c0b6097a511f46967a29 /drivers/scsi/libfc/fc_rport.c
parentscsi: libfc: Revisit kref handling (diff)
downloadlinux-dev-a407c593398c886db4fa1fc5c6fec55e61187a09.tar.xz
linux-dev-a407c593398c886db4fa1fc5c6fec55e61187a09.zip
scsi: libfc: Fixup disc_mutex handling
The list of attached 'rdata' remote port structures is RCU protected, so there is no need to take the 'disc_mutex' when traversing it. Rather we should be using rcu_read_lock() and kref_get_unless_zero() to validate the entries. We need, however, take the disc_mutex when deleting an entry; otherwise we risk clashes with list_add. Signed-off-by: Hannes Reinecke <hare@suse.com> Acked-by: Johannes Thumshirn <jth@kernel.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/libfc/fc_rport.c')
-rw-r--r--drivers/scsi/libfc/fc_rport.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c
index 4ec896e42120..a0ceba10c679 100644
--- a/drivers/scsi/libfc/fc_rport.c
+++ b/drivers/scsi/libfc/fc_rport.c
@@ -378,7 +378,9 @@ static void fc_rport_work(struct work_struct *work)
mutex_unlock(&rdata->rp_mutex);
} else {
FC_RPORT_DBG(rdata, "work delete\n");
+ mutex_lock(&lport->disc.disc_mutex);
list_del_rcu(&rdata->peers);
+ mutex_unlock(&lport->disc.disc_mutex);
mutex_unlock(&rdata->rp_mutex);
kref_put(&rdata->kref, lport->tt.rport_destroy);
}