Mon, Feb 11, 2019 at 09:55:32AM CET, vla...@mellanox.com wrote: >Currently, tcf_block doesn't use any synchronization mechanisms to protect >critical sections that manage lifetime of its chains. block->chain_list and >multiple variables in tcf_chain that control its lifetime assume external >synchronization provided by global rtnl lock. Converting chain reference >counting to atomic reference counters is not possible because cls API uses >multiple counters and flags to control chain lifetime, so all of them must >be synchronized in chain get/put code. > >Use single per-block lock to protect block data and manage lifetime of all >chains on the block. Always take block->lock when accessing chain_list. >Chain get and put modify chain lifetime-management data and parent block's >chain_list, so take the lock in these functions. Verify block->lock state >with assertions in functions that expect to be called with the lock taken >and are called from multiple places. Take block->lock when accessing >filter_chain_list. > >In order to allow parallel update of rules on single block, move all calls >to classifiers outside of critical sections protected by new block->lock. >Rearrange chain get and put functions code to only access protected chain >data while holding block lock: >- Rearrange code to only access chain reference counter and chain action > reference counter while holding block lock. >- Extract code that requires block->lock from tcf_chain_destroy() into > standalone tcf_chain_destroy() function that is called by > __tcf_chain_put() in same critical section that changes chain reference > counters. > >Signed-off-by: Vlad Buslov <vla...@mellanox.com>
Acked-by: Jiri Pirko <j...@mellanox.com>