@@ -1135,36 +1135,12 @@ static int mptcp_nl_remove_subflow_and_signal_addr(struct net *net,
1135
1135
return 0 ;
1136
1136
}
1137
1137
1138
- struct addr_entry_release_work {
1139
- struct rcu_work rwork ;
1140
- struct mptcp_pm_addr_entry * entry ;
1141
- };
1142
-
1143
- static void mptcp_pm_release_addr_entry (struct work_struct * work )
1138
+ /* caller must ensure the RCU grace period is already elapsed */
1139
+ static void __mptcp_pm_release_addr_entry (struct mptcp_pm_addr_entry * entry )
1144
1140
{
1145
- struct addr_entry_release_work * w ;
1146
- struct mptcp_pm_addr_entry * entry ;
1147
-
1148
- w = container_of (to_rcu_work (work ), struct addr_entry_release_work , rwork );
1149
- entry = w -> entry ;
1150
- if (entry ) {
1151
- if (entry -> lsk )
1152
- sock_release (entry -> lsk );
1153
- kfree (entry );
1154
- }
1155
- kfree (w );
1156
- }
1157
-
1158
- static void mptcp_pm_free_addr_entry (struct mptcp_pm_addr_entry * entry )
1159
- {
1160
- struct addr_entry_release_work * w ;
1161
-
1162
- w = kmalloc (sizeof (* w ), GFP_ATOMIC );
1163
- if (w ) {
1164
- INIT_RCU_WORK (& w -> rwork , mptcp_pm_release_addr_entry );
1165
- w -> entry = entry ;
1166
- queue_rcu_work (system_wq , & w -> rwork );
1167
- }
1141
+ if (entry -> lsk )
1142
+ sock_release (entry -> lsk );
1143
+ kfree (entry );
1168
1144
}
1169
1145
1170
1146
static int mptcp_nl_remove_id_zero_address (struct net * net ,
@@ -1244,7 +1220,8 @@ static int mptcp_nl_cmd_del_addr(struct sk_buff *skb, struct genl_info *info)
1244
1220
spin_unlock_bh (& pernet -> lock );
1245
1221
1246
1222
mptcp_nl_remove_subflow_and_signal_addr (sock_net (skb -> sk ), & entry -> addr );
1247
- mptcp_pm_free_addr_entry (entry );
1223
+ synchronize_rcu ();
1224
+ __mptcp_pm_release_addr_entry (entry );
1248
1225
1249
1226
return ret ;
1250
1227
}
@@ -1297,6 +1274,7 @@ static void mptcp_nl_remove_addrs_list(struct net *net,
1297
1274
}
1298
1275
}
1299
1276
1277
+ /* caller must ensure the RCU grace period is already elapsed */
1300
1278
static void __flush_addrs (struct list_head * list )
1301
1279
{
1302
1280
while (!list_empty (list )) {
@@ -1305,7 +1283,7 @@ static void __flush_addrs(struct list_head *list)
1305
1283
cur = list_entry (list -> next ,
1306
1284
struct mptcp_pm_addr_entry , list );
1307
1285
list_del_rcu (& cur -> list );
1308
- mptcp_pm_free_addr_entry (cur );
1286
+ __mptcp_pm_release_addr_entry (cur );
1309
1287
}
1310
1288
}
1311
1289
@@ -1329,6 +1307,7 @@ static int mptcp_nl_cmd_flush_addrs(struct sk_buff *skb, struct genl_info *info)
1329
1307
bitmap_zero (pernet -> id_bitmap , MAX_ADDR_ID + 1 );
1330
1308
spin_unlock_bh (& pernet -> lock );
1331
1309
mptcp_nl_remove_addrs_list (sock_net (skb -> sk ), & free_list );
1310
+ synchronize_rcu ();
1332
1311
__flush_addrs (& free_list );
1333
1312
return 0 ;
1334
1313
}
@@ -1939,7 +1918,8 @@ static void __net_exit pm_nl_exit_net(struct list_head *net_list)
1939
1918
struct pm_nl_pernet * pernet = net_generic (net , pm_nl_pernet_id );
1940
1919
1941
1920
/* net is removed from namespace list, can't race with
1942
- * other modifiers
1921
+ * other modifiers, also netns core already waited for a
1922
+ * RCU grace period.
1943
1923
*/
1944
1924
__flush_addrs (& pernet -> local_addr_list );
1945
1925
}
0 commit comments