aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/fcoe
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/fcoe')
-rw-r--r--drivers/scsi/fcoe/libfcoe.c76
1 files changed, 42 insertions, 34 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 1d5b949d4fd0..3ab3db39fc52 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -557,38 +557,44 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send);
557 * 557 *
558 * Called with lock held and preemption disabled. 558 * Called with lock held and preemption disabled.
559 * 559 *
560 * An FCF is considered old if we have missed three advertisements. 560 * An FCF is considered old if we have missed two advertisements.
561 * That is, there have been no valid advertisement from it for three 561 * That is, there have been no valid advertisement from it for 2.5
562 * times its keep-alive period including fuzz. 562 * times its keep-alive period.
563 * 563 *
564 * In addition, determine the time when an FCF selection can occur. 564 * In addition, determine the time when an FCF selection can occur.
565 * 565 *
566 * Also, increment the MissDiscAdvCount when no advertisement is received 566 * Also, increment the MissDiscAdvCount when no advertisement is received
567 * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB). 567 * for the corresponding FCF for 1.5 * FKA_ADV_PERIOD (FC-BB-5 LESB).
568 *
569 * Returns the time in jiffies for the next call.
568 */ 570 */
569static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) 571static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
570{ 572{
571 struct fcoe_fcf *fcf; 573 struct fcoe_fcf *fcf;
572 struct fcoe_fcf *next; 574 struct fcoe_fcf *next;
575 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
576 unsigned long deadline;
573 unsigned long sel_time = 0; 577 unsigned long sel_time = 0;
574 unsigned long mda_time = 0;
575 struct fcoe_dev_stats *stats; 578 struct fcoe_dev_stats *stats;
576 579
577 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { 580 list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
578 mda_time = fcf->fka_period + (fcf->fka_period >> 1); 581 deadline = fcf->time + fcf->fka_period + fcf->fka_period / 2;
579 if ((fip->sel_fcf == fcf) && 582 if (fip->sel_fcf == fcf) {
580 (time_after(jiffies, fcf->time + mda_time))) { 583 if (time_after(jiffies, deadline)) {
581 mod_timer(&fip->timer, jiffies + mda_time); 584 stats = per_cpu_ptr(fip->lp->dev_stats,
582 stats = per_cpu_ptr(fip->lp->dev_stats, 585 smp_processor_id());
583 smp_processor_id()); 586 stats->MissDiscAdvCount++;
584 stats->MissDiscAdvCount++; 587 printk(KERN_INFO "libfcoe: host%d: "
585 printk(KERN_INFO "libfcoe: host%d: Missing Discovery " 588 "Missing Discovery Advertisement "
586 "Advertisement for fab %16.16llx count %lld\n", 589 "for fab %16.16llx count %lld\n",
587 fip->lp->host->host_no, fcf->fabric_name, 590 fip->lp->host->host_no, fcf->fabric_name,
588 stats->MissDiscAdvCount); 591 stats->MissDiscAdvCount);
592 } else if (time_after(next_timer, deadline))
593 next_timer = deadline;
589 } 594 }
590 if (time_after(jiffies, fcf->time + fcf->fka_period * 3 + 595
591 msecs_to_jiffies(FIP_FCF_FUZZ * 3))) { 596 deadline += fcf->fka_period;
597 if (time_after(jiffies, deadline)) {
592 if (fip->sel_fcf == fcf) 598 if (fip->sel_fcf == fcf)
593 fip->sel_fcf = NULL; 599 fip->sel_fcf = NULL;
594 list_del(&fcf->list); 600 list_del(&fcf->list);
@@ -598,19 +604,21 @@ static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
598 stats = per_cpu_ptr(fip->lp->dev_stats, 604 stats = per_cpu_ptr(fip->lp->dev_stats,
599 smp_processor_id()); 605 smp_processor_id());
600 stats->VLinkFailureCount++; 606 stats->VLinkFailureCount++;
601 } else if (fcoe_ctlr_mtu_valid(fcf) && 607 } else {
602 (!sel_time || time_before(sel_time, fcf->time))) { 608 if (time_after(next_timer, deadline))
603 sel_time = fcf->time; 609 next_timer = deadline;
610 if (fcoe_ctlr_mtu_valid(fcf) &&
611 (!sel_time || time_before(sel_time, fcf->time)))
612 sel_time = fcf->time;
604 } 613 }
605 } 614 }
606 if (sel_time) { 615 if (sel_time) {
607 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY); 616 sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
608 fip->sel_time = sel_time; 617 fip->sel_time = sel_time;
609 if (time_before(sel_time, fip->timer.expires))
610 mod_timer(&fip->timer, sel_time);
611 } else { 618 } else {
612 fip->sel_time = 0; 619 fip->sel_time = 0;
613 } 620 }
621 return next_timer;
614} 622}
615 623
616/** 624/**
@@ -1148,7 +1156,7 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1148 struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg; 1156 struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg;
1149 struct fcoe_fcf *sel; 1157 struct fcoe_fcf *sel;
1150 struct fcoe_fcf *fcf; 1158 struct fcoe_fcf *fcf;
1151 unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD); 1159 unsigned long next_timer;
1152 1160
1153 spin_lock_bh(&fip->lock); 1161 spin_lock_bh(&fip->lock);
1154 if (fip->state == FIP_ST_DISABLED) { 1162 if (fip->state == FIP_ST_DISABLED) {
@@ -1157,13 +1165,16 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1157 } 1165 }
1158 1166
1159 fcf = fip->sel_fcf; 1167 fcf = fip->sel_fcf;
1160 fcoe_ctlr_age_fcfs(fip); 1168 next_timer = fcoe_ctlr_age_fcfs(fip);
1161 1169
1162 sel = fip->sel_fcf; 1170 sel = fip->sel_fcf;
1163 if (!sel && fip->sel_time && time_after_eq(jiffies, fip->sel_time)) { 1171 if (!sel && fip->sel_time) {
1164 fcoe_ctlr_select(fip); 1172 if (time_after_eq(jiffies, fip->sel_time)) {
1165 sel = fip->sel_fcf; 1173 fcoe_ctlr_select(fip);
1166 fip->sel_time = 0; 1174 sel = fip->sel_fcf;
1175 fip->sel_time = 0;
1176 } else if (time_after(next_timer, fip->sel_time))
1177 next_timer = fip->sel_time;
1167 } 1178 }
1168 1179
1169 if (sel != fcf) { 1180 if (sel != fcf) {
@@ -1201,12 +1212,9 @@ static void fcoe_ctlr_timeout(unsigned long arg)
1201 } 1212 }
1202 if (time_after(next_timer, fip->port_ka_time)) 1213 if (time_after(next_timer, fip->port_ka_time))
1203 next_timer = fip->port_ka_time; 1214 next_timer = fip->port_ka_time;
1204 mod_timer(&fip->timer, next_timer);
1205 } else if (fip->sel_time) {
1206 next_timer = fip->sel_time +
1207 msecs_to_jiffies(FCOE_CTLR_START_DELAY);
1208 mod_timer(&fip->timer, next_timer);
1209 } 1215 }
1216 if (!list_empty(&fip->fcfs))
1217 mod_timer(&fip->timer, next_timer);
1210 if (fip->send_ctlr_ka || fip->send_port_ka) 1218 if (fip->send_ctlr_ka || fip->send_port_ka)
1211 schedule_work(&fip->timer_work); 1219 schedule_work(&fip->timer_work);
1212 spin_unlock_bh(&fip->lock); 1220 spin_unlock_bh(&fip->lock);