44
44
* path this potential over-use of the mutex is acceptable.
45
45
*/
46
46
47
+ /*
48
+ * RPORT REFERENCE COUNTING
49
+ *
50
+ * A rport reference should be taken when:
51
+ * - an rport is allocated
52
+ * - a workqueue item is scheduled
53
+ * - an ELS request is send
54
+ * The reference should be dropped when:
55
+ * - the workqueue function has finished
56
+ * - the ELS response is handled
57
+ * - an rport is removed
58
+ */
59
+
47
60
#include <linux/kernel.h>
48
61
#include <linux/spinlock.h>
49
62
#include <linux/interrupt.h>
@@ -242,6 +255,8 @@ static void fc_rport_state_enter(struct fc_rport_priv *rdata,
242
255
/**
243
256
* fc_rport_work() - Handler for remote port events in the rport_event_queue
244
257
* @work: Handle to the remote port being dequeued
258
+ *
259
+ * Reference counting: drops kref on return
245
260
*/
246
261
static void fc_rport_work (struct work_struct * work )
247
262
{
@@ -329,7 +344,8 @@ static void fc_rport_work(struct work_struct *work)
329
344
FC_RPORT_DBG (rdata , "lld callback ev %d\n" , event );
330
345
rdata -> lld_event_callback (lport , rdata , event );
331
346
}
332
- cancel_delayed_work_sync (& rdata -> retry_work );
347
+ if (cancel_delayed_work_sync (& rdata -> retry_work ))
348
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
333
349
334
350
/*
335
351
* Reset any outstanding exchanges before freeing rport.
@@ -381,6 +397,7 @@ static void fc_rport_work(struct work_struct *work)
381
397
mutex_unlock (& rdata -> rp_mutex );
382
398
break ;
383
399
}
400
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
384
401
}
385
402
386
403
/**
@@ -431,19 +448,26 @@ static int fc_rport_login(struct fc_rport_priv *rdata)
431
448
* Set the new event so that the old pending event will not occur.
432
449
* Since we have the mutex, even if fc_rport_work() is already started,
433
450
* it'll see the new event.
451
+ *
452
+ * Reference counting: does not modify kref
434
453
*/
435
454
static void fc_rport_enter_delete (struct fc_rport_priv * rdata ,
436
455
enum fc_rport_event event )
437
456
{
457
+ struct fc_lport * lport = rdata -> local_port ;
458
+
438
459
if (rdata -> rp_state == RPORT_ST_DELETE )
439
460
return ;
440
461
441
462
FC_RPORT_DBG (rdata , "Delete port\n" );
442
463
443
464
fc_rport_state_enter (rdata , RPORT_ST_DELETE );
444
465
445
- if (rdata -> event == RPORT_EV_NONE )
446
- queue_work (rport_event_queue , & rdata -> event_work );
466
+ kref_get (& rdata -> kref );
467
+ if (rdata -> event == RPORT_EV_NONE &&
468
+ !queue_work (rport_event_queue , & rdata -> event_work ))
469
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
470
+
447
471
rdata -> event = event ;
448
472
}
449
473
@@ -496,15 +520,22 @@ static int fc_rport_logoff(struct fc_rport_priv *rdata)
496
520
*
497
521
* Locking Note: The rport lock is expected to be held before calling
498
522
* this routine.
523
+ *
524
+ * Reference counting: schedules workqueue, does not modify kref
499
525
*/
500
526
static void fc_rport_enter_ready (struct fc_rport_priv * rdata )
501
527
{
528
+ struct fc_lport * lport = rdata -> local_port ;
529
+
502
530
fc_rport_state_enter (rdata , RPORT_ST_READY );
503
531
504
532
FC_RPORT_DBG (rdata , "Port is Ready\n" );
505
533
506
- if (rdata -> event == RPORT_EV_NONE )
507
- queue_work (rport_event_queue , & rdata -> event_work );
534
+ kref_get (& rdata -> kref );
535
+ if (rdata -> event == RPORT_EV_NONE &&
536
+ !queue_work (rport_event_queue , & rdata -> event_work ))
537
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
538
+
508
539
rdata -> event = RPORT_EV_READY ;
509
540
}
510
541
@@ -515,11 +546,14 @@ static void fc_rport_enter_ready(struct fc_rport_priv *rdata)
515
546
* Locking Note: Called without the rport lock held. This
516
547
* function will hold the rport lock, call an _enter_*
517
548
* function and then unlock the rport.
549
+ *
550
+ * Reference counting: Drops kref on return.
518
551
*/
519
552
static void fc_rport_timeout (struct work_struct * work )
520
553
{
521
554
struct fc_rport_priv * rdata =
522
555
container_of (work , struct fc_rport_priv , retry_work .work );
556
+ struct fc_lport * lport = rdata -> local_port ;
523
557
524
558
mutex_lock (& rdata -> rp_mutex );
525
559
@@ -547,6 +581,7 @@ static void fc_rport_timeout(struct work_struct *work)
547
581
}
548
582
549
583
mutex_unlock (& rdata -> rp_mutex );
584
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
550
585
}
551
586
552
587
/**
@@ -556,6 +591,8 @@ static void fc_rport_timeout(struct work_struct *work)
556
591
*
557
592
* Locking Note: The rport lock is expected to be held before
558
593
* calling this routine
594
+ *
595
+ * Reference counting: does not modify kref
559
596
*/
560
597
static void fc_rport_error (struct fc_rport_priv * rdata , struct fc_frame * fp )
561
598
{
@@ -602,11 +639,14 @@ static void fc_rport_error(struct fc_rport_priv *rdata, struct fc_frame *fp)
602
639
*
603
640
* Locking Note: The rport lock is expected to be held before
604
641
* calling this routine
642
+ *
643
+ * Reference counting: increments kref when scheduling retry_work
605
644
*/
606
645
static void fc_rport_error_retry (struct fc_rport_priv * rdata ,
607
646
struct fc_frame * fp )
608
647
{
609
648
unsigned long delay = msecs_to_jiffies (FC_DEF_E_D_TOV );
649
+ struct fc_lport * lport = rdata -> local_port ;
610
650
611
651
/* make sure this isn't an FC_EX_CLOSED error, never retry those */
612
652
if (PTR_ERR (fp ) == - FC_EX_CLOSED )
@@ -619,7 +659,9 @@ static void fc_rport_error_retry(struct fc_rport_priv *rdata,
619
659
/* no additional delay on exchange timeouts */
620
660
if (PTR_ERR (fp ) == - FC_EX_TIMEOUT )
621
661
delay = 0 ;
622
- schedule_delayed_work (& rdata -> retry_work , delay );
662
+ kref_get (& rdata -> kref );
663
+ if (!schedule_delayed_work (& rdata -> retry_work , delay ))
664
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
623
665
return ;
624
666
}
625
667
@@ -740,6 +782,8 @@ static void fc_rport_flogi_resp(struct fc_seq *sp, struct fc_frame *fp,
740
782
*
741
783
* Locking Note: The rport lock is expected to be held before calling
742
784
* this routine.
785
+ *
786
+ * Reference counting: increments kref when sending ELS
743
787
*/
744
788
static void fc_rport_enter_flogi (struct fc_rport_priv * rdata )
745
789
{
@@ -758,18 +802,21 @@ static void fc_rport_enter_flogi(struct fc_rport_priv *rdata)
758
802
if (!fp )
759
803
return fc_rport_error_retry (rdata , fp );
760
804
805
+ kref_get (& rdata -> kref );
761
806
if (!lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_FLOGI ,
762
807
fc_rport_flogi_resp , rdata ,
763
- 2 * lport -> r_a_tov ))
808
+ 2 * lport -> r_a_tov )) {
764
809
fc_rport_error_retry (rdata , NULL );
765
- else
766
- kref_get ( & rdata -> kref );
810
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
811
+ }
767
812
}
768
813
769
814
/**
770
815
* fc_rport_recv_flogi_req() - Handle Fabric Login (FLOGI) request in p-mp mode
771
816
* @lport: The local port that received the PLOGI request
772
817
* @rx_fp: The PLOGI request frame
818
+ *
819
+ * Reference counting: drops kref on return
773
820
*/
774
821
static void fc_rport_recv_flogi_req (struct fc_lport * lport ,
775
822
struct fc_frame * rx_fp )
@@ -824,8 +871,7 @@ static void fc_rport_recv_flogi_req(struct fc_lport *lport,
824
871
* RPORT wouldn;t have created and 'rport_lookup' would have
825
872
* failed anyway in that case.
826
873
*/
827
- if (lport -> point_to_multipoint )
828
- break ;
874
+ break ;
829
875
case RPORT_ST_DELETE :
830
876
mutex_unlock (& rdata -> rp_mutex );
831
877
rjt_data .reason = ELS_RJT_FIP ;
@@ -969,6 +1015,8 @@ fc_rport_compatible_roles(struct fc_lport *lport, struct fc_rport_priv *rdata)
969
1015
*
970
1016
* Locking Note: The rport lock is expected to be held before calling
971
1017
* this routine.
1018
+ *
1019
+ * Reference counting: increments kref when sending ELS
972
1020
*/
973
1021
static void fc_rport_enter_plogi (struct fc_rport_priv * rdata )
974
1022
{
@@ -995,12 +1043,13 @@ static void fc_rport_enter_plogi(struct fc_rport_priv *rdata)
995
1043
}
996
1044
rdata -> e_d_tov = lport -> e_d_tov ;
997
1045
1046
+ kref_get (& rdata -> kref );
998
1047
if (!lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_PLOGI ,
999
1048
fc_rport_plogi_resp , rdata ,
1000
- 2 * lport -> r_a_tov ))
1049
+ 2 * lport -> r_a_tov )) {
1001
1050
fc_rport_error_retry (rdata , NULL );
1002
- else
1003
- kref_get ( & rdata -> kref );
1051
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
1052
+ }
1004
1053
}
1005
1054
1006
1055
/**
@@ -1108,6 +1157,8 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp,
1108
1157
*
1109
1158
* Locking Note: The rport lock is expected to be held before calling
1110
1159
* this routine.
1160
+ *
1161
+ * Reference counting: increments kref when sending ELS
1111
1162
*/
1112
1163
static void fc_rport_enter_prli (struct fc_rport_priv * rdata )
1113
1164
{
@@ -1151,11 +1202,12 @@ static void fc_rport_enter_prli(struct fc_rport_priv *rdata)
1151
1202
fc_host_port_id (lport -> host ), FC_TYPE_ELS ,
1152
1203
FC_FC_FIRST_SEQ | FC_FC_END_SEQ | FC_FC_SEQ_INIT , 0 );
1153
1204
1205
+ kref_get (& rdata -> kref );
1154
1206
if (!lport -> tt .exch_seq_send (lport , fp , fc_rport_prli_resp ,
1155
- NULL , rdata , 2 * lport -> r_a_tov ))
1207
+ NULL , rdata , 2 * lport -> r_a_tov )) {
1156
1208
fc_rport_error_retry (rdata , NULL );
1157
- else
1158
- kref_get ( & rdata -> kref );
1209
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
1210
+ }
1159
1211
}
1160
1212
1161
1213
/**
@@ -1230,6 +1282,8 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp,
1230
1282
*
1231
1283
* Locking Note: The rport lock is expected to be held before calling
1232
1284
* this routine.
1285
+ *
1286
+ * Reference counting: increments kref when sending ELS
1233
1287
*/
1234
1288
static void fc_rport_enter_rtv (struct fc_rport_priv * rdata )
1235
1289
{
@@ -1247,12 +1301,13 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
1247
1301
return ;
1248
1302
}
1249
1303
1304
+ kref_get (& rdata -> kref );
1250
1305
if (!lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_RTV ,
1251
1306
fc_rport_rtv_resp , rdata ,
1252
- 2 * lport -> r_a_tov ))
1307
+ 2 * lport -> r_a_tov )) {
1253
1308
fc_rport_error_retry (rdata , NULL );
1254
- else
1255
- kref_get ( & rdata -> kref );
1309
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
1310
+ }
1256
1311
}
1257
1312
1258
1313
/**
@@ -1262,15 +1317,16 @@ static void fc_rport_enter_rtv(struct fc_rport_priv *rdata)
1262
1317
* @lport_arg: The local port
1263
1318
*/
1264
1319
static void fc_rport_logo_resp (struct fc_seq * sp , struct fc_frame * fp ,
1265
- void * lport_arg )
1320
+ void * rdata_arg )
1266
1321
{
1267
- struct fc_lport * lport = lport_arg ;
1322
+ struct fc_rport_priv * rdata = rdata_arg ;
1323
+ struct fc_lport * lport = rdata -> local_port ;
1268
1324
1269
1325
FC_RPORT_ID_DBG (lport , fc_seq_exch (sp )-> did ,
1270
1326
"Received a LOGO %s\n" , fc_els_resp_type (fp ));
1271
- if (IS_ERR (fp ))
1272
- return ;
1273
- fc_frame_free ( fp );
1327
+ if (! IS_ERR (fp ))
1328
+ fc_frame_free ( fp ) ;
1329
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
1274
1330
}
1275
1331
1276
1332
/**
@@ -1279,6 +1335,8 @@ static void fc_rport_logo_resp(struct fc_seq *sp, struct fc_frame *fp,
1279
1335
*
1280
1336
* Locking Note: The rport lock is expected to be held before calling
1281
1337
* this routine.
1338
+ *
1339
+ * Reference counting: increments kref when sending ELS
1282
1340
*/
1283
1341
static void fc_rport_enter_logo (struct fc_rport_priv * rdata )
1284
1342
{
@@ -1291,8 +1349,10 @@ static void fc_rport_enter_logo(struct fc_rport_priv *rdata)
1291
1349
fp = fc_frame_alloc (lport , sizeof (struct fc_els_logo ));
1292
1350
if (!fp )
1293
1351
return ;
1294
- (void )lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_LOGO ,
1295
- fc_rport_logo_resp , lport , 0 );
1352
+ kref_get (& rdata -> kref );
1353
+ if (!lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_LOGO ,
1354
+ fc_rport_logo_resp , rdata , 0 ))
1355
+ kref_put (& rdata -> kref , lport -> tt .rport_destroy );
1296
1356
}
1297
1357
1298
1358
/**
@@ -1359,6 +1419,8 @@ static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp,
1359
1419
*
1360
1420
* Locking Note: The rport lock is expected to be held before calling
1361
1421
* this routine.
1422
+ *
1423
+ * Reference counting: increments kref when sending ELS
1362
1424
*/
1363
1425
static void fc_rport_enter_adisc (struct fc_rport_priv * rdata )
1364
1426
{
@@ -1375,12 +1437,13 @@ static void fc_rport_enter_adisc(struct fc_rport_priv *rdata)
1375
1437
fc_rport_error_retry (rdata , fp );
1376
1438
return ;
1377
1439
}
1440
+ kref_get (& rdata -> kref );
1378
1441
if (!lport -> tt .elsct_send (lport , rdata -> ids .port_id , fp , ELS_ADISC ,
1379
1442
fc_rport_adisc_resp , rdata ,
1380
- 2 * lport -> r_a_tov ))
1443
+ 2 * lport -> r_a_tov )) {
1381
1444
fc_rport_error_retry (rdata , NULL );
1382
- else
1383
- kref_get ( & rdata -> kref );
1445
+ kref_put ( & rdata -> kref , lport -> tt . rport_destroy );
1446
+ }
1384
1447
}
1385
1448
1386
1449
/**
@@ -1494,6 +1557,8 @@ static void fc_rport_recv_rls_req(struct fc_rport_priv *rdata,
1494
1557
* The ELS opcode has already been validated by the caller.
1495
1558
*
1496
1559
* Locking Note: Called with the lport lock held.
1560
+ *
1561
+ * Reference counting: does not modify kref
1497
1562
*/
1498
1563
static void fc_rport_recv_els_req (struct fc_lport * lport , struct fc_frame * fp )
1499
1564
{
@@ -1561,6 +1626,8 @@ static void fc_rport_recv_els_req(struct fc_lport *lport, struct fc_frame *fp)
1561
1626
* @fp: The request frame
1562
1627
*
1563
1628
* Locking Note: Called with the lport lock held.
1629
+ *
1630
+ * Reference counting: does not modify kref
1564
1631
*/
1565
1632
static void fc_rport_recv_req (struct fc_lport * lport , struct fc_frame * fp )
1566
1633
{
@@ -1605,6 +1672,8 @@ static void fc_rport_recv_req(struct fc_lport *lport, struct fc_frame *fp)
1605
1672
* @rx_fp: The PLOGI request frame
1606
1673
*
1607
1674
* Locking Note: The rport lock is held before calling this function.
1675
+ *
1676
+ * Reference counting: increments kref on return
1608
1677
*/
1609
1678
static void fc_rport_recv_plogi_req (struct fc_lport * lport ,
1610
1679
struct fc_frame * rx_fp )
@@ -1919,6 +1988,8 @@ static void fc_rport_recv_prlo_req(struct fc_rport_priv *rdata,
1919
1988
*
1920
1989
* Locking Note: The rport lock is expected to be held before calling
1921
1990
* this function.
1991
+ *
1992
+ * Reference counting: drops kref on return
1922
1993
*/
1923
1994
static void fc_rport_recv_logo_req (struct fc_lport * lport , struct fc_frame * fp )
1924
1995
{
0 commit comments