net_sched: convert idrinfo->lock from spinlock to a mutex
authorCong Wang <xiyou.wangcong@gmail.com>
Tue, 2 Oct 2018 19:50:19 +0000 (12:50 -0700)
committerDavid S. Miller <davem@davemloft.net>
Fri, 5 Oct 2018 07:36:31 +0000 (00:36 -0700)
commit95278ddaa15cfa23e4a06ee9ed7b6ee0197c500b
tree66c03ef2f1ffb146684af06d2cf664a262037715
parent6f52f80e85309738121f2db51a3cac91b8195743
net_sched: convert idrinfo->lock from spinlock to a mutex

In commit ec3ed293e766 ("net_sched: change tcf_del_walker() to take idrinfo->lock")
we move fl_hw_destroy_tmplt() to a workqueue to avoid blocking
with the spinlock held. Unfortunately, this causes a lot of
troubles here:

1. tcf_chain_destroy() could be called right after we queue the work
   but before the work runs. This is a use-after-free.

2. The chain refcnt is already 0, we can't even just hold it again.
   We can check refcnt==1 but it is ugly.

3. The chain with refcnt 0 is still visible in its block, which means
   it could be still found and used!

4. The block has a refcnt too, we can't hold it without introducing a
   proper API either.

We can make it working but the end result is ugly. Instead of wasting
time on reviewing it, let's just convert the troubling spinlock to
a mutex, which allows us to use non-atomic allocations too.

Fixes: ec3ed293e766 ("net_sched: change tcf_del_walker() to take idrinfo->lock")
Reported-by: Ido Schimmel <idosch@idosch.org>
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Vlad Buslov <vladbu@mellanox.com>
Cc: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Tested-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/act_api.h
net/sched/act_api.c
net/sched/cls_flower.c