• Cong Wang's avatar
    net_sched: get rid of rcu_barrier() in tcf_block_put_ext() · efbf7897
    Cong Wang authored
    Both Eric and Paolo noticed the rcu_barrier() we use in
    tcf_block_put_ext() could be a performance bottleneck when
    we have a lot of tc classes.
    
    Paolo provided the following to demonstrate the issue:
    
    tc qdisc add dev lo root htb
    for I in `seq 1 1000`; do
            tc class add dev lo parent 1: classid 1:$I htb rate 100kbit
            tc qdisc add dev lo parent 1:$I handle $((I + 1)): htb
            for J in `seq 1 10`; do
                    tc filter add dev lo parent $((I + 1)): u32 match ip src 1.1.1.$J
            done
    done
    time tc qdisc del dev root
    
    real    0m54.764s
    user    0m0.023s
    sys     0m0.000s
    
    The rcu_barrier() there is to ensure we free the block after all chains
    are gone, that is, to queue tcf_block_put_final() at the tail of workqueue.
    We can achieve this ordering requirement by refcnt'ing tcf block instead,
    that is, the tcf block is freed only when the last chain in this block is
    gone. This also simplifies the code.
    
    Paolo reported after this patch we get:
    
    real    0m0.017s
    user    0m0.000s
    sys     0m0.017s
    Tested-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Cc: Eric Dumazet <edumazet@google.com>
    Cc: Jiri Pirko <jiri@mellanox.com>
    Cc: Jamal Hadi Salim <jhs@mojatatu.com>
    Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    efbf7897
cls_api.c 28.7 KB