void qdisc_destroy(struct Qdisc *qdisc) { struct Qdisc_ops *ops = qdisc->ops; struct net_device *dev; if (qdisc->flags&TCQ_F_BUILTIN || !atomic_dec_and_test(&qdisc->refcnt)) return; dev = qdisc->dev; if (dev) { struct Qdisc *q, **qp; for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) { if (q == qdisc) { *qp = q->next; break; } } } #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); kfree(qdisc); }
void qdisc_destroy(struct Qdisc *qdisc) { struct Qdisc_ops *ops = qdisc->ops; if (!atomic_dec_and_test(&qdisc->refcnt)) return; #ifdef CONFIG_NET_SCHED if (qdisc->dev) { struct Qdisc *q, **qp; for (qp = &qdisc->dev->qdisc_list; (q=*qp) != NULL; qp = &q->next) if (q == qdisc) { *qp = q->next; q->next = NULL; break; } } #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&qdisc->stats); #endif #endif start_bh_atomic(); if (ops->reset) ops->reset(qdisc); if (ops->destroy) ops->destroy(qdisc); end_bh_atomic(); if (!(qdisc->flags&TCQ_F_BUILTIN)) kfree(qdisc); }
void tcf_police_destroy(struct tcf_police *p) { unsigned h = tcf_police_hash(p->index); struct tcf_police **p1p; for (p1p = &tcf_police_ht[h]; *p1p; p1p = &(*p1p)->next) { if (*p1p == p) { write_lock_bh(&police_lock); *p1p = p->next; write_unlock_bh(&police_lock); #ifdef CONFIG_NET_ESTIMATOR qdisc_kill_estimator(&p->stats); #endif if (p->R_tab) qdisc_put_rtab(p->R_tab); if (p->P_tab) qdisc_put_rtab(p->P_tab); kfree(p); return; } } BUG_TRAP(0); }