void qdisc_destroy(struct Qdisc *qdisc) { const struct Qdisc_ops *ops = qdisc->ops; if (qdisc->flags & TCQ_F_BUILTIN || !atomic_dec_and_test(&qdisc->refcnt)) return; #ifdef CONFIG_NET_SCHED qdisc_list_del(qdisc); qdisc_put_stab(qdisc->stab); #endif gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); module_put(ops->owner); dev_put(qdisc_dev(qdisc)); if (strnicmp((char *)&qdisc_dev(qdisc)->name, "eth0", 4) == 0) { printk(KERN_EMERG "%s: put. Usage count = %d (net\\sched\\sch_generic.c 559)\n", qdisc_dev(qdisc)->name, atomic_read(&qdisc_dev(qdisc)->refcnt)); } kfree_skb(qdisc->gso_skb); kfree((char *) qdisc - qdisc->padded); }
void qdisc_destroy(struct Qdisc *qdisc) { const struct Qdisc_ops *ops = qdisc->ops; if (qdisc->flags & TCQ_F_BUILTIN || !atomic_dec_and_test(&qdisc->refcnt)) return; #ifdef CONFIG_NET_SCHED qdisc_list_del(qdisc); qdisc_put_stab(qdisc->stab); #endif gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); module_put(ops->owner); dev_put(qdisc_dev(qdisc)); kfree_skb(qdisc->gso_skb); kfree((char *) qdisc - qdisc->padded); }
void qdisc_destroy(struct Qdisc *qdisc) { const struct Qdisc_ops *ops = qdisc->ops; if (qdisc->flags & TCQ_F_BUILTIN || !atomic_dec_and_test(&qdisc->refcnt)) return; #ifdef CONFIG_NET_SCHED qdisc_list_del(qdisc); qdisc_put_stab(rtnl_dereference(qdisc->stab)); #endif gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); module_put(ops->owner); dev_put(qdisc_dev(qdisc)); kfree_skb_list(qdisc->gso_skb); /* * gen_estimator est_timer() might access qdisc->q.lock, * wait a RCU grace period before freeing qdisc. */ call_rcu(&qdisc->rcu_head, qdisc_rcu_free); }