]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sched/act_mirred.c
net_sched: switch to exit_batch for action pernet ops
[linux.git] / net / sched / act_mirred.c
index 8b3e593884803370ea27ef5fe770fa5ae829a888..37e5e4decbd630483c57bb40bddf5a5178bda6a5 100644 (file)
@@ -29,7 +29,6 @@
 #include <net/tc_act/tc_mirred.h>
 
 static LIST_HEAD(mirred_list);
-static DEFINE_SPINLOCK(mirred_list_lock);
 
 static bool tcf_mirred_is_act_redirect(int action)
 {
@@ -50,18 +49,15 @@ static bool tcf_mirred_act_wants_ingress(int action)
        }
 }
 
-static void tcf_mirred_release(struct tc_action *a, int bind)
+static void tcf_mirred_release(struct tc_action *a)
 {
        struct tcf_mirred *m = to_mirred(a);
        struct net_device *dev;
 
-       /* We could be called either in a RCU callback or with RTNL lock held. */
-       spin_lock_bh(&mirred_list_lock);
        list_del(&m->tcfm_list);
-       dev = rcu_dereference_protected(m->tcfm_dev, 1);
+       dev = rtnl_dereference(m->tcfm_dev);
        if (dev)
                dev_put(dev);
-       spin_unlock_bh(&mirred_list_lock);
 }
 
 static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
@@ -139,8 +135,6 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        m->tcf_action = parm->action;
        m->tcfm_eaction = parm->eaction;
        if (dev != NULL) {
-               m->tcfm_ifindex = parm->ifindex;
-               m->net = net;
                if (ret != ACT_P_CREATED)
                        dev_put(rcu_dereference_protected(m->tcfm_dev, 1));
                dev_hold(dev);
@@ -149,9 +143,7 @@ static int tcf_mirred_init(struct net *net, struct nlattr *nla,
        }
 
        if (ret == ACT_P_CREATED) {
-               spin_lock_bh(&mirred_list_lock);
                list_add(&m->tcfm_list, &mirred_list);
-               spin_unlock_bh(&mirred_list_lock);
                tcf_idr_insert(tn, *a);
        }
 
@@ -247,13 +239,14 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind,
 {
        unsigned char *b = skb_tail_pointer(skb);
        struct tcf_mirred *m = to_mirred(a);
+       struct net_device *dev = rtnl_dereference(m->tcfm_dev);
        struct tc_mirred opt = {
                .index   = m->tcf_index,
                .action  = m->tcf_action,
                .refcnt  = m->tcf_refcnt - ref,
                .bindcnt = m->tcf_bindcnt - bind,
                .eaction = m->tcfm_eaction,
-               .ifindex = m->tcfm_ifindex,
+               .ifindex = dev ? dev->ifindex : 0,
        };
        struct tcf_t t;
 
@@ -294,7 +287,6 @@ static int mirred_device_event(struct notifier_block *unused,
 
        ASSERT_RTNL();
        if (event == NETDEV_UNREGISTER) {
-               spin_lock_bh(&mirred_list_lock);
                list_for_each_entry(m, &mirred_list, tcfm_list) {
                        if (rcu_access_pointer(m->tcfm_dev) == dev) {
                                dev_put(dev);
@@ -304,7 +296,6 @@ static int mirred_device_event(struct notifier_block *unused,
                                RCU_INIT_POINTER(m->tcfm_dev, NULL);
                        }
                }
-               spin_unlock_bh(&mirred_list_lock);
        }
 
        return NOTIFY_DONE;
@@ -318,7 +309,7 @@ static struct net_device *tcf_mirred_get_dev(const struct tc_action *a)
 {
        struct tcf_mirred *m = to_mirred(a);
 
-       return __dev_get_by_index(m->net, m->tcfm_ifindex);
+       return rtnl_dereference(m->tcfm_dev);
 }
 
 static struct tc_action_ops act_mirred_ops = {
@@ -343,16 +334,14 @@ static __net_init int mirred_init_net(struct net *net)
        return tc_action_net_init(tn, &act_mirred_ops);
 }
 
-static void __net_exit mirred_exit_net(struct net *net)
+static void __net_exit mirred_exit_net(struct list_head *net_list)
 {
-       struct tc_action_net *tn = net_generic(net, mirred_net_id);
-
-       tc_action_net_exit(tn);
+       tc_action_net_exit(net_list, mirred_net_id);
 }
 
 static struct pernet_operations mirred_net_ops = {
        .init = mirred_init_net,
-       .exit = mirred_exit_net,
+       .exit_batch = mirred_exit_net,
        .id   = &mirred_net_id,
        .size = sizeof(struct tc_action_net),
 };