@@ -68,7 +68,10 @@ struct tc_u_knode {
68
68
u32 __percpu * pcpu_success ;
69
69
#endif
70
70
struct tcf_proto * tp ;
71
- struct rcu_head rcu ;
71
+ union {
72
+ struct work_struct work ;
73
+ struct rcu_head rcu ;
74
+ };
72
75
/* The 'sel' field MUST be the last field in structure to allow for
73
76
* tc_u32_keys allocated at end of structure.
74
77
*/
@@ -418,11 +421,21 @@ static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
418
421
* this the u32_delete_key_rcu variant does not free the percpu
419
422
* statistics.
420
423
*/
424
+ static void u32_delete_key_work (struct work_struct * work )
425
+ {
426
+ struct tc_u_knode * key = container_of (work , struct tc_u_knode , work );
427
+
428
+ rtnl_lock ();
429
+ u32_destroy_key (key -> tp , key , false);
430
+ rtnl_unlock ();
431
+ }
432
+
421
433
static void u32_delete_key_rcu (struct rcu_head * rcu )
422
434
{
423
435
struct tc_u_knode * key = container_of (rcu , struct tc_u_knode , rcu );
424
436
425
- u32_destroy_key (key -> tp , key , false);
437
+ INIT_WORK (& key -> work , u32_delete_key_work );
438
+ tcf_queue_work (& key -> work );
426
439
}
427
440
428
441
/* u32_delete_key_freepf_rcu is the rcu callback variant
@@ -432,11 +445,21 @@ static void u32_delete_key_rcu(struct rcu_head *rcu)
432
445
* for the variant that should be used with keys return from
433
446
* u32_init_knode()
434
447
*/
448
+ static void u32_delete_key_freepf_work (struct work_struct * work )
449
+ {
450
+ struct tc_u_knode * key = container_of (work , struct tc_u_knode , work );
451
+
452
+ rtnl_lock ();
453
+ u32_destroy_key (key -> tp , key , true);
454
+ rtnl_unlock ();
455
+ }
456
+
435
457
static void u32_delete_key_freepf_rcu (struct rcu_head * rcu )
436
458
{
437
459
struct tc_u_knode * key = container_of (rcu , struct tc_u_knode , rcu );
438
460
439
- u32_destroy_key (key -> tp , key , true);
461
+ INIT_WORK (& key -> work , u32_delete_key_freepf_work );
462
+ tcf_queue_work (& key -> work );
440
463
}
441
464
442
465
static int u32_delete_key (struct tcf_proto * tp , struct tc_u_knode * key )
0 commit comments