• Cong Wang's avatar
    net_sched: carefully handle tcf_block_put() · 1697c4bb
    Cong Wang authored
    As pointed out by Jiri, there is still a race condition between
    tcf_block_put() and tcf_chain_destroy() in a RCU callback. There
    is no way to make it correct without proper locking or synchronization,
    because both operate on a shared list.
    
    Locking is hard, because the only lock we can pick here is a spinlock,
    however, in tc_dump_tfilter() we iterate this list with a sleeping
    function called (tcf_chain_dump()), which makes using a lock to protect
    chain_list almost impossible.
    
    Jiri suggested the idea of holding a refcnt before flushing, this works
    because it guarantees us there would be no parallel tcf_chain_destroy()
    during the loop, therefore the race condition is gone. But we have to
    be very careful with proper synchronization with RCU callbacks.
    Suggested-by: default avatarJiri Pirko <jiri@mellanox.com>
    Cc: Jamal Hadi Salim <jhs@mojatatu.com>
    Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Acked-by: default avatarJiri Pirko <jiri@mellanox.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    1697c4bb
cls_api.c 23.6 KB