Release 4.16 net/sched/sch_generic.c
/*
* net/sched/sch_generic.c Generic packet scheduler routines.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
* Jamal Hadi Salim, <hadi@cyberus.ca> 990601
* - Ingress support
*/
#include <linux/bitops.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
#include <linux/rcupdate.h>
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/if_vlan.h>
#include <linux/skb_array.h>
#include <linux/if_macvlan.h>
#include <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/dst.h>
#include <trace/events/qdisc.h>
#include <net/xfrm.h>
/* Qdisc to use by default */
const struct Qdisc_ops *default_qdisc_ops = &pfifo_fast_ops;
EXPORT_SYMBOL(default_qdisc_ops);
/* Main transmission queue. */
/* Modifications to data participating in scheduling must be protected with
* qdisc_lock(qdisc) spinlock.
*
* The idea is the following:
* - enqueue, dequeue are serialized via qdisc root lock
* - ingress filtering is also serialized via qdisc root lock
* - updates to tree and tree walking are only done under the rtnl mutex.
*/
static inline struct sk_buff *__skb_dequeue_bad_txq(struct Qdisc *q)
{
const struct netdev_queue *txq = q->dev_queue;
spinlock_t *lock = NULL;
struct sk_buff *skb;
if (q->flags & TCQ_F_NOLOCK) {
lock = qdisc_lock(q);
spin_lock(lock);
}
skb = skb_peek(&q->skb_bad_txq);
if (skb) {
/* check the reason of requeuing without tx lock first */
txq = skb_get_tx_queue(txq->dev, skb);
if (!netif_xmit_frozen_or_stopped(txq)) {
skb = __skb_dequeue(&q->skb_bad_txq);
if (qdisc_is_percpu_stats(q)) {
qdisc_qstats_cpu_backlog_dec(q, skb);
qdisc_qstats_cpu_qlen_dec(q);
} else {
qdisc_qstats_backlog_dec(q, skb);
q->q.qlen--;
}
} else {
skb = NULL;
}
}
if (lock)
spin_unlock(lock);
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 162 | 100.00% | 1 | 100.00% |
| Total | 162 | 100.00% | 1 | 100.00% |
static inline struct sk_buff *qdisc_dequeue_skb_bad_txq(struct Qdisc *q)
{
struct sk_buff *skb = skb_peek(&q->skb_bad_txq);
if (unlikely(skb))
skb = __skb_dequeue_bad_txq(q);
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 44 | 100.00% | 1 | 100.00% |
| Total | 44 | 100.00% | 1 | 100.00% |
static inline void qdisc_enqueue_skb_bad_txq(struct Qdisc *q,
struct sk_buff *skb)
{
spinlock_t *lock = NULL;
if (q->flags & TCQ_F_NOLOCK) {
lock = qdisc_lock(q);
spin_lock(lock);
}
__skb_queue_tail(&q->skb_bad_txq, skb);
if (qdisc_is_percpu_stats(q)) {
qdisc_qstats_cpu_backlog_inc(q, skb);
qdisc_qstats_cpu_qlen_inc(q);
} else {
qdisc_qstats_backlog_inc(q, skb);
q->q.qlen++;
}
if (lock)
spin_unlock(lock);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 64 | 62.75% | 1 | 50.00% |
| Eric Dumazet | 38 | 37.25% | 1 | 50.00% |
| Total | 102 | 100.00% | 2 | 100.00% |
static inline int __dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
{
while (skb) {
struct sk_buff *next = skb->next;
__skb_queue_tail(&q->gso_skb, skb);
q->qstats.requeues++;
qdisc_qstats_backlog_inc(q, skb);
q->q.qlen++; /* it's still part of the queue */
skb = next;
}
__netif_schedule(q);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Wei Yongjun | 20 | 26.32% | 1 | 10.00% |
| Jamal Hadi Salim | 19 | 25.00% | 1 | 10.00% |
| Jarek Poplawski | 12 | 15.79% | 2 | 20.00% |
| Krishna Kumar | 8 | 10.53% | 1 | 10.00% |
| Américo Wang | 7 | 9.21% | 1 | 10.00% |
| John Fastabend | 5 | 6.58% | 1 | 10.00% |
| David S. Miller | 2 | 2.63% | 1 | 10.00% |
| Linus Torvalds (pre-git) | 2 | 2.63% | 1 | 10.00% |
| Andi Kleen | 1 | 1.32% | 1 | 10.00% |
| Total | 76 | 100.00% | 10 | 100.00% |
static inline int dev_requeue_skb_locked(struct sk_buff *skb, struct Qdisc *q)
{
spinlock_t *lock = qdisc_lock(q);
spin_lock(lock);
while (skb) {
struct sk_buff *next = skb->next;
__skb_queue_tail(&q->gso_skb, skb);
qdisc_qstats_cpu_requeues_inc(q);
qdisc_qstats_cpu_backlog_inc(q, skb);
qdisc_qstats_cpu_qlen_inc(q);
skb = next;
}
spin_unlock(lock);
__netif_schedule(q);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 66 | 73.33% | 1 | 50.00% |
| Wei Yongjun | 24 | 26.67% | 1 | 50.00% |
| Total | 90 | 100.00% | 2 | 100.00% |
static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
{
if (q->flags & TCQ_F_NOLOCK)
return dev_requeue_skb_locked(skb, q);
else
return __dev_requeue_skb(skb, q);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 42 | 100.00% | 1 | 100.00% |
| Total | 42 | 100.00% | 1 | 100.00% |
static void try_bulk_dequeue_skb(struct Qdisc *q,
struct sk_buff *skb,
const struct netdev_queue *txq,
int *packets)
{
int bytelimit = qdisc_avail_bulklimit(txq) - skb->len;
while (bytelimit > 0) {
struct sk_buff *nskb = q->dequeue(q);
if (!nskb)
break;
bytelimit -= nskb->len; /* covers GSO len */
skb->next = nskb;
skb = nskb;
(*packets)++; /* GSO counts as one pkt */
}
skb->next = NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Jesper Dangaard Brouer | 62 | 65.96% | 3 | 75.00% |
| Eric Dumazet | 32 | 34.04% | 1 | 25.00% |
| Total | 94 | 100.00% | 4 | 100.00% |
/* This variant of try_bulk_dequeue_skb() makes sure
* all skbs in the chain are for the same txq
*/
static void try_bulk_dequeue_skb_slow(struct Qdisc *q,
struct sk_buff *skb,
int *packets)
{
int mapping = skb_get_queue_mapping(skb);
struct sk_buff *nskb;
int cnt = 0;
do {
nskb = q->dequeue(q);
if (!nskb)
break;
if (unlikely(skb_get_queue_mapping(nskb) != mapping)) {
qdisc_enqueue_skb_bad_txq(q, nskb);
break;
}
skb->next = nskb;
skb = nskb;
} while (++cnt < 8);
(*packets) += cnt;
skb->next = NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Eric Dumazet | 105 | 96.33% | 1 | 50.00% |
| John Fastabend | 4 | 3.67% | 1 | 50.00% |
| Total | 109 | 100.00% | 2 | 100.00% |
/* Note that dequeue_skb can possibly return a SKB list (via skb->next).
* A requeued skb (via q->gso_skb) can also be a SKB list.
*/
static struct sk_buff *dequeue_skb(struct Qdisc *q, bool *validate,
int *packets)
{
const struct netdev_queue *txq = q->dev_queue;
struct sk_buff *skb = NULL;
*packets = 1;
if (unlikely(!skb_queue_empty(&q->gso_skb))) {
spinlock_t *lock = NULL;
if (q->flags & TCQ_F_NOLOCK) {
lock = qdisc_lock(q);
spin_lock(lock);
}
skb = skb_peek(&q->gso_skb);
/* skb may be null if another cpu pulls gso_skb off in between
* empty check and lock.
*/
if (!skb) {
if (lock)
spin_unlock(lock);
goto validate;
}
/* skb in gso_skb were already validated */
*validate = false;
if (xfrm_offload(skb))
*validate = true;
/* check the reason of requeuing without tx lock first */
txq = skb_get_tx_queue(txq->dev, skb);
if (!netif_xmit_frozen_or_stopped(txq)) {
skb = __skb_dequeue(&q->gso_skb);
if (qdisc_is_percpu_stats(q)) {
qdisc_qstats_cpu_backlog_dec(q, skb);
qdisc_qstats_cpu_qlen_dec(q);
} else {
qdisc_qstats_backlog_dec(q, skb);
q->q.qlen--;
}
} else {
skb = NULL;
}
if (lock)
spin_unlock(lock);
goto trace;
}
validate:
*validate = true;
if ((q->flags & TCQ_F_ONETXQUEUE) &&
netif_xmit_frozen_or_stopped(txq))
return skb;
skb = qdisc_dequeue_skb_bad_txq(q);
if (unlikely(skb))
goto bulk;
skb = q->dequeue(q);
if (skb) {
bulk:
if (qdisc_may_bulk(q))
try_bulk_dequeue_skb(q, skb, txq, packets);
else
try_bulk_dequeue_skb_slow(q, skb, packets);
}
trace:
trace_qdisc_dequeue(q, txq, *packets, skb);
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 136 | 41.46% | 3 | 15.00% |
| Eric Dumazet | 60 | 18.29% | 3 | 15.00% |
| Jesper Dangaard Brouer | 40 | 12.20% | 3 | 15.00% |
| Jarek Poplawski | 29 | 8.84% | 2 | 10.00% |
| Jamal Hadi Salim | 25 | 7.62% | 1 | 5.00% |
| Steffen Klassert | 12 | 3.66% | 1 | 5.00% |
| Krishna Kumar | 9 | 2.74% | 1 | 5.00% |
| David S. Miller | 8 | 2.44% | 3 | 15.00% |
| Américo Wang | 7 | 2.13% | 1 | 5.00% |
| Tom Herbert | 1 | 0.30% | 1 | 5.00% |
| Daniel Borkmann | 1 | 0.30% | 1 | 5.00% |
| Total | 328 | 100.00% | 20 | 100.00% |
/*
* Transmit possibly several skbs, and handle the return status as
* required. Owning running seqcount bit guarantees that
* only one CPU can execute this function.
*
* Returns to the caller:
* false - hardware queue frozen backoff
* true - feel free to send more pkts
*/
bool sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
struct net_device *dev, struct netdev_queue *txq,
spinlock_t *root_lock, bool validate)
{
int ret = NETDEV_TX_BUSY;
bool again = false;
/* And release qdisc */
if (root_lock)
spin_unlock(root_lock);
/* Note that we validate skb (GSO, checksum, ...) outside of locks */
if (validate)
skb = validate_xmit_skb_list(skb, dev, &again);
#ifdef CONFIG_XFRM_OFFLOAD
if (unlikely(again)) {
if (root_lock)
spin_lock(root_lock);
dev_requeue_skb(skb, q);
return false;
}
#endif
if (likely(skb)) {
HARD_TX_LOCK(dev, txq, smp_processor_id());
if (!netif_xmit_frozen_or_stopped(txq))
skb = dev_hard_start_xmit(skb, dev, txq, &ret);
HARD_TX_UNLOCK(dev, txq);
} else {
if (root_lock)
spin_lock(root_lock);
return true;
}
if (root_lock)
spin_lock(root_lock);
if (!dev_xmit_complete(ret)) {
/* Driver returned NETDEV_TX_BUSY - requeue skb */
if (unlikely(ret != NETDEV_TX_BUSY))
net_warn_ratelimited("BUG %s code %d qlen %d\n",
dev->name, ret, q->q.qlen);
dev_requeue_skb(skb, q);
return false;
}
if (ret && netif_xmit_frozen_or_stopped(txq))
return false;
return true;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Jamal Hadi Salim | 42 | 17.80% | 2 | 6.90% |
| Steffen Klassert | 41 | 17.37% | 1 | 3.45% |
| David S. Miller | 27 | 11.44% | 6 | 20.69% |
| Krishna Kumar | 25 | 10.59% | 2 | 6.90% |
| Eric Dumazet | 25 | 10.59% | 2 | 6.90% |
| John Fastabend | 22 | 9.32% | 2 | 6.90% |
| Linus Torvalds (pre-git) | 15 | 6.36% | 4 | 13.79% |
| Lars Persson | 12 | 5.08% | 1 | 3.45% |
| Stephen Hemminger | 8 | 3.39% | 1 | 3.45% |
| Peter P. Waskiewicz Jr | 7 | 2.97% | 1 | 3.45% |
| Jarek Poplawski | 4 | 1.69% | 1 | 3.45% |
| Herbert Xu | 3 | 1.27% | 3 | 10.34% |
| Tom Herbert | 2 | 0.85% | 1 | 3.45% |
| Thomas Graf | 2 | 0.85% | 1 | 3.45% |
| Joe Perches | 1 | 0.42% | 1 | 3.45% |
| Total | 236 | 100.00% | 29 | 100.00% |
/*
* NOTE: Called under qdisc_lock(q) with locally disabled BH.
*
* running seqcount guarantees only one CPU can process
* this qdisc at a time. qdisc_lock(q) serializes queue accesses for
* this queue.
*
* netif_tx_lock serializes accesses to device driver.
*
* qdisc_lock(q) and netif_tx_lock are mutually exclusive,
* if one is grabbed, another must be free.
*
* Note, that this procedure can be called by a watchdog timer
*
* Returns to the caller:
* 0 - queue is empty or throttled.
* >0 - queue is not empty.
*
*/
static inline bool qdisc_restart(struct Qdisc *q, int *packets)
{
bool more, validate, nolock = q->flags & TCQ_F_NOLOCK;
spinlock_t *root_lock = NULL;
struct netdev_queue *txq;
struct net_device *dev;
struct sk_buff *skb;
/* Dequeue packet */
if (nolock && test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
return false;
skb = dequeue_skb(q, &validate, packets);
if (unlikely(!skb)) {
if (nolock)
clear_bit(__QDISC_STATE_RUNNING, &q->state);
return false;
}
if (!nolock)
root_lock = qdisc_lock(q);
dev = qdisc_dev(q);
txq = skb_get_tx_queue(dev, skb);
more = sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
if (nolock)
clear_bit(__QDISC_STATE_RUNNING, &q->state);
return more;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Krishna Kumar | 79 | 46.75% | 1 | 14.29% |
| John Fastabend | 78 | 46.15% | 3 | 42.86% |
| Jesper Dangaard Brouer | 6 | 3.55% | 1 | 14.29% |
| Eric Dumazet | 5 | 2.96% | 1 | 14.29% |
| Daniel Borkmann | 1 | 0.59% | 1 | 14.29% |
| Total | 169 | 100.00% | 7 | 100.00% |
void __qdisc_run(struct Qdisc *q)
{
int quota = dev_tx_weight;
int packets;
while (qdisc_restart(q, &packets)) {
/*
* Ordered by possible occurrence: Postpone processing if
* 1. we've exceeded packet quota
* 2. another process needs the CPU;
*/
quota -= packets;
if (quota <= 0 || need_resched()) {
__netif_schedule(q);
break;
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Herbert Xu | 28 | 53.85% | 3 | 33.33% |
| Jesper Dangaard Brouer | 10 | 19.23% | 1 | 11.11% |
| Jamal Hadi Salim | 6 | 11.54% | 1 | 11.11% |
| David S. Miller | 5 | 9.62% | 2 | 22.22% |
| Krishna Kumar | 2 | 3.85% | 1 | 11.11% |
| Matthias Tafelmeier | 1 | 1.92% | 1 | 11.11% |
| Total | 52 | 100.00% | 9 | 100.00% |
unsigned long dev_trans_start(struct net_device *dev)
{
unsigned long val, res;
unsigned int i;
if (is_vlan_dev(dev))
dev = vlan_dev_real_dev(dev);
else if (netif_is_macvlan(dev))
dev = macvlan_dev_real_dev(dev);
res = netdev_get_tx_queue(dev, 0)->trans_start;
for (i = 1; i < dev->num_tx_queues; i++) {
val = netdev_get_tx_queue(dev, i)->trans_start;
if (val && time_after(val, res))
res = val;
}
return res;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Eric Dumazet | 66 | 61.68% | 1 | 25.00% |
| Nikolay Aleksandrov | 20 | 18.69% | 1 | 25.00% |
| Chris Dion | 15 | 14.02% | 1 | 25.00% |
| Florian Westphal | 6 | 5.61% | 1 | 25.00% |
| Total | 107 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(dev_trans_start);
static void dev_watchdog(struct timer_list *t)
{
struct net_device *dev = from_timer(dev, t, watchdog_timer);
netif_tx_lock(dev);
if (!qdisc_tx_is_noop(dev)) {
if (netif_device_present(dev) &&
netif_running(dev) &&
netif_carrier_ok(dev)) {
int some_queue_timedout = 0;
unsigned int i;
unsigned long trans_start;
for (i = 0; i < dev->num_tx_queues; i++) {
struct netdev_queue *txq;
txq = netdev_get_tx_queue(dev, i);
trans_start = txq->trans_start;
if (netif_xmit_stopped(txq) &&
time_after(jiffies, (trans_start +
dev->watchdog_timeo))) {
some_queue_timedout = 1;
txq->trans_timeout++;
break;
}
}
if (some_queue_timedout) {
WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit queue %u timed out\n",
dev->name, netdev_drivername(dev), i);
dev->netdev_ops->ndo_tx_timeout(dev);
}
if (!mod_timer(&dev->watchdog_timer,
round_jiffies(jiffies +
dev->watchdog_timeo)))
dev_hold(dev);
}
}
netif_tx_unlock(dev);
dev_put(dev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 99 | 47.14% | 7 | 38.89% |
| David S. Miller | 46 | 21.90% | 1 | 5.56% |
| Eric Dumazet | 26 | 12.38% | 1 | 5.56% |
| Kees Cook | 12 | 5.71% | 1 | 5.56% |
| Arjan van de Ven | 11 | 5.24% | 3 | 16.67% |
| Stephen Hemminger | 8 | 3.81% | 2 | 11.11% |
| David Decotigny | 5 | 2.38% | 1 | 5.56% |
| Herbert Xu | 2 | 0.95% | 1 | 5.56% |
| Tom Herbert | 1 | 0.48% | 1 | 5.56% |
| Total | 210 | 100.00% | 18 | 100.00% |
void __netdev_watchdog_up(struct net_device *dev)
{
if (dev->netdev_ops->ndo_tx_timeout) {
if (dev->watchdog_timeo <= 0)
dev->watchdog_timeo = 5*HZ;
if (!mod_timer(&dev->watchdog_timer,
round_jiffies(jiffies + dev->watchdog_timeo)))
dev_hold(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 55 | 90.16% | 4 | 66.67% |
| Stephen Hemminger | 3 | 4.92% | 1 | 16.67% |
| Venkatesh Pallipadi | 3 | 4.92% | 1 | 16.67% |
| Total | 61 | 100.00% | 6 | 100.00% |
static void dev_watchdog_up(struct net_device *dev)
{
__netdev_watchdog_up(dev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 16 | 100.00% | 4 | 100.00% |
| Total | 16 | 100.00% | 4 | 100.00% |
static void dev_watchdog_down(struct net_device *dev)
{
netif_tx_lock_bh(dev);
if (del_timer(&dev->watchdog_timer))
dev_put(dev);
netif_tx_unlock_bh(dev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 33 | 91.67% | 5 | 71.43% |
| Herbert Xu | 2 | 5.56% | 1 | 14.29% |
| Stephen Hemminger | 1 | 2.78% | 1 | 14.29% |
| Total | 36 | 100.00% | 7 | 100.00% |
/**
* netif_carrier_on - set carrier
* @dev: network device
*
* Device has detected that carrier.
*/
void netif_carrier_on(struct net_device *dev)
{
if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
if (dev->reg_state == NETREG_UNINITIALIZED)
return;
atomic_inc(&dev->carrier_up_count);
linkwatch_fire_event(dev);
if (netif_running(dev))
__netdev_watchdog_up(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Denys Vlasenko | 39 | 67.24% | 1 | 20.00% |
| David S. Miller | 9 | 15.52% | 1 | 20.00% |
| David Decotigny | 8 | 13.79% | 2 | 40.00% |
| Jeff Garzik | 2 | 3.45% | 1 | 20.00% |
| Total | 58 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(netif_carrier_on);
/**
* netif_carrier_off - clear carrier
* @dev: network device
*
* Device has detected loss of carrier.
*/
void netif_carrier_off(struct net_device *dev)
{
if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state)) {
if (dev->reg_state == NETREG_UNINITIALIZED)
return;
atomic_inc(&dev->carrier_down_count);
linkwatch_fire_event(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Denys Vlasenko | 28 | 59.57% | 1 | 25.00% |
| David S. Miller | 11 | 23.40% | 1 | 25.00% |
| David Decotigny | 8 | 17.02% | 2 | 50.00% |
| Total | 47 | 100.00% | 4 | 100.00% |
EXPORT_SYMBOL(netif_carrier_off);
/* "NOOP" scheduler: the best scheduler, recommended for all interfaces
under all circumstances. It is difficult to invent anything faster or
cheaper.
*/
static int noop_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
struct sk_buff **to_free)
{
__qdisc_drop(skb, to_free);
return NET_XMIT_CN;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 23 | 71.88% | 2 | 66.67% |
| Eric Dumazet | 9 | 28.12% | 1 | 33.33% |
| Total | 32 | 100.00% | 3 | 100.00% |
static struct sk_buff *noop_dequeue(struct Qdisc *qdisc)
{
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 16 | 100.00% | 1 | 100.00% |
| Total | 16 | 100.00% | 1 | 100.00% |
struct Qdisc_ops noop_qdisc_ops __read_mostly = {
.id = "noop",
.priv_size = 0,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.peek = noop_dequeue,
.owner = THIS_MODULE,
};
static struct netdev_queue noop_netdev_queue = {
.qdisc = &noop_qdisc,
.qdisc_sleeping = &noop_qdisc,
};
struct Qdisc noop_qdisc = {
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.flags = TCQ_F_BUILTIN,
.ops = &noop_qdisc_ops,
.q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
.dev_queue = &noop_netdev_queue,
.running = SEQCNT_ZERO(noop_qdisc.running),
.busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock),
};
EXPORT_SYMBOL(noop_qdisc);
static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
/* register_qdisc() assigns a default of noop_enqueue if unset,
* but __dev_queue_xmit() treats noqueue only as such
* if this is NULL - so clear it here. */
qdisc->enqueue = NULL;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Phil Sutter | 26 | 83.87% | 1 | 50.00% |
| Alexander Aring | 5 | 16.13% | 1 | 50.00% |
| Total | 31 | 100.00% | 2 | 100.00% |
struct Qdisc_ops noqueue_qdisc_ops __read_mostly = {
.id = "noqueue",
.priv_size = 0,
.init = noqueue_init,
.enqueue = noop_enqueue,
.dequeue = noop_dequeue,
.peek = noop_dequeue,
.owner = THIS_MODULE,
};
static const u8 prio2band[TC_PRIO_MAX + 1] = {
1, 2, 2, 2, 1, 2, 0, 0 , 1, 1, 1, 1, 1, 1, 1, 1
};
/* 3-band FIFO queue: old style, but should be a bit faster than
generic prio+fifo combination.
*/
#define PFIFO_FAST_BANDS 3
/*
* Private data for a pfifo_fast scheduler containing:
* - rings for priority bands
*/
struct pfifo_fast_priv {
struct skb_array q[PFIFO_FAST_BANDS];
};
static inline struct skb_array *band2list(struct pfifo_fast_priv *priv,
int band)
{
return &priv->q[band];
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Krishna Kumar | 8 | 30.77% | 1 | 20.00% |
| David S. Miller | 7 | 26.92% | 2 | 40.00% |
| Thomas Graf | 7 | 26.92% | 1 | 20.00% |
| John Fastabend | 4 | 15.38% | 1 | 20.00% |
| Total | 26 | 100.00% | 5 | 100.00% |
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc,
struct sk_buff **to_free)
{
int band = prio2band[skb->priority & TC_PRIO_MAX];
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
struct skb_array *q = band2list(priv, band);
unsigned int pkt_len = qdisc_pkt_len(skb);
int err;
err = skb_array_produce(q, skb);
if (unlikely(err))
return qdisc_drop_cpu(skb, qdisc, to_free);
qdisc_qstats_cpu_qlen_inc(qdisc);
/* Note: skb can not be used after skb_array_produce(),
* so we better not use qdisc_qstats_cpu_backlog_inc()
*/
this_cpu_add(qdisc->cpu_qstats->backlog, pkt_len);
return NET_XMIT_SUCCESS;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 29 | 25.44% | 1 | 11.11% |
| Krishna Kumar | 25 | 21.93% | 1 | 11.11% |
| Eric Dumazet | 23 | 20.18% | 2 | 22.22% |
| David S. Miller | 23 | 20.18% | 1 | 11.11% |
| Thomas Graf | 7 | 6.14% | 2 | 22.22% |
| Linus Torvalds (pre-git) | 5 | 4.39% | 1 | 11.11% |
| Jamal Hadi Salim | 2 | 1.75% | 1 | 11.11% |
| Total | 114 | 100.00% | 9 | 100.00% |
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc)
{
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
struct sk_buff *skb = NULL;
int band;
for (band = 0; band < PFIFO_FAST_BANDS && !skb; band++) {
struct skb_array *q = band2list(priv, band);
if (__skb_array_empty(q))
continue;
skb = skb_array_consume_bh(q);
}
if (likely(skb)) {
qdisc_qstats_cpu_backlog_dec(qdisc, skb);
qdisc_bstats_cpu_update(qdisc, skb);
qdisc_qstats_cpu_qlen_dec(qdisc);
}
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 42 | 38.53% | 1 | 20.00% |
| Krishna Kumar | 21 | 19.27% | 1 | 20.00% |
| Florian Westphal | 20 | 18.35% | 1 | 20.00% |
| Linus Torvalds (pre-git) | 19 | 17.43% | 1 | 20.00% |
| David S. Miller | 7 | 6.42% | 1 | 20.00% |
| Total | 109 | 100.00% | 5 | 100.00% |
static struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc)
{
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
struct sk_buff *skb = NULL;
int band;
for (band = 0; band < PFIFO_FAST_BANDS && !skb; band++) {
struct skb_array *q = band2list(priv, band);
skb = __skb_array_peek(q);
}
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 31 | 42.47% | 1 | 33.33% |
| Jarek Poplawski | 25 | 34.25% | 1 | 33.33% |
| Krishna Kumar | 17 | 23.29% | 1 | 33.33% |
| Total | 73 | 100.00% | 3 | 100.00% |
static void pfifo_fast_reset(struct Qdisc *qdisc)
{
int i, band;
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (band = 0; band < PFIFO_FAST_BANDS; band++) {
struct skb_array *q = band2list(priv, band);
struct sk_buff *skb;
/* NULL ring is possible if destroy path is due to a failed
* skb_array_init() in pfifo_fast_init() case.
*/
if (!q->ring.queue)
continue;
while ((skb = skb_array_consume_bh(q)) != NULL)
kfree_skb(skb);
}
for_each_possible_cpu(i) {
struct gnet_stats_queue *q = per_cpu_ptr(qdisc->cpu_qstats, i);
q->backlog = 0;
q->qlen = 0;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 57 | 47.90% | 1 | 12.50% |
| David S. Miller | 27 | 22.69% | 1 | 12.50% |
| Linus Torvalds (pre-git) | 12 | 10.08% | 3 | 37.50% |
| Américo Wang | 11 | 9.24% | 1 | 12.50% |
| Krishna Kumar | 8 | 6.72% | 1 | 12.50% |
| Thomas Graf | 4 | 3.36% | 1 | 12.50% |
| Total | 119 | 100.00% | 8 | 100.00% |
static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
{
struct tc_prio_qopt opt = { .bands = PFIFO_FAST_BANDS };
memcpy(&opt.priomap, prio2band, TC_PRIO_MAX + 1);
if (nla_put(skb, TCA_OPTIONS, sizeof(opt), &opt))
goto nla_put_failure;
return skb->len;
nla_put_failure:
return -1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 72 | 100.00% | 2 | 100.00% |
| Total | 72 | 100.00% | 2 | 100.00% |
static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
unsigned int qlen = qdisc_dev(qdisc)->tx_queue_len;
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
int prio;
/* guard against zero length rings */
if (!qlen)
return -EINVAL;
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
struct skb_array *q = band2list(priv, prio);
int err;
err = skb_array_init(q, qlen, GFP_KERNEL);
if (err)
return -ENOMEM;
}
/* Can by-pass the queue discipline */
qdisc->flags |= TCQ_F_CAN_BYPASS;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 50 | 43.86% | 1 | 16.67% |
| David S. Miller | 44 | 38.60% | 1 | 16.67% |
| Eric Dumazet | 7 | 6.14% | 1 | 16.67% |
| Krishna Kumar | 7 | 6.14% | 1 | 16.67% |
| Alexander Aring | 5 | 4.39% | 1 | 16.67% |
| Linus Torvalds (pre-git) | 1 | 0.88% | 1 | 16.67% |
| Total | 114 | 100.00% | 6 | 100.00% |
static void pfifo_fast_destroy(struct Qdisc *sch)
{
struct pfifo_fast_priv *priv = qdisc_priv(sch);
int prio;
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
struct skb_array *q = band2list(priv, prio);
/* NULL ring is possible if destroy path is due to a failed
* skb_array_init() in pfifo_fast_init() case.
*/
if (!q->ring.queue)
continue;
/* Destroy ring but no need to kfree_skb because a call to
* pfifo_fast_reset() has already done that work.
*/
ptr_ring_cleanup(&q->ring, NULL);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 73 | 100.00% | 1 | 100.00% |
| Total | 73 | 100.00% | 1 | 100.00% |
static int pfifo_fast_change_tx_queue_len(struct Qdisc *sch,
unsigned int new_len)
{
struct pfifo_fast_priv *priv = qdisc_priv(sch);
struct skb_array *bands[PFIFO_FAST_BANDS];
int prio;
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) {
struct skb_array *q = band2list(priv, prio);
bands[prio] = q;
}
return skb_array_resize_multiple(bands, PFIFO_FAST_BANDS, new_len,
GFP_KERNEL);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Américo Wang | 82 | 100.00% | 1 | 100.00% |
| Total | 82 | 100.00% | 1 | 100.00% |
struct Qdisc_ops pfifo_fast_ops __read_mostly = {
.id = "pfifo_fast",
.priv_size = sizeof(struct pfifo_fast_priv),
.enqueue = pfifo_fast_enqueue,
.dequeue = pfifo_fast_dequeue,
.peek = pfifo_fast_peek,
.init = pfifo_fast_init,
.destroy = pfifo_fast_destroy,
.reset = pfifo_fast_reset,
.dump = pfifo_fast_dump,
.change_tx_queue_len = pfifo_fast_change_tx_queue_len,
.owner = THIS_MODULE,
.static_flags = TCQ_F_NOLOCK | TCQ_F_CPUSTATS,
};
EXPORT_SYMBOL(pfifo_fast_ops);
static struct lock_class_key qdisc_tx_busylock;
static struct lock_class_key qdisc_running_key;
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
struct netlink_ext_ack *extack)
{
void *p;
struct Qdisc *sch;
unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size;
int err = -ENOBUFS;
struct net_device *dev;
if (!dev_queue) {
NL_SET_ERR_MSG(extack, "No device queue given");
err = -EINVAL;
goto errout;
}
dev = dev_queue->dev;
p = kzalloc_node(size, GFP_KERNEL,
netdev_queue_numa_node_read(dev_queue));
if (!p)
goto errout;
sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
/* if we got non aligned memory, ask more and do alignment ourself */
if (sch != p) {
kfree(p);
p = kzalloc_node(size + QDISC_ALIGNTO - 1, GFP_KERNEL,
netdev_queue_numa_node_read(dev_queue));
if (!p)
goto errout;
sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p);
sch->padded = (char *) sch - (char *) p;
}
__skb_queue_head_init(&sch->gso_skb);
__skb_queue_head_init(&sch->skb_bad_txq);
qdisc_skb_head_init(&sch->q);
spin_lock_init(&sch->q.lock);
if (ops->static_flags & TCQ_F_CPUSTATS) {
sch->cpu_bstats =
netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu);
if (!sch->cpu_bstats)
goto errout1;
sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
if (!sch->cpu_qstats) {
free_percpu(sch->cpu_bstats);
goto errout1;
}
}
spin_lock_init(&sch->busylock);
lockdep_set_class(&sch->busylock,
dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
seqcount_init(&sch->running);
lockdep_set_class(&sch->running,
dev->qdisc_running_key ?: &qdisc_running_key);
sch->ops = ops;
sch->flags = ops->static_flags;
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev_queue = dev_queue;
dev_hold(dev);
refcount_set(&sch->refcnt, 1);
return sch;
errout1:
kfree(p);
errout:
return ERR_PTR(err);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Eric Dumazet | 122 | 29.90% | 5 | 25.00% |
| John Fastabend | 90 | 22.06% | 3 | 15.00% |
| Linus Torvalds (pre-git) | 70 | 17.16% | 3 | 15.00% |
| Stephen Hemminger | 40 | 9.80% | 2 | 10.00% |
| Thomas Graf | 30 | 7.35% | 1 | 5.00% |
| Jesus Sanchez-Palencia | 19 | 4.66% | 1 | 5.00% |
| Alexander Aring | 12 | 2.94% | 1 | 5.00% |
| Florian Westphal | 11 | 2.70% | 1 | 5.00% |
| David S. Miller | 9 | 2.21% | 1 | 5.00% |
| Patrick McHardy | 4 | 0.98% | 1 | 5.00% |
| Elena Reshetova | 1 | 0.25% | 1 | 5.00% |
| Total | 408 | 100.00% | 20 | 100.00% |
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
unsigned int parentid,
struct netlink_ext_ack *extack)
{
struct Qdisc *sch;
if (!try_module_get(ops->owner)) {
NL_SET_ERR_MSG(extack, "Failed to increase module reference counter");
return NULL;
}
sch = qdisc_alloc(dev_queue, ops, extack);
if (IS_ERR(sch)) {
module_put(ops->owner);
return NULL;
}
sch->parent = parentid;
if (!ops->init || ops->init(sch, NULL, extack) == 0)
return sch;
qdisc_destroy(sch);
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Thomas Graf | 35 | 28.93% | 2 | 15.38% |
| Linus Torvalds (pre-git) | 25 | 20.66% | 3 | 23.08% |
| Alexander Aring | 18 | 14.88% | 3 | 23.08% |
| Eric Dumazet | 15 | 12.40% | 1 | 7.69% |
| Stephen Hemminger | 11 | 9.09% | 2 | 15.38% |
| Patrick McHardy | 10 | 8.26% | 1 | 7.69% |
| David S. Miller | 7 | 5.79% | 1 | 7.69% |
| Total | 121 | 100.00% | 13 | 100.00% |
EXPORT_SYMBOL(qdisc_create_dflt);
/* Under qdisc_lock(qdisc) and BH! */
void qdisc_reset(struct Qdisc *qdisc)
{
const struct Qdisc_ops *ops = qdisc->ops;
struct sk_buff *skb, *tmp;
if (ops->reset)
ops->reset(qdisc);
skb_queue_walk_safe(&qdisc->gso_skb, skb, tmp) {
__skb_unlink(skb, &qdisc->gso_skb);
kfree_skb_list(skb);
}
skb_queue_walk_safe(&qdisc->skb_bad_txq, skb, tmp) {
__skb_unlink(skb, &qdisc->skb_bad_txq);
kfree_skb_list(skb);
}
qdisc->q.qlen = 0;
qdisc->qstats.backlog = 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 44 | 41.12% | 2 | 25.00% |
| Linus Torvalds (pre-git) | 31 | 28.97% | 1 | 12.50% |
| Krishna Kumar | 11 | 10.28% | 1 | 12.50% |
| Eric Dumazet | 8 | 7.48% | 2 | 25.00% |
| Konstantin Khlebnikov | 7 | 6.54% | 1 | 12.50% |
| Jarek Poplawski | 6 | 5.61% | 1 | 12.50% |
| Total | 107 | 100.00% | 8 | 100.00% |
EXPORT_SYMBOL(qdisc_reset);
void qdisc_free(struct Qdisc *qdisc)
{
if (qdisc_is_percpu_stats(qdisc)) {
free_percpu(qdisc->cpu_bstats);
free_percpu(qdisc->cpu_qstats);
}
kfree((char *) qdisc - qdisc->padded);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 23 | 50.00% | 2 | 50.00% |
| Eric Dumazet | 20 | 43.48% | 1 | 25.00% |
| Américo Wang | 3 | 6.52% | 1 | 25.00% |
| Total | 46 | 100.00% | 4 | 100.00% |
void qdisc_destroy(struct Qdisc *qdisc)
{
const struct Qdisc_ops *ops = qdisc->ops;
struct sk_buff *skb, *tmp;
if (qdisc->flags & TCQ_F_BUILTIN ||
!refcount_dec_and_test(&qdisc->refcnt))
return;
#ifdef CONFIG_NET_SCHED
qdisc_hash_del(qdisc);
qdisc_put_stab(rtnl_dereference(qdisc->stab));
#endif
gen_kill_estimator(&qdisc->rate_est);
if (ops->reset)
ops->reset(qdisc);
if (ops->destroy)
ops->destroy(qdisc);
module_put(ops->owner);
dev_put(qdisc_dev(qdisc));
skb_queue_walk_safe(&qdisc->gso_skb, skb, tmp) {
__skb_unlink(skb, &qdisc->gso_skb);
kfree_skb_list(skb);
}
skb_queue_walk_safe(&qdisc->skb_bad_txq, skb, tmp) {
__skb_unlink(skb, &qdisc->skb_bad_txq);
kfree_skb_list(skb);
}
qdisc_free(qdisc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Patrick McHardy | 55 | 32.35% | 2 | 10.53% |
| John Fastabend | 46 | 27.06% | 2 | 10.53% |
| David S. Miller | 34 | 20.00% | 4 | 21.05% |
| Eric Dumazet | 10 | 5.88% | 3 | 15.79% |
| Jarek Poplawski | 9 | 5.29% | 2 | 10.53% |
| Jussi Kivilinna | 7 | 4.12% | 1 | 5.26% |
| Linus Torvalds (pre-git) | 5 | 2.94% | 1 | 5.26% |
| Jiri Kosina | 1 | 0.59% | 1 | 5.26% |
| Andrew Morton | 1 | 0.59% | 1 | 5.26% |
| Elena Reshetova | 1 | 0.59% | 1 | 5.26% |
| Américo Wang | 1 | 0.59% | 1 | 5.26% |
| Total | 170 | 100.00% | 19 | 100.00% |
EXPORT_SYMBOL(qdisc_destroy);
/* 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);
/* ... 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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Patrick McHardy | 78 | 100.00% | 1 | 100.00% |
| Total | 78 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(dev_graft_qdisc);
static void attach_one_default_qdisc(struct net_device *dev,
struct netdev_queue *dev_queue,
void *_unused)
{
struct Qdisc *qdisc;
const struct Qdisc_ops *ops = default_qdisc_ops;
if (dev->priv_flags & IFF_NO_QUEUE)
ops = &noqueue_qdisc_ops;
qdisc = qdisc_create_dflt(dev_queue, ops, TC_H_ROOT, NULL);
if (!qdisc) {
netdev_info(dev, "activation failed\n");
return;
}
if (!netif_is_multiqueue(dev))
qdisc->flags |= TCQ_F_ONETXQUEUE | TCQ_F_NOPARENT;
dev_queue->qdisc_sleeping = qdisc;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 32 | 33.33% | 3 | 25.00% |
| David S. Miller | 22 | 22.92% | 2 | 16.67% |
| Eric Dumazet | 20 | 20.83% | 3 | 25.00% |
| Phil Sutter | 18 | 18.75% | 2 | 16.67% |
| Alexander Aring | 2 | 2.08% | 1 | 8.33% |
| Patrick McHardy | 2 | 2.08% | 1 | 8.33% |
| Total | 96 | 100.00% | 12 | 100.00% |
static void attach_default_qdiscs(struct net_device *dev)
{
struct netdev_queue *txq;
struct Qdisc *qdisc;
txq = netdev_get_tx_queue(dev, 0);
if (!netif_is_multiqueue(dev) ||
dev->priv_flags & IFF_NO_QUEUE) {
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
dev->qdisc = txq->qdisc_sleeping;
qdisc_refcount_inc(dev->qdisc);
} else {
qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT, NULL);
if (qdisc) {
dev->qdisc = qdisc;
qdisc->ops->attach(qdisc);
}
}
#ifdef CONFIG_NET_SCHED
if (dev->qdisc != &noop_qdisc)
qdisc_hash_add(dev->qdisc, false);
#endif
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 96 | 73.28% | 1 | 12.50% |
| Jiri Kosina | 20 | 15.27% | 2 | 25.00% |
| Eric Dumazet | 7 | 5.34% | 2 | 25.00% |
| Américo Wang | 3 | 2.29% | 1 | 12.50% |
| Phil Sutter | 3 | 2.29% | 1 | 12.50% |
| Alexander Aring | 2 | 1.53% | 1 | 12.50% |
| Total | 131 | 100.00% | 8 | 100.00% |
static void transition_one_qdisc(struct net_device *dev,
struct netdev_queue *dev_queue,
void *_need_watchdog)
{
struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
int *need_watchdog_p = _need_watchdog;
if (!(new_qdisc->flags & TCQ_F_BUILTIN))
clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
if (need_watchdog_p) {
dev_queue->trans_start = 0;
*need_watchdog_p = 1;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 63 | 76.83% | 4 | 50.00% |
| Eric Dumazet | 8 | 9.76% | 1 | 12.50% |
| Patrick McHardy | 7 | 8.54% | 1 | 12.50% |
| Linus Torvalds (pre-git) | 3 | 3.66% | 1 | 12.50% |
| Tommy S. Christensen | 1 | 1.22% | 1 | 12.50% |
| Total | 82 | 100.00% | 8 | 100.00% |
void dev_activate(struct net_device *dev)
{
int need_watchdog;
/* No queueing discipline is attached to device;
* create default one for devices, which need queueing
* and noqueue_qdisc for virtual interfaces
*/
if (dev->qdisc == &noop_qdisc)
attach_default_qdiscs(dev);
if (!netif_carrier_ok(dev))
/* Delay activation until next carrier-on event */
return;
need_watchdog = 0;
netdev_for_each_tx_queue(dev, transition_one_qdisc, &need_watchdog);
if (dev_ingress_queue(dev))
transition_one_qdisc(dev, dev_ingress_queue(dev), NULL);
if (need_watchdog) {
netif_trans_update(dev);
dev_watchdog_up(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 58 | 66.67% | 3 | 33.33% |
| Eric Dumazet | 10 | 11.49% | 1 | 11.11% |
| Linus Torvalds (pre-git) | 10 | 11.49% | 2 | 22.22% |
| Patrick McHardy | 5 | 5.75% | 1 | 11.11% |
| Florian Westphal | 3 | 3.45% | 1 | 11.11% |
| Stephen Hemminger | 1 | 1.15% | 1 | 11.11% |
| Total | 87 | 100.00% | 9 | 100.00% |
EXPORT_SYMBOL(dev_activate);
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 = rtnl_dereference(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));
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 87 | 88.78% | 6 | 66.67% |
| Jarek Poplawski | 4 | 4.08% | 1 | 11.11% |
| Linus Torvalds (pre-git) | 4 | 4.08% | 1 | 11.11% |
| John Fastabend | 3 | 3.06% | 1 | 11.11% |
| Total | 98 | 100.00% | 9 | 100.00% |
static bool some_qdisc_is_busy(struct net_device *dev)
{
unsigned int i;
for (i = 0; i < dev->num_tx_queues; i++) {
struct netdev_queue *dev_queue;
spinlock_t *root_lock;
struct Qdisc *q;
int val;
dev_queue = netdev_get_tx_queue(dev, i);
q = dev_queue->qdisc_sleeping;
if (q->flags & TCQ_F_NOLOCK) {
val = test_bit(__QDISC_STATE_SCHED, &q->state);
} else {
root_lock = qdisc_lock(q);
spin_lock_bh(root_lock);
val = (qdisc_is_running(q) ||
test_bit(__QDISC_STATE_SCHED, &q->state));
spin_unlock_bh(root_lock);
}
if (val)
return true;
}
return false;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 107 | 79.26% | 7 | 70.00% |
| John Fastabend | 25 | 18.52% | 1 | 10.00% |
| Herbert Xu | 2 | 1.48% | 1 | 10.00% |
| Eric Dumazet | 1 | 0.74% | 1 | 10.00% |
| Total | 135 | 100.00% | 10 | 100.00% |
static void dev_qdisc_reset(struct net_device *dev,
struct netdev_queue *dev_queue,
void *none)
{
struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
if (qdisc)
qdisc_reset(qdisc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 38 | 100.00% | 1 | 100.00% |
| Total | 38 | 100.00% | 1 | 100.00% |
/**
* dev_deactivate_many - deactivate transmissions on several devices
* @head: list of devices to deactivate
*
* This function returns only when all outstanding transmissions
* have completed, unless all devices are in dismantle phase.
*/
void dev_deactivate_many(struct list_head *head)
{
struct net_device *dev;
list_for_each_entry(dev, head, close_list) {
netdev_for_each_tx_queue(dev, dev_deactivate_queue,
&noop_qdisc);
if (dev_ingress_queue(dev))
dev_deactivate_queue(dev, dev_ingress_queue(dev),
&noop_qdisc);
dev_watchdog_down(dev);
}
/* Wait for outstanding qdisc-less dev_queue_xmit calls.
* This is avoided if all devices are in dismantle phase :
* Caller will call synchronize_net() for us
*/
synchronize_net();
/* Wait for outstanding qdisc_run calls. */
list_for_each_entry(dev, head, close_list) {
while (some_qdisc_is_busy(dev))
yield();
/* The new qdisc is assigned at this point so we can safely
* unwind stale skb lists and qdisc statistics
*/
netdev_for_each_tx_queue(dev, dev_qdisc_reset, NULL);
if (dev_ingress_queue(dev))
dev_qdisc_reset(dev, dev_ingress_queue(dev), NULL);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 31 | 27.19% | 1 | 6.67% |
| David S. Miller | 25 | 21.93% | 4 | 26.67% |
| Octavian Purdila | 23 | 20.18% | 1 | 6.67% |
| Linus Torvalds (pre-git) | 17 | 14.91% | 4 | 26.67% |
| Eric Dumazet | 12 | 10.53% | 2 | 13.33% |
| Herbert Xu | 3 | 2.63% | 1 | 6.67% |
| Eric W. Biedermann | 2 | 1.75% | 1 | 6.67% |
| Linus Torvalds | 1 | 0.88% | 1 | 6.67% |
| Total | 114 | 100.00% | 15 | 100.00% |
void dev_deactivate(struct net_device *dev)
{
LIST_HEAD(single);
list_add(&dev->close_list, &single);
dev_deactivate_many(&single);
list_del(&single);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Octavian Purdila | 31 | 81.58% | 1 | 33.33% |
| Eric W. Biedermann | 7 | 18.42% | 2 | 66.67% |
| Total | 38 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(dev_deactivate);
static int qdisc_change_tx_queue_len(struct net_device *dev,
struct netdev_queue *dev_queue)
{
struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
const struct Qdisc_ops *ops = qdisc->ops;
if (ops->change_tx_queue_len)
return ops->change_tx_queue_len(qdisc, dev->tx_queue_len);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Américo Wang | 56 | 100.00% | 1 | 100.00% |
| Total | 56 | 100.00% | 1 | 100.00% |
int dev_qdisc_change_tx_queue_len(struct net_device *dev)
{
bool up = dev->flags & IFF_UP;
unsigned int i;
int ret = 0;
if (up)
dev_deactivate(dev);
for (i = 0; i < dev->num_tx_queues; i++) {
ret = qdisc_change_tx_queue_len(dev, &dev->_tx[i]);
/* TODO: revert changes on a partial failure */
if (ret)
break;
}
if (up)
dev_activate(dev);
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Américo Wang | 87 | 100.00% | 1 | 100.00% |
| Total | 87 | 100.00% | 1 | 100.00% |
static void dev_init_scheduler_queue(struct net_device *dev,
struct netdev_queue *dev_queue,
void *_qdisc)
{
struct Qdisc *qdisc = _qdisc;
rcu_assign_pointer(dev_queue->qdisc, qdisc);
dev_queue->qdisc_sleeping = qdisc;
__skb_queue_head_init(&qdisc->gso_skb);
__skb_queue_head_init(&qdisc->skb_bad_txq);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 38 | 65.52% | 2 | 40.00% |
| John Fastabend | 20 | 34.48% | 3 | 60.00% |
| Total | 58 | 100.00% | 5 | 100.00% |
void dev_init_scheduler(struct net_device *dev)
{
dev->qdisc = &noop_qdisc;
netdev_for_each_tx_queue(dev, dev_init_scheduler_queue, &noop_qdisc);
if (dev_ingress_queue(dev))
dev_init_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
timer_setup(&dev->watchdog_timer, dev_watchdog, 0);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Linus Torvalds (pre-git) | 19 | 32.20% | 4 | 33.33% |
| David S. Miller | 12 | 20.34% | 3 | 25.00% |
| Eric Dumazet | 10 | 16.95% | 1 | 8.33% |
| Patrick McHardy | 9 | 15.25% | 2 | 16.67% |
| Pavel Emelyanov | 7 | 11.86% | 1 | 8.33% |
| Kees Cook | 2 | 3.39% | 1 | 8.33% |
| Total | 59 | 100.00% | 12 | 100.00% |
static void shutdown_scheduler_queue(struct net_device *dev,
struct netdev_queue *dev_queue,
void *_qdisc_default)
{
struct Qdisc *qdisc = dev_queue->qdisc_sleeping;
struct Qdisc *qdisc_default = _qdisc_default;
if (qdisc) {
rcu_assign_pointer(dev_queue->qdisc, qdisc_default);
dev_queue->qdisc_sleeping = qdisc_default;
qdisc_destroy(qdisc);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 32 | 51.61% | 2 | 33.33% |
| Linus Torvalds (pre-git) | 26 | 41.94% | 3 | 50.00% |
| Jarek Poplawski | 4 | 6.45% | 1 | 16.67% |
| Total | 62 | 100.00% | 6 | 100.00% |
void dev_shutdown(struct net_device *dev)
{
netdev_for_each_tx_queue(dev, shutdown_scheduler_queue, &noop_qdisc);
if (dev_ingress_queue(dev))
shutdown_scheduler_queue(dev, dev_ingress_queue(dev), &noop_qdisc);
qdisc_destroy(dev->qdisc);
dev->qdisc = &noop_qdisc;
WARN_ON(timer_pending(&dev->watchdog_timer));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| David S. Miller | 23 | 35.38% | 3 | 25.00% |
| Linus Torvalds (pre-git) | 17 | 26.15% | 6 | 50.00% |
| Patrick McHardy | 14 | 21.54% | 1 | 8.33% |
| Eric Dumazet | 10 | 15.38% | 1 | 8.33% |
| Ilpo Järvinen | 1 | 1.54% | 1 | 8.33% |
| Total | 65 | 100.00% | 12 | 100.00% |
void psched_ratecfg_precompute(struct psched_ratecfg *r,
const struct tc_ratespec *conf,
u64 rate64)
{
memset(r, 0, sizeof(*r));
r->overhead = conf->overhead;
r->rate_bytes_ps = max_t(u64, conf->rate, rate64);
r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK);
r->mult = 1;
/*
* The deal here is to replace a divide by a reciprocal one
* in fast path (a reciprocal divide is a multiply and a shift)
*
* Normal formula would be :
* time_in_ns = (NSEC_PER_SEC * len) / rate_bps
*
* We compute mult/shift to use instead :
* time_in_ns = (len * mult) >> shift;
*
* We try to get the highest possible mult value for accuracy,
* but have to make sure no overflows will ever happen.
*/
if (r->rate_bytes_ps > 0) {
u64 factor = NSEC_PER_SEC;
for (;;) {
r->mult = div64_u64(factor, r->rate_bytes_ps);
if (r->mult & (1U << 31) || factor & (1ULL << 63))
break;
factor <<= 1;
r->shift++;
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Eric Dumazet | 66 | 47.48% | 3 | 60.00% |
| Jiri Pirko | 61 | 43.88% | 1 | 20.00% |
| Jesper Dangaard Brouer | 12 | 8.63% | 1 | 20.00% |
| Total | 139 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(psched_ratecfg_precompute);
static void mini_qdisc_rcu_func(struct rcu_head *head)
{
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Jiri Pirko | 10 | 100.00% | 1 | 100.00% |
| Total | 10 | 100.00% | 1 | 100.00% |
void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp,
struct tcf_proto *tp_head)
{
struct mini_Qdisc *miniq_old = rtnl_dereference(*miniqp->p_miniq);
struct mini_Qdisc *miniq;
if (!tp_head) {
RCU_INIT_POINTER(*miniqp->p_miniq, NULL);
/* Wait for flying RCU callback before it is freed. */
rcu_barrier_bh();
return;
}
miniq = !miniq_old || miniq_old == &miniqp->miniq2 ?
&miniqp->miniq1 : &miniqp->miniq2;
/* We need to make sure that readers won't see the miniq
* we are about to modify. So wait until previous call_rcu_bh callback
* is done.
*/
rcu_barrier_bh();
miniq->filter_list = tp_head;
rcu_assign_pointer(*miniqp->p_miniq, miniq);
if (miniq_old)
/* This is counterpart of the rcu barriers above. We need to
* block potential new user of miniq_old until all readers
* are not seeing it.
*/
call_rcu_bh(&miniq_old->rcu, mini_qdisc_rcu_func);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Jiri Pirko | 107 | 95.54% | 1 | 50.00% |
| Américo Wang | 5 | 4.46% | 1 | 50.00% |
| Total | 112 | 100.00% | 2 | 100.00% |
EXPORT_SYMBOL(mini_qdisc_pair_swap);
void mini_qdisc_pair_init(struct mini_Qdisc_pair *miniqp, struct Qdisc *qdisc,
struct mini_Qdisc __rcu **p_miniq)
{
miniqp->miniq1.cpu_bstats = qdisc->cpu_bstats;
miniqp->miniq1.cpu_qstats = qdisc->cpu_qstats;
miniqp->miniq2.cpu_bstats = qdisc->cpu_bstats;
miniqp->miniq2.cpu_qstats = qdisc->cpu_qstats;
miniqp->p_miniq = p_miniq;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| Jiri Pirko | 68 | 100.00% | 1 | 100.00% |
| Total | 68 | 100.00% | 1 | 100.00% |
EXPORT_SYMBOL(mini_qdisc_pair_init);
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
| John Fastabend | 1262 | 21.61% | 13 | 6.44% |
| David S. Miller | 1012 | 17.33% | 31 | 15.35% |
| Eric Dumazet | 764 | 13.08% | 30 | 14.85% |
| Linus Torvalds (pre-git) | 643 | 11.01% | 15 | 7.43% |
| Américo Wang | 267 | 4.57% | 7 | 3.47% |
| Jiri Pirko | 264 | 4.52% | 2 | 0.99% |
| Krishna Kumar | 232 | 3.97% | 4 | 1.98% |
| Patrick McHardy | 218 | 3.73% | 9 | 4.46% |
| Jesper Dangaard Brouer | 134 | 2.29% | 5 | 2.48% |
| Jarek Poplawski | 114 | 1.95% | 9 | 4.46% |
| Jamal Hadi Salim | 97 | 1.66% | 4 | 1.98% |
| Stephen Hemminger | 89 | 1.52% | 9 | 4.46% |
| Thomas Graf | 88 | 1.51% | 6 | 2.97% |
| Denys Vlasenko | 67 | 1.15% | 1 | 0.50% |
| Steffen Klassert | 56 | 0.96% | 1 | 0.50% |
| Dave Jones | 55 | 0.94% | 1 | 0.50% |
| Octavian Purdila | 54 | 0.92% | 1 | 0.50% |
| Phil Sutter | 52 | 0.89% | 3 | 1.49% |
| Wei Yongjun | 44 | 0.75% | 1 | 0.50% |
| Alexander Aring | 44 | 0.75% | 3 | 1.49% |
| Herbert Xu | 40 | 0.69% | 9 | 4.46% |
| Florian Westphal | 40 | 0.69% | 4 | 1.98% |
| Nikolay Aleksandrov | 23 | 0.39% | 1 | 0.50% |
| Jiri Kosina | 21 | 0.36% | 2 | 0.99% |
| David Decotigny | 21 | 0.36% | 3 | 1.49% |
| Jesus Sanchez-Palencia | 19 | 0.33% | 1 | 0.50% |
| Chris Dion | 18 | 0.31% | 1 | 0.50% |
| Kees Cook | 14 | 0.24% | 1 | 0.50% |
| Lars Persson | 12 | 0.21% | 1 | 0.50% |
| Arjan van de Ven | 11 | 0.19% | 3 | 1.49% |
| Eric W. Biedermann | 9 | 0.15% | 2 | 0.99% |
| Peter P. Waskiewicz Jr | 7 | 0.12% | 1 | 0.50% |
| Jussi Kivilinna | 7 | 0.12% | 1 | 0.50% |
| Konstantin Khlebnikov | 7 | 0.12% | 1 | 0.50% |
| Pavel Emelyanov | 7 | 0.12% | 1 | 0.50% |
| Tom Herbert | 4 | 0.07% | 1 | 0.50% |
| Arthur Kepner | 3 | 0.05% | 1 | 0.50% |
| Venkatesh Pallipadi | 3 | 0.05% | 1 | 0.50% |
| Tejun Heo | 3 | 0.05% | 1 | 0.50% |
| Jeff Garzik | 2 | 0.03% | 1 | 0.50% |
| Daniel Borkmann | 2 | 0.03% | 1 | 0.50% |
| Elena Reshetova | 2 | 0.03% | 1 | 0.50% |
| Adrian Bunk | 1 | 0.02% | 1 | 0.50% |
| Ilpo Järvinen | 1 | 0.02% | 1 | 0.50% |
| Andi Kleen | 1 | 0.02% | 1 | 0.50% |
| Andrew Morton | 1 | 0.02% | 1 | 0.50% |
| Tommy S. Christensen | 1 | 0.02% | 1 | 0.50% |
| Linus Torvalds | 1 | 0.02% | 1 | 0.50% |
| Matthias Tafelmeier | 1 | 0.02% | 1 | 0.50% |
| Joe Perches | 1 | 0.02% | 1 | 0.50% |
| Total | 5839 | 100.00% | 202 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.