aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe/fcoe_ctlr.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-05-24 02:11:58 -0400
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)
2496 struct fcoe_rport *frport; 2496 struct fcoe_rport *frport;
2497 int ret = -1; 2497 int ret = -1;
2498 2498
2499 rcu_read_lock();
2500 rdata = lport->tt.rport_lookup(lport, port_id); 2499 rdata = lport->tt.rport_lookup(lport, port_id);
2501 if (rdata) { 2500 if (rdata) {
2502 frport = fcoe_ctlr_rport(rdata); 2501 frport = fcoe_ctlr_rport(rdata);
2503 memcpy(mac, frport->enode_mac, ETH_ALEN); 2502 memcpy(mac, frport->enode_mac, ETH_ALEN);
2504 ret = 0; 2503 ret = 0;
2504 kref_put(&rdata->kref, lport->tt.rport_destroy);
2505 } 2505 }
2506 rcu_read_unlock();
2507 return ret; 2506 return ret;
2508} 2507}
2509 2508
@@ -2585,11 +2584,7 @@ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip,
2585 fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0); 2584 fcoe_ctlr_vn_send(fip, FIP_SC_VN_PROBE_REQ, fcoe_all_vn2vn, 0);
2586 return; 2585 return;
2587 } 2586 }
2588 mutex_lock(&lport->disc.disc_mutex);
2589 rdata = lport->tt.rport_lookup(lport, new->ids.port_id); 2587 rdata = lport->tt.rport_lookup(lport, new->ids.port_id);
2590 if (rdata)
2591 kref_get(&rdata->kref);
2592 mutex_unlock(&lport->disc.disc_mutex);
2593 if (rdata) { 2588 if (rdata) {
2594 if (rdata->ids.node_name == new->ids.node_name && 2589 if (rdata->ids.node_name == new->ids.node_name &&
2595 rdata->ids.port_name == new->ids.port_name) { 2590 rdata->ids.port_name == new->ids.port_name) {