Skip to content

Commit

Permalink
scsi: fcoe: hold disc_mutex when traversing rport lists
Browse files Browse the repository at this point in the history
When calling either fc_rport_logon() or fc_rport_logoff() during rport list
traversal we cannot use the RCU list traversal, as either of these
functions will be taking a mutex.  So we need to partially revert commit
a407c59 to take the disc mutex during traversal.  We should, however,
continue to use krefs to ensure that the rport object will not be freed
from under us.

Fixes: a407c59 ("scsi: libfc: Fixup disc_mutex handling")
Signed-off-by: Hannes Reinecke <[email protected]>
Reviewed-by: Johannes Thumshirn <[email protected]>
Signed-off-by: Martin K. Petersen <[email protected]>
  • Loading branch information
hreinecke authored and martinkpetersen committed Jul 13, 2018
1 parent bbc0f8b commit 0993ed9
Showing 1 changed file with 4 additions and 8 deletions.
12 changes: 4 additions & 8 deletions drivers/scsi/fcoe/fcoe_ctlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2175,15 +2175,13 @@ static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport)
{
struct fc_rport_priv *rdata;

rcu_read_lock();
mutex_lock(&lport->disc.disc_mutex);
list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) {
if (kref_get_unless_zero(&rdata->kref)) {
fc_rport_logoff(rdata);
kref_put(&rdata->kref, fc_rport_destroy);
}
}
rcu_read_unlock();
mutex_lock(&lport->disc.disc_mutex);
lport->disc.disc_callback = NULL;
mutex_unlock(&lport->disc.disc_mutex);
}
Expand Down Expand Up @@ -2712,7 +2710,7 @@ static unsigned long fcoe_ctlr_vn_age(struct fcoe_ctlr *fip)
unsigned long deadline;

next_time = jiffies + msecs_to_jiffies(FIP_VN_BEACON_INT * 10);
rcu_read_lock();
mutex_lock(&lport->disc.disc_mutex);
list_for_each_entry_rcu(rdata, &lport->disc.rports, peers) {
if (!kref_get_unless_zero(&rdata->kref))
continue;
Expand All @@ -2733,7 +2731,7 @@ static unsigned long fcoe_ctlr_vn_age(struct fcoe_ctlr *fip)
next_time = deadline;
kref_put(&rdata->kref, fc_rport_destroy);
}
rcu_read_unlock();
mutex_unlock(&lport->disc.disc_mutex);
return next_time;
}

Expand Down Expand Up @@ -3080,8 +3078,6 @@ static void fcoe_ctlr_vn_disc(struct fcoe_ctlr *fip)
mutex_lock(&disc->disc_mutex);
callback = disc->pending ? disc->disc_callback : NULL;
disc->pending = 0;
mutex_unlock(&disc->disc_mutex);
rcu_read_lock();
list_for_each_entry_rcu(rdata, &disc->rports, peers) {
if (!kref_get_unless_zero(&rdata->kref))
continue;
Expand All @@ -3090,7 +3086,7 @@ static void fcoe_ctlr_vn_disc(struct fcoe_ctlr *fip)
fc_rport_login(rdata);
kref_put(&rdata->kref, fc_rport_destroy);
}
rcu_read_unlock();
mutex_unlock(&disc->disc_mutex);
if (callback)
callback(lport, DISC_EV_SUCCESS);
}
Expand Down

0 comments on commit 0993ed9

Please sign in to comment.