mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-24 05:01:03 +02:00
net_sched: convert idrinfo->lock from spinlock to a mutex
In commitec3ed293e7
("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:ec3ed293e7
("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>
This commit is contained in:
committed by
David S. Miller
parent
6f52f80e85
commit
95278ddaa1
@@ -13,7 +13,7 @@
|
||||
#include <net/netns/generic.h>
|
||||
|
||||
struct tcf_idrinfo {
|
||||
spinlock_t lock;
|
||||
struct mutex lock;
|
||||
struct idr action_idr;
|
||||
};
|
||||
|
||||
@@ -117,7 +117,7 @@ int tc_action_net_init(struct tc_action_net *tn,
|
||||
if (!tn->idrinfo)
|
||||
return -ENOMEM;
|
||||
tn->ops = ops;
|
||||
spin_lock_init(&tn->idrinfo->lock);
|
||||
mutex_init(&tn->idrinfo->lock);
|
||||
idr_init(&tn->idrinfo->action_idr);
|
||||
return err;
|
||||
}
|
||||
|
Reference in New Issue
Block a user