net_sched: drop packets after root qdisc lock is released
[cascardo/linux.git] / net / sched / sch_dsmark.c
index 34b4dda..1308bbf 100644 (file)
@@ -191,7 +191,8 @@ static inline struct tcf_proto __rcu **dsmark_find_tcf(struct Qdisc *sch,
 
 /* --------------------------- Qdisc operations ---------------------------- */
 
-static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+                         struct sk_buff **to_free)
 {
        struct dsmark_qdisc_data *p = qdisc_priv(sch);
        int err;
@@ -234,7 +235,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 #ifdef CONFIG_NET_CLS_ACT
                case TC_ACT_QUEUED:
                case TC_ACT_STOLEN:
-                       kfree_skb(skb);
+                       __qdisc_drop(skb, to_free);
                        return NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
 
                case TC_ACT_SHOT:
@@ -251,7 +252,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
                }
        }
 
-       err = qdisc_enqueue(skb, p->q);
+       err = qdisc_enqueue(skb, p->q, to_free);
        if (err != NET_XMIT_SUCCESS) {
                if (net_xmit_drop_count(err))
                        qdisc_qstats_drop(sch);
@@ -264,7 +265,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        return NET_XMIT_SUCCESS;
 
 drop:
-       qdisc_drop(skb, sch);
+       qdisc_drop(skb, sch, to_free);
        return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
 }
 
@@ -320,23 +321,6 @@ static struct sk_buff *dsmark_peek(struct Qdisc *sch)
        return p->q->ops->peek(p->q);
 }
 
-static unsigned int dsmark_drop(struct Qdisc *sch)
-{
-       struct dsmark_qdisc_data *p = qdisc_priv(sch);
-       unsigned int len;
-
-       pr_debug("%s(sch %p,[qdisc %p])\n", __func__, sch, p);
-
-       if (p->q->ops->drop == NULL)
-               return 0;
-
-       len = p->q->ops->drop(p->q);
-       if (len)
-               sch->q.qlen--;
-
-       return len;
-}
-
 static int dsmark_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct dsmark_qdisc_data *p = qdisc_priv(sch);
@@ -489,7 +473,6 @@ static struct Qdisc_ops dsmark_qdisc_ops __read_mostly = {
        .enqueue        =       dsmark_enqueue,
        .dequeue        =       dsmark_dequeue,
        .peek           =       dsmark_peek,
-       .drop           =       dsmark_drop,
        .init           =       dsmark_init,
        .reset          =       dsmark_reset,
        .destroy        =       dsmark_destroy,