void net_dec_egress_queue(void);
 #endif
 
-extern void rtnetlink_init(void);
-extern void __rtnl_unlock(void);
+void rtnetlink_init(void);
+void __rtnl_unlock(void);
+void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail);
 
 #define ASSERT_RTNL() do { \
        if (unlikely(!rtnl_is_locked())) { \
 
        return skb;
 }
 
-static inline void __qdisc_reset_queue(struct Qdisc *sch,
-                                      struct sk_buff_head *list)
+static inline void __qdisc_reset_queue(struct sk_buff_head *list)
 {
        /*
         * We do not know the backlog in bytes of this list, it
         * is up to the caller to correct it
         */
-       __skb_queue_purge(list);
+       if (!skb_queue_empty(list)) {
+               rtnl_kfree_skbs(list->next, list->prev);
+               __skb_queue_head_init(list);
+       }
 }
 
 static inline void qdisc_reset_queue(struct Qdisc *sch)
 {
-       __qdisc_reset_queue(sch, &sch->q);
+       __qdisc_reset_queue(&sch->q);
        sch->qstats.backlog = 0;
 }
 
        return old;
 }
 
+static inline void rtnl_qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
+{
+       rtnl_kfree_skbs(skb, skb);
+       qdisc_qstats_drop(sch);
+}
+
 static inline int qdisc_drop(struct sk_buff *skb, struct Qdisc *sch)
 {
        kfree_skb(skb);
 
 }
 EXPORT_SYMBOL(rtnl_lock);
 
+static struct sk_buff *defer_kfree_skb_list;
+void rtnl_kfree_skbs(struct sk_buff *head, struct sk_buff *tail)
+{
+       if (head && tail) {
+               tail->next = defer_kfree_skb_list;
+               defer_kfree_skb_list = head;
+       }
+}
+EXPORT_SYMBOL(rtnl_kfree_skbs);
+
 void __rtnl_unlock(void)
 {
+       struct sk_buff *head = defer_kfree_skb_list;
+
+       defer_kfree_skb_list = NULL;
+
        mutex_unlock(&rtnl_mutex);
+
+       while (head) {
+               struct sk_buff *next = head->next;
+
+               kfree_skb(head);
+               cond_resched();
+               head = next;
+       }
 }
 
 void rtnl_unlock(void)
 
        struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
 
        for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
-               __qdisc_reset_queue(qdisc, band2list(priv, prio));
+               __qdisc_reset_queue(band2list(priv, prio));
 
        priv->bitmap = 0;
        qdisc->qstats.backlog = 0;