• Cong Wang's avatar
    net_sched: introduce tcf_exts_get_net() and tcf_exts_put_net() · e4b95c41
    Cong Wang authored
    Instead of holding netns refcnt in tc actions, we can minimize
    the holding time by saving it in struct tcf_exts instead. This
    means we can just hold netns refcnt right before call_rcu() and
    release it after tcf_exts_destroy() is done.
    
    However, because on netns cleanup path we call tcf_proto_destroy()
    too, obviously we can not hold netns for a zero refcnt, in this
    case we have to do cleanup synchronously. It is fine for RCU too,
    the caller cleanup_net() already waits for a grace period.
    
    For other cases, refcnt is non-zero and we can safely grab it as
    normal and release it after we are done.
    
    This patch provides two new API for each filter to use:
    tcf_exts_get_net() and tcf_exts_put_net(). And all filters now can
    use the following pattern:
    
    void __destroy_filter() {
      tcf_exts_destroy();
      tcf_exts_put_net();  // <== release netns refcnt
      kfree();
    }
    void some_work() {
      rtnl_lock();
      __destroy_filter();
      rtnl_unlock();
    }
    void some_rcu_callback() {
      tcf_queue_work(some_work);
    }
    
    if (tcf_exts_get_net())  // <== hold netns refcnt
      call_rcu(some_rcu_callback);
    else
      __destroy_filter();
    
    Cc: Lucas Bates <lucasb@mojatatu.com>
    Cc: Jamal Hadi Salim <jhs@mojatatu.com>
    Cc: Jiri Pirko <jiri@resnulli.us>
    Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e4b95c41
cls_api.c 23.8 KB