|
@@ -557,38 +557,44 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
|
|
|
*
|
|
|
* Called with lock held and preemption disabled.
|
|
|
*
|
|
|
- * An FCF is considered old if we have missed three advertisements.
|
|
|
- * That is, there have been no valid advertisement from it for three
|
|
|
- * times its keep-alive period including fuzz.
|
|
|
+ * An FCF is considered old if we have missed two advertisements.
|
|
|
+ * That is, there have been no valid advertisement from it for 2.5
|
|
|
+ * times its keep-alive period.
|
|
|
*
|
|
|
* In addition, determine the time when an FCF selection can occur.
|
|
|
*
|
|
|
* Also, increment the MissDiscAdvCount when no advertisement is received
|
|
|
* for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
|
|
|
+ *
|
|
|
+ * Returns the time in jiffies for the next call.
|
|
|
*/
|
|
|
-static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
|
|
|
+static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
|
|
|
{
|
|
|
struct fcoe_fcf *fcf;
|
|
|
struct fcoe_fcf *next;
|
|
|
+ unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
|
|
|
+ unsigned long deadline;
|
|
|
unsigned long sel_time = 0;
|
|
|
- unsigned long mda_time = 0;
|
|
|
struct fcoe_dev_stats *stats;
|
|
|
|
|
|
list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
|
|
|
- mda_time = fcf->fka_period + (fcf->fka_period >> 1);
|
|
|
- if ((fip->sel_fcf == fcf) &&
|
|
|
- (time_after(jiffies, fcf->time + mda_time))) {
|
|
|
- mod_timer(&fip->timer, jiffies + mda_time);
|
|
|
- stats = per_cpu_ptr(fip->lp->dev_stats,
|
|
|
- smp_processor_id());
|
|
|
- stats->MissDiscAdvCount++;
|
|
|
- printk(KERN_INFO "libfcoe: host%d: Missing Discovery "
|
|
|
- "Advertisement for fab %16.16llx count %lld\n",
|
|
|
- fip->lp->host->host_no, fcf->fabric_name,
|
|
|
- stats->MissDiscAdvCount);
|
|
|
+ deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2;
|
|
|
+ if (fip->sel_fcf == fcf) {
|
|
|
+ if (time_after(jiffies, deadline)) {
|
|
|
+ stats = per_cpu_ptr(fip->lp->dev_stats,
|
|
|
+ smp_processor_id());
|
|
|
+ stats->MissDiscAdvCount++;
|
|
|
+ printk(KERN_INFO "libfcoe: host%d: "
|
|
|
+ "Missing Discovery Advertisement "
|
|
|
+ "for fab %16.16llx count %lld\n",
|
|
|
+ fip->lp->host->host_no, fcf->fabric_name,
|
|
|
+ stats->MissDiscAdvCount);
|
|
|
+ } else if (time_after(next_timer, deadline))
|
|
|
+ next_timer = deadline;
|
|
|
}
|
|
|
- if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
|
|
|
- msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
|
|
|
+
|
|
|
+ deadline += fcf->fka_period;
|
|
|
+ if (time_after(jiffies, deadline)) {
|
|
|
if (fip->sel_fcf == fcf)
|
|
|
fip->sel_fcf = NULL;
|
|
|
list_del(&fcf->list);
|
|
@@ -598,19 +604,21 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
|
|
|
stats = per_cpu_ptr(fip->lp->dev_stats,
|
|
|
smp_processor_id());
|
|
|
stats->VLinkFailureCount++;
|
|
|
- } else if (fcoe_ctlr_mtu_valid(fcf) &&
|
|
|
- (!sel_time || time_before(sel_time, fcf->time))) {
|
|
|
- sel_time = fcf->time;
|
|
|
+ } else {
|
|
|
+ if (time_after(next_timer, deadline))
|
|
|
+ next_timer = deadline;
|
|
|
+ if (fcoe_ctlr_mtu_valid(fcf) &&
|
|
|
+ (!sel_time || time_before(sel_time, fcf->time)))
|
|
|
+ sel_time = fcf->time;
|
|
|
}
|
|
|
}
|
|
|
if (sel_time) {
|
|
|
sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
|
|
|
fip->sel_time = sel_time;
|
|
|
- if (time_before(sel_time, fip->timer.expires))
|
|
|
- mod_timer(&fip->timer, sel_time);
|
|
|
} else {
|
|
|
fip->sel_time = 0;
|
|
|
}
|
|
|
+ return next_timer;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1148,7 +1156,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
|
|
|
struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg;
|
|
|
struct fcoe_fcf *sel;
|
|
|
struct fcoe_fcf *fcf;
|
|
|
- unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
|
|
|
+ unsigned long next_timer;
|
|
|
|
|
|
spin_lock_bh(&fip->lock);
|
|
|
if (fip->state == FIP_ST_DISABLED) {
|
|
@@ -1157,13 +1165,16 @@ static void fcoe_ctlr_timeout(unsigned long arg)
|
|
|
}
|
|
|
|
|
|
fcf = fip->sel_fcf;
|
|
|
- fcoe_ctlr_age_fcfs(fip);
|
|
|
+ next_timer = fcoe_ctlr_age_fcfs(fip);
|
|
|
|
|
|
sel = fip->sel_fcf;
|
|
|
- if (!sel && fip->sel_time && time_after_eq(jiffies, fip->sel_time)) {
|
|
|
- fcoe_ctlr_select(fip);
|
|
|
- sel = fip->sel_fcf;
|
|
|
- fip->sel_time = 0;
|
|
|
+ if (!sel && fip->sel_time) {
|
|
|
+ if (time_after_eq(jiffies, fip->sel_time)) {
|
|
|
+ fcoe_ctlr_select(fip);
|
|
|
+ sel = fip->sel_fcf;
|
|
|
+ fip->sel_time = 0;
|
|
|
+ } else if (time_after(next_timer, fip->sel_time))
|
|
|
+ next_timer = fip->sel_time;
|
|
|
}
|
|
|
|
|
|
if (sel != fcf) {
|
|
@@ -1201,12 +1212,9 @@ static void fcoe_ctlr_timeout(unsigned long arg)
|
|
|
}
|
|
|
if (time_after(next_timer, fip->port_ka_time))
|
|
|
next_timer = fip->port_ka_time;
|
|
|
- mod_timer(&fip->timer, next_timer);
|
|
|
- } else if (fip->sel_time) {
|
|
|
- next_timer = fip->sel_time +
|
|
|
- msecs_to_jiffies(FCOE_CTLR_START_DELAY);
|
|
|
- mod_timer(&fip->timer, next_timer);
|
|
|
}
|
|
|
+ if (!list_empty(&fip->fcfs))
|
|
|
+ mod_timer(&fip->timer, next_timer);
|
|
|
if (fip->send_ctlr_ka || fip->send_port_ka)
|
|
|
schedule_work(&fip->timer_work);
|
|
|
spin_unlock_bh(&fip->lock);
|