aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Eykholt <jeykholt@cisco.com>2010-11-30 19:19:56 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-12-21 13:24:32 -0500
commit794d98e77f5901ceded697f1633463e88f078038 (patch)
tree97ac82ba7b14821472f81400f8d1a7230e037cb7
parentb69ae0ae3f322d9a6bc4e209049b5b6e193ad652 (diff)
[SCSI] libfcoe: retry rejected FLOGI to another FCF if possible
Switches using multiple-FCFs may reject FLOGI in order to balance the load between multiple FCFs. Even though the FCF was available, it may have more load at the point we actually send the FLOGI. If the FLOGI fails, select a different FCF if possible, among those with the same priority. If no other FCF is available, just deliver the reject to libfc for retry. Signed-off-by: Joe Eykholt <jeykholt@cisco.com> Signed-off-by: Robert Love <robert.w.love@intel.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r--drivers/scsi/fcoe/libfcoe.c207
-rw-r--r--include/scsi/libfcoe.h8
2 files changed, 185 insertions, 30 deletions
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 826c260f7951..c90622c28b6c 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -54,6 +54,8 @@ MODULE_LICENSE("GPL v2");
54static void fcoe_ctlr_timeout(unsigned long); 54static void fcoe_ctlr_timeout(unsigned long);
55static void fcoe_ctlr_timer_work(struct work_struct *); 55static void fcoe_ctlr_timer_work(struct work_struct *);
56static void fcoe_ctlr_recv_work(struct work_struct *); 56static void fcoe_ctlr_recv_work(struct work_struct *);
57static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *);
58static void fcoe_ctlr_select(struct fcoe_ctlr *);
57 59
58static void fcoe_ctlr_vn_start(struct fcoe_ctlr *); 60static void fcoe_ctlr_vn_start(struct fcoe_ctlr *);
59static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *); 61static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *);
@@ -176,6 +178,7 @@ void fcoe_ctlr_init(struct fcoe_ctlr *fip, enum fip_state mode)
176 fip->mode = mode; 178 fip->mode = mode;
177 INIT_LIST_HEAD(&fip->fcfs); 179 INIT_LIST_HEAD(&fip->fcfs);
178 mutex_init(&fip->ctlr_mutex); 180 mutex_init(&fip->ctlr_mutex);
181 spin_lock_init(&fip->ctlr_lock);
179 fip->flogi_oxid = FC_XID_UNKNOWN; 182 fip->flogi_oxid = FC_XID_UNKNOWN;
180 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip); 183 setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
181 INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work); 184 INIT_WORK(&fip->timer_work, fcoe_ctlr_timer_work);
@@ -231,17 +234,31 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
231EXPORT_SYMBOL(fcoe_ctlr_destroy); 234EXPORT_SYMBOL(fcoe_ctlr_destroy);
232 235
233/** 236/**
234 * fcoe_ctlr_announce() - announce new selection 237 * fcoe_ctlr_announce() - announce new FCF selection
235 * @fip: The FCoE controller 238 * @fip: The FCoE controller
236 * 239 *
237 * Also sets the destination MAC for FCoE and control packets 240 * Also sets the destination MAC for FCoE and control packets
241 *
242 * Called with neither ctlr_mutex nor ctlr_lock held.
238 */ 243 */
239static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) 244static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
240{ 245{
241 struct fcoe_fcf *sel = fip->sel_fcf; 246 struct fcoe_fcf *sel;
247 struct fcoe_fcf *fcf;
248
249 mutex_lock(&fip->ctlr_mutex);
250 spin_lock_bh(&fip->ctlr_lock);
251
252 kfree_skb(fip->flogi_req);
253 fip->flogi_req = NULL;
254 list_for_each_entry(fcf, &fip->fcfs, list)
255 fcf->flogi_sent = 0;
256
257 spin_unlock_bh(&fip->ctlr_lock);
258 sel = fip->sel_fcf;
242 259
243 if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr)) 260 if (sel && !compare_ether_addr(sel->fcf_mac, fip->dest_addr))
244 return; 261 goto unlock;
245 if (!is_zero_ether_addr(fip->dest_addr)) { 262 if (!is_zero_ether_addr(fip->dest_addr)) {
246 printk(KERN_NOTICE "libfcoe: host%d: " 263 printk(KERN_NOTICE "libfcoe: host%d: "
247 "FIP Fibre-Channel Forwarder MAC %pM deselected\n", 264 "FIP Fibre-Channel Forwarder MAC %pM deselected\n",
@@ -255,6 +272,8 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
255 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN); 272 memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
256 fip->map_dest = 0; 273 fip->map_dest = 0;
257 } 274 }
275unlock:
276 mutex_unlock(&fip->ctlr_mutex);
258} 277}
259 278
260/** 279/**
@@ -591,6 +610,9 @@ static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip, struct fc_lport *lport,
591 * The caller must check that the length is a multiple of 4. 610 * The caller must check that the length is a multiple of 4.
592 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes). 611 * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
593 * The the skb must also be an fc_frame. 612 * The the skb must also be an fc_frame.
613 *
614 * This is called from the lower-level driver with spinlocks held,
615 * so we must not take a mutex here.
594 */ 616 */
595int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport, 617int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
596 struct sk_buff *skb) 618 struct sk_buff *skb)
@@ -628,7 +650,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
628 switch (op) { 650 switch (op) {
629 case ELS_FLOGI: 651 case ELS_FLOGI:
630 op = FIP_DT_FLOGI; 652 op = FIP_DT_FLOGI;
631 break; 653 if (fip->mode == FIP_MODE_VN2VN)
654 break;
655 spin_lock_bh(&fip->ctlr_lock);
656 kfree_skb(fip->flogi_req);
657 fip->flogi_req = skb;
658 fip->flogi_req_send = 1;
659 spin_unlock_bh(&fip->ctlr_lock);
660 schedule_work(&fip->timer_work);
661 return -EINPROGRESS;
632 case ELS_FDISC: 662 case ELS_FDISC:
633 if (ntoh24(fh->fh_s_id)) 663 if (ntoh24(fh->fh_s_id))
634 return 0; 664 return 0;
@@ -1088,18 +1118,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1088 els_op = *(u8 *)(fh + 1); 1118 els_op = *(u8 *)(fh + 1);
1089 1119
1090 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) && 1120 if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC) &&
1091 sub == FIP_SC_REP && els_op == ELS_LS_ACC && 1121 sub == FIP_SC_REP && fip->mode != FIP_MODE_VN2VN) {
1092 fip->mode != FIP_MODE_VN2VN) { 1122 if (els_op == ELS_LS_ACC) {
1093 if (!is_valid_ether_addr(granted_mac)) { 1123 if (!is_valid_ether_addr(granted_mac)) {
1094 LIBFCOE_FIP_DBG(fip, 1124 LIBFCOE_FIP_DBG(fip,
1095 "Invalid MAC address %pM in FIP ELS\n", 1125 "Invalid MAC address %pM in FIP ELS\n",
1096 granted_mac); 1126 granted_mac);
1097 goto drop; 1127 goto drop;
1098 } 1128 }
1099 memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN); 1129 memcpy(fr_cb(fp)->granted_mac, granted_mac, ETH_ALEN);
1100 1130
1101 if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) 1131 if (fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
1102 fip->flogi_oxid = FC_XID_UNKNOWN; 1132 fip->flogi_oxid = FC_XID_UNKNOWN;
1133 if (els_dtype == FIP_DT_FLOGI)
1134 fcoe_ctlr_announce(fip);
1135 }
1136 } else if (els_dtype == FIP_DT_FLOGI &&
1137 !fcoe_ctlr_flogi_retry(fip))
1138 goto drop; /* retrying FLOGI so drop reject */
1103 } 1139 }
1104 1140
1105 if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) && 1141 if ((desc_cnt == 0) || ((els_op != ELS_LS_RJT) &&
@@ -1355,12 +1391,15 @@ drop:
1355 * 1391 *
1356 * If there are conflicting advertisements, no FCF can be chosen. 1392 * If there are conflicting advertisements, no FCF can be chosen.
1357 * 1393 *
1394 * If there is already a selected FCF, this will choose a better one or
1395 * an equivalent one that hasn't already been sent a FLOGI.
1396 *
1358 * Called with lock held. 1397 * Called with lock held.
1359 */ 1398 */
1360static void fcoe_ctlr_select(struct fcoe_ctlr *fip) 1399static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1361{ 1400{
1362 struct fcoe_fcf *fcf; 1401 struct fcoe_fcf *fcf;
1363 struct fcoe_fcf *best = NULL; 1402 struct fcoe_fcf *best = fip->sel_fcf;
1364 struct fcoe_fcf *first; 1403 struct fcoe_fcf *first;
1365 1404
1366 first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list); 1405 first = list_first_entry(&fip->fcfs, struct fcoe_fcf, list);
@@ -1377,6 +1416,8 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1377 "or FC-MAP\n"); 1416 "or FC-MAP\n");
1378 return NULL; 1417 return NULL;
1379 } 1418 }
1419 if (fcf->flogi_sent)
1420 continue;
1380 if (!fcoe_ctlr_fcf_usable(fcf)) { 1421 if (!fcoe_ctlr_fcf_usable(fcf)) {
1381 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx " 1422 LIBFCOE_FIP_DBG(fip, "FCF for fab %16.16llx "
1382 "map %x %svalid %savailable\n", 1423 "map %x %svalid %savailable\n",
@@ -1386,11 +1427,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1386 "" : "un"); 1427 "" : "un");
1387 continue; 1428 continue;
1388 } 1429 }
1389 if (!best) { 1430 if (!best || fcf->pri < best->pri || best->flogi_sent)
1390 best = fcf;
1391 continue;
1392 }
1393 if (fcf->pri < best->pri)
1394 best = fcf; 1431 best = fcf;
1395 } 1432 }
1396 fip->sel_fcf = best; 1433 fip->sel_fcf = best;
@@ -1404,6 +1441,121 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1404} 1441}
1405 1442
1406/** 1443/**
1444 * fcoe_ctlr_flogi_send_locked() - send FIP-encapsulated FLOGI to current FCF
1445 * @fip: The FCoE controller
1446 *
1447 * Returns non-zero error if it could not be sent.
1448 *
1449 * Called with ctlr_mutex and ctlr_lock held.
1450 * Caller must verify that fip->sel_fcf is not NULL.
1451 */
1452static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip)
1453{
1454 struct sk_buff *skb;
1455 struct sk_buff *skb_orig;
1456 struct fc_frame_header *fh;
1457 int error;
1458
1459 skb_orig = fip->flogi_req;
1460 if (!skb_orig)
1461 return -EINVAL;
1462
1463 /*
1464 * Clone and send the FLOGI request. If clone fails, use original.
1465 */
1466 skb = skb_clone(skb_orig, GFP_ATOMIC);
1467 if (!skb) {
1468 skb = skb_orig;
1469 fip->flogi_req = NULL;
1470 }
1471 fh = (struct fc_frame_header *)skb->data;
1472 error = fcoe_ctlr_encaps(fip, fip->lp, FIP_DT_FLOGI, skb,
1473 ntoh24(fh->fh_d_id));
1474 if (error) {
1475 kfree_skb(skb);
1476 return error;
1477 }
1478 fip->send(fip, skb);
1479 fip->sel_fcf->flogi_sent = 1;
1480 return 0;
1481}
1482
1483/**
1484 * fcoe_ctlr_flogi_retry() - resend FLOGI request to a new FCF if possible
1485 * @fip: The FCoE controller
1486 *
1487 * Returns non-zero error code if there's no FLOGI request to retry or
1488 * no alternate FCF available.
1489 */
1490static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip)
1491{
1492 struct fcoe_fcf *fcf;
1493 int error;
1494
1495 mutex_lock(&fip->ctlr_mutex);
1496 spin_lock_bh(&fip->ctlr_lock);
1497 LIBFCOE_FIP_DBG(fip, "re-sending FLOGI - reselect\n");
1498 fcoe_ctlr_select(fip);
1499 fcf = fip->sel_fcf;
1500 if (!fcf || fcf->flogi_sent) {
1501 kfree_skb(fip->flogi_req);
1502 fip->flogi_req = NULL;
1503 error = -ENOENT;
1504 } else {
1505 fcoe_ctlr_solicit(fip, NULL);
1506 error = fcoe_ctlr_flogi_send_locked(fip);
1507 }
1508 spin_unlock_bh(&fip->ctlr_lock);
1509 mutex_unlock(&fip->ctlr_mutex);
1510 return error;
1511}
1512
1513
1514/**
1515 * fcoe_ctlr_flogi_send() - Handle sending of FIP FLOGI.
1516 * @fip: The FCoE controller that timed out
1517 *
1518 * Done here because fcoe_ctlr_els_send() can't get mutex.
1519 *
1520 * Called with ctlr_mutex held. The caller must not hold ctlr_lock.
1521 */
1522static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip)
1523{
1524 struct fcoe_fcf *fcf;
1525
1526 spin_lock_bh(&fip->ctlr_lock);
1527 fcf = fip->sel_fcf;
1528 if (!fcf || !fip->flogi_req_send)
1529 goto unlock;
1530
1531 LIBFCOE_FIP_DBG(fip, "sending FLOGI\n");
1532
1533 /*
1534 * If this FLOGI is being sent due to a timeout retry
1535 * to the same FCF as before, select a different FCF if possible.
1536 */
1537 if (fcf->flogi_sent) {
1538 LIBFCOE_FIP_DBG(fip, "sending FLOGI - reselect\n");
1539 fcoe_ctlr_select(fip);
1540 fcf = fip->sel_fcf;
1541 if (!fcf || fcf->flogi_sent) {
1542 LIBFCOE_FIP_DBG(fip, "sending FLOGI - clearing\n");
1543 list_for_each_entry(fcf, &fip->fcfs, list)
1544 fcf->flogi_sent = 0;
1545 fcoe_ctlr_select(fip);
1546 fcf = fip->sel_fcf;
1547 }
1548 }
1549 if (fcf) {
1550 fcoe_ctlr_flogi_send_locked(fip);
1551 fip->flogi_req_send = 0;
1552 } else /* XXX */
1553 LIBFCOE_FIP_DBG(fip, "No FCF selected - defer send\n");
1554unlock:
1555 spin_unlock_bh(&fip->ctlr_lock);
1556}
1557
1558/**
1407 * fcoe_ctlr_timeout() - FIP timeout handler 1559 * fcoe_ctlr_timeout() - FIP timeout handler
1408 * @arg: The FCoE controller that timed out 1560 * @arg: The FCoE controller that timed out
1409 */ 1561 */
@@ -1455,15 +1607,10 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
1455 next_timer = fip->sel_time; 1607 next_timer = fip->sel_time;
1456 } 1608 }
1457 1609
1458 if (sel != fcf) { 1610 if (sel && fip->flogi_req_send)
1459 fcf = sel; /* the old FCF may have been freed */ 1611 fcoe_ctlr_flogi_send(fip);
1460 fcoe_ctlr_announce(fip); 1612 else if (!sel && fcf)
1461 if (sel) { 1613 reset = 1;
1462 if (time_after(next_timer, fip->ctlr_ka_time))
1463 next_timer = fip->ctlr_ka_time;
1464 } else
1465 reset = 1;
1466 }
1467 1614
1468 if (sel && !sel->fd_flags) { 1615 if (sel && !sel->fd_flags) {
1469 if (time_after_eq(jiffies, fip->ctlr_ka_time)) { 1616 if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
diff --git a/include/scsi/libfcoe.h b/include/scsi/libfcoe.h
index 06f1b5a8ed19..feb6a94c90ea 100644
--- a/include/scsi/libfcoe.h
+++ b/include/scsi/libfcoe.h
@@ -92,10 +92,12 @@ enum fip_state {
92 * @timer_work: &work_struct for doing keep-alives and resets. 92 * @timer_work: &work_struct for doing keep-alives and resets.
93 * @recv_work: &work_struct for receiving FIP frames. 93 * @recv_work: &work_struct for receiving FIP frames.
94 * @fip_recv_list: list of received FIP frames. 94 * @fip_recv_list: list of received FIP frames.
95 * @flogi_req: clone of FLOGI request sent
95 * @rnd_state: state for pseudo-random number generator. 96 * @rnd_state: state for pseudo-random number generator.
96 * @port_id: proposed or selected local-port ID. 97 * @port_id: proposed or selected local-port ID.
97 * @user_mfs: configured maximum FC frame size, including FC header. 98 * @user_mfs: configured maximum FC frame size, including FC header.
98 * @flogi_oxid: exchange ID of most recent fabric login. 99 * @flogi_oxid: exchange ID of most recent fabric login.
100 * @flogi_req_send: send of FLOGI requested
99 * @flogi_count: number of FLOGI attempts in AUTO mode. 101 * @flogi_count: number of FLOGI attempts in AUTO mode.
100 * @map_dest: use the FC_MAP mode for destination MAC addresses. 102 * @map_dest: use the FC_MAP mode for destination MAC addresses.
101 * @spma: supports SPMA server-provided MACs mode 103 * @spma: supports SPMA server-provided MACs mode
@@ -106,6 +108,7 @@ enum fip_state {
106 * @update_mac: LLD-supplied function to handle changes to MAC addresses. 108 * @update_mac: LLD-supplied function to handle changes to MAC addresses.
107 * @get_src_addr: LLD-supplied function to supply a source MAC address. 109 * @get_src_addr: LLD-supplied function to supply a source MAC address.
108 * @ctlr_mutex: lock protecting this structure. 110 * @ctlr_mutex: lock protecting this structure.
111 * @ctlr_lock: spinlock covering flogi_req
109 * 112 *
110 * This structure is used by all FCoE drivers. It contains information 113 * This structure is used by all FCoE drivers. It contains information
111 * needed by all FCoE low-level drivers (LLDs) as well as internal state 114 * needed by all FCoE low-level drivers (LLDs) as well as internal state
@@ -126,12 +129,14 @@ struct fcoe_ctlr {
126 struct work_struct timer_work; 129 struct work_struct timer_work;
127 struct work_struct recv_work; 130 struct work_struct recv_work;
128 struct sk_buff_head fip_recv_list; 131 struct sk_buff_head fip_recv_list;
132 struct sk_buff *flogi_req;
129 133
130 struct rnd_state rnd_state; 134 struct rnd_state rnd_state;
131 u32 port_id; 135 u32 port_id;
132 136
133 u16 user_mfs; 137 u16 user_mfs;
134 u16 flogi_oxid; 138 u16 flogi_oxid;
139 u8 flogi_req_send;
135 u8 flogi_count; 140 u8 flogi_count;
136 u8 map_dest; 141 u8 map_dest;
137 u8 spma; 142 u8 spma;
@@ -143,6 +148,7 @@ struct fcoe_ctlr {
143 void (*update_mac)(struct fc_lport *, u8 *addr); 148 void (*update_mac)(struct fc_lport *, u8 *addr);
144 u8 * (*get_src_addr)(struct fc_lport *); 149 u8 * (*get_src_addr)(struct fc_lport *);
145 struct mutex ctlr_mutex; 150 struct mutex ctlr_mutex;
151 spinlock_t ctlr_lock;
146}; 152};
147 153
148/** 154/**
@@ -155,6 +161,7 @@ struct fcoe_ctlr {
155 * @fcf_mac: Ethernet address of the FCF 161 * @fcf_mac: Ethernet address of the FCF
156 * @vfid: virtual fabric ID 162 * @vfid: virtual fabric ID
157 * @pri: selection priority, smaller values are better 163 * @pri: selection priority, smaller values are better
164 * @flogi_sent: current FLOGI sent to this FCF
158 * @flags: flags received from advertisement 165 * @flags: flags received from advertisement
159 * @fka_period: keep-alive period, in jiffies 166 * @fka_period: keep-alive period, in jiffies
160 * 167 *
@@ -176,6 +183,7 @@ struct fcoe_fcf {
176 u8 fcf_mac[ETH_ALEN]; 183 u8 fcf_mac[ETH_ALEN];
177 184
178 u8 pri; 185 u8 pri;
186 u8 flogi_sent;
179 u16 flags; 187 u16 flags;
180 u32 fka_period; 188 u32 fka_period;
181 u8 fd_flags:1; 189 u8 fd_flags:1;