static void multiq_reset(struct Qdisc *sch) { u16 band; struct multiq_sched_data *q = qdisc_priv(sch); for (band = 0; band < q->bands; band++) qdisc_reset(q->queues[band]); sch->q.qlen = 0; q->curband = 0; }
static void prio_reset(struct Qdisc *sch) { int prio; struct prio_sched_data *q = qdisc_priv(sch); for (prio = 0; prio < q->bands; prio++) qdisc_reset(q->queues[prio]); sch->qstats.backlog = 0; sch->q.qlen = 0; }
static void tbf_reset(struct Qdisc *sch) { struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); sch->q.qlen = 0; q->t_c = psched_get_time(); q->tokens = q->buffer; q->ptokens = q->mtu; qdisc_watchdog_cancel(&q->watchdog); }
static void prio_reset(struct Qdisc *sch) { int prio; struct prio_sched_data *q = qdisc_priv(sch); for (prio = 0; prio < q->bands; prio++) qdisc_reset(q->queues[prio]); sch->q.qlen = 0; q->enable_flow = 1; }
static void tbf_reset(struct Qdisc* sch) { struct tbf_sched_data *q = qdisc_priv(sch); qdisc_reset(q->qdisc); sch->q.qlen = 0; PSCHED_GET_TIME(q->t_c); q->tokens = q->buffer; q->ptokens = q->mtu; sch->flags &= ~TCQ_F_THROTTLED; del_timer(&q->wd_timer); }
void dev_deactivate(struct net_device *dev) { struct Qdisc *qdisc; struct sk_buff *skb; int running; spin_lock_bh(&dev->queue_lock); qdisc = dev->qdisc; dev->qdisc = &noop_qdisc; qdisc_reset(qdisc); skb = dev->gso_skb; dev->gso_skb = NULL; spin_unlock_bh(&dev->queue_lock); kfree_skb(skb); dev_watchdog_down(dev); /* Wait for outstanding qdisc-less dev_queue_xmit calls. */ synchronize_rcu(); /* Wait for outstanding qdisc_run calls. */ do { while (test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state)) yield(); /* * Double-check inside queue lock to ensure that all effects * of the queue run are visible when we return. */ spin_lock_bh(&dev->queue_lock); running = test_bit(__LINK_STATE_QDISC_RUNNING, &dev->state); spin_unlock_bh(&dev->queue_lock); /* * The running flag should never be set at this point because * we've already set dev->qdisc to noop_qdisc *inside* the same * pair of spin locks. That is, if any qdisc_run starts after * our initial test it should see the noop_qdisc and then * clear the RUNNING bit before dropping the queue lock. So * if it is set here then we've found a bug. */ } while (WARN_ON_ONCE(running)); }
void dev_deactivate(struct net_device *dev) { struct Qdisc *qdisc; spin_lock_bh(&dev->queue_lock); qdisc = dev->qdisc; dev->qdisc = &noop_qdisc; qdisc_reset(qdisc); spin_unlock_bh(&dev->queue_lock); dev_watchdog_down(dev); while (test_bit(__LINK_STATE_SCHED, &dev->state)) yield(); spin_unlock_wait(&dev->xmit_lock); }
static void dev_deactivate_queue(struct net_device *dev, struct netdev_queue *dev_queue, void *_qdisc_default) { struct Qdisc *qdisc_default = _qdisc_default; struct Qdisc *qdisc; qdisc = dev_queue->qdisc; if (qdisc) { spin_lock_bh(qdisc_lock(qdisc)); if (!(qdisc->flags & TCQ_F_BUILTIN)) set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state); rcu_assign_pointer(dev_queue->qdisc, qdisc_default); qdisc_reset(qdisc); spin_unlock_bh(qdisc_lock(qdisc)); } }
/* Attach toplevel qdisc to device queue. */ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, struct Qdisc *qdisc) { struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; spinlock_t *root_lock; root_lock = qdisc_lock(oqdisc); spin_lock_bh(root_lock); /* Prune old scheduler */ if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) qdisc_reset(oqdisc); /* ... and graft new one */ if (qdisc == NULL) qdisc = &noop_qdisc; dev_queue->qdisc_sleeping = qdisc; rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc); spin_unlock_bh(root_lock); return oqdisc; }
static void teql_destroy(struct Qdisc *sch) { struct Qdisc *q, *prev; struct teql_sched_data *dat = qdisc_priv(sch); struct teql_master *master = dat->m; prev = master->slaves; if (prev) { do { q = NEXT_SLAVE(prev); if (q == sch) { NEXT_SLAVE(prev) = NEXT_SLAVE(q); if (q == master->slaves) { master->slaves = NEXT_SLAVE(q); if (q == master->slaves) { struct netdev_queue *txq; spinlock_t *root_lock; txq = netdev_get_tx_queue(master->dev, 0); master->slaves = NULL; root_lock = qdisc_root_sleeping_lock(txq->qdisc); spin_lock_bh(root_lock); qdisc_reset(txq->qdisc); spin_unlock_bh(root_lock); } } skb_queue_purge(&dat->q); teql_neigh_release(xchg(&dat->ncache, NULL)); break; } } while ((prev = q) != master->slaves); } }
void dev_deactivate(struct device *dev) { struct Qdisc *qdisc; start_bh_atomic(); qdisc = xchg(&dev->qdisc, &noop_qdisc); qdisc_reset(qdisc); if (qdisc->h.forw) { struct Qdisc_head **hp, *h; for (hp = &qdisc_head.forw; (h = *hp) != &qdisc_head; hp = &h->forw) { if (h == &qdisc->h) { *hp = h->forw; h->forw = NULL; break; } } } end_bh_atomic(); }