@@ -54,6 +54,8 @@ MODULE_LICENSE("GPL v2");
54
54
static void fcoe_ctlr_timeout (unsigned long );
55
55
static void fcoe_ctlr_timer_work (struct work_struct * );
56
56
static void fcoe_ctlr_recv_work (struct work_struct * );
57
+ static int fcoe_ctlr_flogi_retry (struct fcoe_ctlr * );
58
+ static void fcoe_ctlr_select (struct fcoe_ctlr * );
57
59
58
60
static void fcoe_ctlr_vn_start (struct fcoe_ctlr * );
59
61
static 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
178
fip -> mode = mode ;
177
179
INIT_LIST_HEAD (& fip -> fcfs );
178
180
mutex_init (& fip -> ctlr_mutex );
181
+ spin_lock_init (& fip -> ctlr_lock );
179
182
fip -> flogi_oxid = FC_XID_UNKNOWN ;
180
183
setup_timer (& fip -> timer , fcoe_ctlr_timeout , (unsigned long )fip );
181
184
INIT_WORK (& fip -> timer_work , fcoe_ctlr_timer_work );
@@ -231,17 +234,31 @@ void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
231
234
EXPORT_SYMBOL (fcoe_ctlr_destroy );
232
235
233
236
/**
234
- * fcoe_ctlr_announce() - announce new selection
237
+ * fcoe_ctlr_announce() - announce new FCF selection
235
238
* @fip: The FCoE controller
236
239
*
237
240
* Also sets the destination MAC for FCoE and control packets
241
+ *
242
+ * Called with neither ctlr_mutex nor ctlr_lock held.
238
243
*/
239
244
static 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
260
if (sel && !compare_ether_addr (sel -> fcf_mac , fip -> dest_addr ))
244
- return ;
261
+ goto unlock ;
245
262
if (!is_zero_ether_addr (fip -> dest_addr )) {
246
263
printk (KERN_NOTICE "libfcoe: host%d: "
247
264
"FIP Fibre-Channel Forwarder MAC %pM deselected\n" ,
@@ -255,6 +272,8 @@ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip)
255
272
memcpy (fip -> dest_addr , sel -> fcf_mac , ETH_ALEN );
256
273
fip -> map_dest = 0 ;
257
274
}
275
+ unlock :
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
610
* The caller must check that the length is a multiple of 4.
592
611
* The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
593
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
*/
595
617
int fcoe_ctlr_els_send (struct fcoe_ctlr * fip , struct fc_lport * lport ,
596
618
struct sk_buff * skb )
@@ -628,7 +650,15 @@ int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct fc_lport *lport,
628
650
switch (op ) {
629
651
case ELS_FLOGI :
630
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
662
case ELS_FDISC :
633
663
if (ntoh24 (fh -> fh_s_id ))
634
664
return 0 ;
@@ -1088,18 +1118,24 @@ static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
1088
1118
els_op = * (u8 * )(fh + 1 );
1089
1119
1090
1120
if ((els_dtype == FIP_DT_FLOGI || els_dtype == FIP_DT_FDISC ) &&
1091
- sub == FIP_SC_REP && els_op == ELS_LS_ACC &&
1092
- fip -> mode != FIP_MODE_VN2VN ) {
1093
- if (!is_valid_ether_addr (granted_mac )) {
1094
- LIBFCOE_FIP_DBG (fip ,
1095
- "Invalid MAC address %pM in FIP ELS\n" ,
1096
- granted_mac );
1097
- goto drop ;
1098
- }
1099
- memcpy (fr_cb (fp )-> granted_mac , granted_mac , ETH_ALEN );
1121
+ sub == FIP_SC_REP && fip -> mode != FIP_MODE_VN2VN ) {
1122
+ if ( els_op == ELS_LS_ACC ) {
1123
+ if (!is_valid_ether_addr (granted_mac )) {
1124
+ LIBFCOE_FIP_DBG (fip ,
1125
+ "Invalid MAC address %pM in FIP ELS\n" ,
1126
+ granted_mac );
1127
+ goto drop ;
1128
+ }
1129
+ memcpy (fr_cb (fp )-> granted_mac , granted_mac , ETH_ALEN );
1100
1130
1101
- if (fip -> flogi_oxid == ntohs (fh -> fh_ox_id ))
1102
- fip -> flogi_oxid = FC_XID_UNKNOWN ;
1131
+ if (fip -> flogi_oxid == ntohs (fh -> fh_ox_id )) {
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
1141
if ((desc_cnt == 0 ) || ((els_op != ELS_LS_RJT ) &&
@@ -1355,12 +1391,15 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
1355
1391
*
1356
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
1397
* Called with lock held.
1359
1398
*/
1360
1399
static void fcoe_ctlr_select (struct fcoe_ctlr * fip )
1361
1400
{
1362
1401
struct fcoe_fcf * fcf ;
1363
- struct fcoe_fcf * best = NULL ;
1402
+ struct fcoe_fcf * best = fip -> sel_fcf ;
1364
1403
struct fcoe_fcf * first ;
1365
1404
1366
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
1416
"or FC-MAP\n" );
1378
1417
return NULL ;
1379
1418
}
1419
+ if (fcf -> flogi_sent )
1420
+ continue ;
1380
1421
if (!fcoe_ctlr_fcf_usable (fcf )) {
1381
1422
LIBFCOE_FIP_DBG (fip , "FCF for fab %16.16llx "
1382
1423
"map %x %svalid %savailable\n" ,
@@ -1386,11 +1427,7 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1386
1427
"" : "un" );
1387
1428
continue ;
1388
1429
}
1389
- if (!best ) {
1390
- best = fcf ;
1391
- continue ;
1392
- }
1393
- if (fcf -> pri < best -> pri )
1430
+ if (!best || fcf -> pri < best -> pri || best -> flogi_sent )
1394
1431
best = fcf ;
1395
1432
}
1396
1433
fip -> sel_fcf = best ;
@@ -1403,6 +1440,121 @@ static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
1403
1440
}
1404
1441
}
1405
1442
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
+ */
1452
+ static 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
+ */
1490
+ static 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
+ */
1522
+ static 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" );
1554
+ unlock :
1555
+ spin_unlock_bh (& fip -> ctlr_lock );
1556
+ }
1557
+
1406
1558
/**
1407
1559
* fcoe_ctlr_timeout() - FIP timeout handler
1408
1560
* @arg: The FCoE controller that timed out
@@ -1455,15 +1607,10 @@ static void fcoe_ctlr_timer_work(struct work_struct *work)
1455
1607
next_timer = fip -> sel_time ;
1456
1608
}
1457
1609
1458
- if (sel != fcf ) {
1459
- fcf = sel ; /* the old FCF may have been freed */
1460
- fcoe_ctlr_announce (fip );
1461
- if (sel ) {
1462
- if (time_after (next_timer , fip -> ctlr_ka_time ))
1463
- next_timer = fip -> ctlr_ka_time ;
1464
- } else
1465
- reset = 1 ;
1466
- }
1610
+ if (sel && fip -> flogi_req_send )
1611
+ fcoe_ctlr_flogi_send (fip );
1612
+ else if (!sel && fcf )
1613
+ reset = 1 ;
1467
1614
1468
1615
if (sel && !sel -> fd_flags ) {
1469
1616
if (time_after_eq (jiffies , fip -> ctlr_ka_time )) {
0 commit comments