summaryrefslogtreecommitdiff
path: root/drivers/scsi/fcoe/fcoe_ctlr.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-05-24 08:11:58 +0200
committerMartin K. Petersen <martin.petersen@oracle.com>2016-07-12 23:16:31 -0400
commitbaa6719f902af9c03e528b08dfb847de295b5137 (patch)
tree8ac928054932e15da8feaa5a60b7385ab0787958 /drivers/scsi/fcoe/fcoe_ctlr.c
parent7e1ee4412ca35b17e21159d85224e37e8f259311 (diff)
libfc: Update rport reference counting
Originally libfc would just be initializing the refcount to '1', and using the disc_mutex to synchronize if and when the final put should be happening. This has a race condition as the mutex might be delayed, causing other threads to access an invalid structure. This patch updates the rport reference counting to increase the reference every time 'rport_lookup' is called, and decreases the reference correspondingly. This removes the need to hold 'disc_mutex' when removing the structure, and avoids the above race condition. Signed-off-by: Hannes Reinecke <hare@suse.com> Acked-by: Vasu Dev <vasu.dev@intel.com> Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/fcoe/fcoe_ctlr.c')
-rw-r--r--drivers/scsi/fcoe/fcoe_ctlr.c7
1 files changed, 1 insertions, 6 deletions
diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c
index 3e83d485f743..ada4bdec9a4c 100644
--- a/drivers/scsi/fcoe/fcoe_ctlr.c
+++ b/drivers/scsi/fcoe/fcoe_ctlr.c
@@ -2496,14 +2496,13 @@ static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *fip, u32 port_id, u8 *mac)
struct fcoe_rport *frport;
int ret = -1;
- rcu_read_lock();
rdata = lport->tt.rport_lookup(lport, port_id);
if (rdata) {
frport = fcoe_ctlr_rport(rdata);
memcpy(mac, frport->enode_mac, ETH_ALEN);
ret = 0;
+ kref_put(&rdata->kref, lport->tt.rport_destroy);
}
- rcu_read_unlock();
return ret;
}
@@ -2585,11 +2584,7 @@ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
return;
}
- mutex_lock(&lport->disc.disc_mutex);
rdata = lport->tt.rport_lookup(lport, new->ids.port_id);
- if (rdata)
- kref_get(&rdata->kref);
- mutex_unlock(&lport->disc.disc_mutex);
if (rdata) {
if (rdata->ids.node_name == new->ids.node_name &&
rdata->ids.port_name == new->ids.port_name) {