@@ -166,7 +166,7 @@ struct nvmet_fc_tgt_assoc {
166
166
struct nvmet_fc_hostport * hostport ;
167
167
struct nvmet_fc_ls_iod * rcv_disconn ;
168
168
struct list_head a_list ;
169
- struct nvmet_fc_tgt_queue __rcu * queues [NVMET_NR_QUEUES + 1 ];
169
+ struct nvmet_fc_tgt_queue * queues [NVMET_NR_QUEUES + 1 ];
170
170
struct kref ref ;
171
171
struct work_struct del_work ;
172
172
struct rcu_head rcu ;
@@ -803,14 +803,11 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc,
803
803
if (!queue )
804
804
return NULL ;
805
805
806
- if (!nvmet_fc_tgt_a_get (assoc ))
807
- goto out_free_queue ;
808
-
809
806
queue -> work_q = alloc_workqueue ("ntfc%d.%d.%d" , 0 , 0 ,
810
807
assoc -> tgtport -> fc_target_port .port_num ,
811
808
assoc -> a_id , qid );
812
809
if (!queue -> work_q )
813
- goto out_a_put ;
810
+ goto out_free_queue ;
814
811
815
812
queue -> qid = qid ;
816
813
queue -> sqsize = sqsize ;
@@ -832,15 +829,13 @@ nvmet_fc_alloc_target_queue(struct nvmet_fc_tgt_assoc *assoc,
832
829
goto out_fail_iodlist ;
833
830
834
831
WARN_ON (assoc -> queues [qid ]);
835
- rcu_assign_pointer ( assoc -> queues [qid ], queue ) ;
832
+ assoc -> queues [qid ] = queue ;
836
833
837
834
return queue ;
838
835
839
836
out_fail_iodlist :
840
837
nvmet_fc_destroy_fcp_iodlist (assoc -> tgtport , queue );
841
838
destroy_workqueue (queue -> work_q );
842
- out_a_put :
843
- nvmet_fc_tgt_a_put (assoc );
844
839
out_free_queue :
845
840
kfree (queue );
846
841
return NULL ;
@@ -853,12 +848,8 @@ nvmet_fc_tgt_queue_free(struct kref *ref)
853
848
struct nvmet_fc_tgt_queue * queue =
854
849
container_of (ref , struct nvmet_fc_tgt_queue , ref );
855
850
856
- rcu_assign_pointer (queue -> assoc -> queues [queue -> qid ], NULL );
857
-
858
851
nvmet_fc_destroy_fcp_iodlist (queue -> assoc -> tgtport , queue );
859
852
860
- nvmet_fc_tgt_a_put (queue -> assoc );
861
-
862
853
destroy_workqueue (queue -> work_q );
863
854
864
855
kfree_rcu (queue , rcu );
@@ -970,7 +961,7 @@ nvmet_fc_find_target_queue(struct nvmet_fc_tgtport *tgtport,
970
961
rcu_read_lock ();
971
962
list_for_each_entry_rcu (assoc , & tgtport -> assoc_list , a_list ) {
972
963
if (association_id == assoc -> association_id ) {
973
- queue = rcu_dereference ( assoc -> queues [qid ]) ;
964
+ queue = assoc -> queues [qid ];
974
965
if (queue &&
975
966
(!atomic_read (& queue -> connected ) ||
976
967
!nvmet_fc_tgt_q_get (queue )))
@@ -1173,13 +1164,18 @@ nvmet_fc_target_assoc_free(struct kref *ref)
1173
1164
struct nvmet_fc_tgtport * tgtport = assoc -> tgtport ;
1174
1165
struct nvmet_fc_ls_iod * oldls ;
1175
1166
unsigned long flags ;
1167
+ int i ;
1168
+
1169
+ for (i = NVMET_NR_QUEUES ; i >= 0 ; i -- ) {
1170
+ if (assoc -> queues [i ])
1171
+ nvmet_fc_delete_target_queue (assoc -> queues [i ]);
1172
+ }
1176
1173
1177
1174
/* Send Disconnect now that all i/o has completed */
1178
1175
nvmet_fc_xmt_disconnect_assoc (assoc );
1179
1176
1180
1177
nvmet_fc_free_hostport (assoc -> hostport );
1181
1178
spin_lock_irqsave (& tgtport -> lock , flags );
1182
- list_del_rcu (& assoc -> a_list );
1183
1179
oldls = assoc -> rcv_disconn ;
1184
1180
spin_unlock_irqrestore (& tgtport -> lock , flags );
1185
1181
/* if pending Rcv Disconnect Association LS, send rsp now */
@@ -1209,7 +1205,7 @@ static void
1209
1205
nvmet_fc_delete_target_assoc (struct nvmet_fc_tgt_assoc * assoc )
1210
1206
{
1211
1207
struct nvmet_fc_tgtport * tgtport = assoc -> tgtport ;
1212
- struct nvmet_fc_tgt_queue * queue ;
1208
+ unsigned long flags ;
1213
1209
int i , terminating ;
1214
1210
1215
1211
terminating = atomic_xchg (& assoc -> terminating , 1 );
@@ -1218,29 +1214,21 @@ nvmet_fc_delete_target_assoc(struct nvmet_fc_tgt_assoc *assoc)
1218
1214
if (terminating )
1219
1215
return ;
1220
1216
1217
+ spin_lock_irqsave (& tgtport -> lock , flags );
1218
+ list_del_rcu (& assoc -> a_list );
1219
+ spin_unlock_irqrestore (& tgtport -> lock , flags );
1221
1220
1222
- for (i = NVMET_NR_QUEUES ; i >= 0 ; i -- ) {
1223
- rcu_read_lock ();
1224
- queue = rcu_dereference (assoc -> queues [i ]);
1225
- if (!queue ) {
1226
- rcu_read_unlock ();
1227
- continue ;
1228
- }
1221
+ synchronize_rcu ();
1229
1222
1230
- if (!nvmet_fc_tgt_q_get (queue )) {
1231
- rcu_read_unlock ();
1232
- continue ;
1233
- }
1234
- rcu_read_unlock ();
1235
- nvmet_fc_delete_target_queue (queue );
1236
- nvmet_fc_tgt_q_put (queue );
1223
+ /* ensure all in-flight I/Os have been processed */
1224
+ for (i = NVMET_NR_QUEUES ; i >= 0 ; i -- ) {
1225
+ if (assoc -> queues [i ])
1226
+ flush_workqueue (assoc -> queues [i ]-> work_q );
1237
1227
}
1238
1228
1239
1229
dev_info (tgtport -> dev ,
1240
1230
"{%d:%d} Association deleted\n" ,
1241
1231
tgtport -> fc_target_port .port_num , assoc -> a_id );
1242
-
1243
- nvmet_fc_tgt_a_put (assoc );
1244
1232
}
1245
1233
1246
1234
static struct nvmet_fc_tgt_assoc *
@@ -1493,9 +1481,8 @@ __nvmet_fc_free_assocs(struct nvmet_fc_tgtport *tgtport)
1493
1481
list_for_each_entry_rcu (assoc , & tgtport -> assoc_list , a_list ) {
1494
1482
if (!nvmet_fc_tgt_a_get (assoc ))
1495
1483
continue ;
1496
- if (!queue_work (nvmet_wq , & assoc -> del_work ))
1497
- /* already deleting - release local reference */
1498
- nvmet_fc_tgt_a_put (assoc );
1484
+ queue_work (nvmet_wq , & assoc -> del_work );
1485
+ nvmet_fc_tgt_a_put (assoc );
1499
1486
}
1500
1487
rcu_read_unlock ();
1501
1488
}
@@ -1548,9 +1535,8 @@ nvmet_fc_invalidate_host(struct nvmet_fc_target_port *target_port,
1548
1535
continue ;
1549
1536
assoc -> hostport -> invalid = 1 ;
1550
1537
noassoc = false;
1551
- if (!queue_work (nvmet_wq , & assoc -> del_work ))
1552
- /* already deleting - release local reference */
1553
- nvmet_fc_tgt_a_put (assoc );
1538
+ queue_work (nvmet_wq , & assoc -> del_work );
1539
+ nvmet_fc_tgt_a_put (assoc );
1554
1540
}
1555
1541
spin_unlock_irqrestore (& tgtport -> lock , flags );
1556
1542
@@ -1582,7 +1568,7 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
1582
1568
1583
1569
rcu_read_lock ();
1584
1570
list_for_each_entry_rcu (assoc , & tgtport -> assoc_list , a_list ) {
1585
- queue = rcu_dereference ( assoc -> queues [0 ]) ;
1571
+ queue = assoc -> queues [0 ];
1586
1572
if (queue && queue -> nvme_sq .ctrl == ctrl ) {
1587
1573
if (nvmet_fc_tgt_a_get (assoc ))
1588
1574
found_ctrl = true;
@@ -1594,9 +1580,8 @@ nvmet_fc_delete_ctrl(struct nvmet_ctrl *ctrl)
1594
1580
nvmet_fc_tgtport_put (tgtport );
1595
1581
1596
1582
if (found_ctrl ) {
1597
- if (!queue_work (nvmet_wq , & assoc -> del_work ))
1598
- /* already deleting - release local reference */
1599
- nvmet_fc_tgt_a_put (assoc );
1583
+ queue_work (nvmet_wq , & assoc -> del_work );
1584
+ nvmet_fc_tgt_a_put (assoc );
1600
1585
return ;
1601
1586
}
1602
1587
@@ -1626,6 +1611,8 @@ nvmet_fc_unregister_targetport(struct nvmet_fc_target_port *target_port)
1626
1611
/* terminate any outstanding associations */
1627
1612
__nvmet_fc_free_assocs (tgtport );
1628
1613
1614
+ flush_workqueue (nvmet_wq );
1615
+
1629
1616
/*
1630
1617
* should terminate LS's as well. However, LS's will be generated
1631
1618
* at the tail end of association termination, so they likely don't
@@ -1871,9 +1858,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
1871
1858
sizeof (struct fcnvme_ls_disconnect_assoc_acc )),
1872
1859
FCNVME_LS_DISCONNECT_ASSOC );
1873
1860
1874
- /* release get taken in nvmet_fc_find_target_assoc */
1875
- nvmet_fc_tgt_a_put (assoc );
1876
-
1877
1861
/*
1878
1862
* The rules for LS response says the response cannot
1879
1863
* go back until ABTS's have been sent for all outstanding
@@ -1888,8 +1872,6 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
1888
1872
assoc -> rcv_disconn = iod ;
1889
1873
spin_unlock_irqrestore (& tgtport -> lock , flags );
1890
1874
1891
- nvmet_fc_delete_target_assoc (assoc );
1892
-
1893
1875
if (oldls ) {
1894
1876
dev_info (tgtport -> dev ,
1895
1877
"{%d:%d} Multiple Disconnect Association LS's "
@@ -1905,6 +1887,9 @@ nvmet_fc_ls_disconnect(struct nvmet_fc_tgtport *tgtport,
1905
1887
nvmet_fc_xmt_ls_rsp (tgtport , oldls );
1906
1888
}
1907
1889
1890
+ queue_work (nvmet_wq , & assoc -> del_work );
1891
+ nvmet_fc_tgt_a_put (assoc );
1892
+
1908
1893
return false;
1909
1894
}
1910
1895
@@ -2903,6 +2888,9 @@ nvmet_fc_remove_port(struct nvmet_port *port)
2903
2888
2904
2889
nvmet_fc_portentry_unbind (pe );
2905
2890
2891
+ /* terminate any outstanding associations */
2892
+ __nvmet_fc_free_assocs (pe -> tgtport );
2893
+
2906
2894
kfree (pe );
2907
2895
}
2908
2896
@@ -2934,6 +2922,9 @@ static int __init nvmet_fc_init_module(void)
2934
2922
2935
2923
static void __exit nvmet_fc_exit_module (void )
2936
2924
{
2925
+ /* ensure any shutdown operation, e.g. delete ctrls have finished */
2926
+ flush_workqueue (nvmet_wq );
2927
+
2937
2928
/* sanity check - all lports should be removed */
2938
2929
if (!list_empty (& nvmet_fc_target_list ))
2939
2930
pr_warn ("%s: targetport list not empty\n" , __func__ );
0 commit comments