This patch introduces a dedicated workqueue for tc filters so that each tc filter's RCU callback could defer their action destroy work to this workqueue. The helper tcf_queue_work() is introduced for them to use.
Because we hold RTNL lock when calling tcf_block_put(), we can not simply flush works inside it, therefore we have to defer it again to this workqueue and make sure all flying RCU callbacks have already queued their work before this one, in other words, to ensure this is the last one to execute to prevent any use-after-free.
On the other hand, this makes tcf_block_put() ugly and harder to understand. Since David and Eric strongly dislike adding synchronize_rcu(), this is probably the only solution that could make everyone happy.
Please also see the code comments below.
7aa0045dadb6 net_sched: introduce a workqueue for RCU callbacks of tc filter
include/net/pkt_cls.h | 3 +++
include/net/sch_generic.h | 2 ++
net/sched/cls_api.c | 68 +++++++++++++++++++++++++++++++++++------------
3 files changed, 56 insertions(+), 17 deletions(-)