Release 4.7 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 <net/sch_generic.h>
#include <net/pkt_sched.h>
#include <net/dst.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 int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
{
q->gso_skb = skb;
q->qstats.requeues++;
qdisc_qstats_backlog_inc(q, skb);
q->q.qlen++; /* it's still part of the queue */
__netif_schedule(q);
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 19 | 35.85% | 1 | 11.11% |
jarek poplawski | jarek poplawski | 13 | 24.53% | 2 | 22.22% |
krishna kumar | krishna kumar | 9 | 16.98% | 2 | 22.22% |
americo wang | americo wang | 7 | 13.21% | 1 | 11.11% |
pre-git | pre-git | 2 | 3.77% | 1 | 11.11% |
david s. miller | david s. miller | 2 | 3.77% | 1 | 11.11% |
andi kleen | andi kleen | 1 | 1.89% | 1 | 11.11% |
| Total | 53 | 100.00% | 9 | 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 | jesper dangaard brouer | 62 | 65.96% | 3 | 75.00% |
eric dumazet | eric dumazet | 32 | 34.04% | 1 | 25.00% |
| Total | 94 | 100.00% | 4 | 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)
{
struct sk_buff *skb = q->gso_skb;
const struct netdev_queue *txq = q->dev_queue;
*packets = 1;
*validate = true;
if (unlikely(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)) {
q->gso_skb = NULL;
qdisc_qstats_backlog_dec(q, skb);
q->q.qlen--;
} else
skb = NULL;
/* skb in gso_skb were already validated */
*validate = false;
} else {
if (!(q->flags & TCQ_F_ONETXQUEUE) ||
!netif_xmit_frozen_or_stopped(txq)) {
skb = q->dequeue(q);
if (skb && qdisc_may_bulk(q))
try_bulk_dequeue_skb(q, skb, txq, packets);
}
}
return skb;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
eric dumazet | eric dumazet | 45 | 27.11% | 2 | 14.29% |
jarek poplawski | jarek poplawski | 39 | 23.49% | 2 | 14.29% |
jamal hadi salim | jamal hadi salim | 29 | 17.47% | 1 | 7.14% |
jesper dangaard brouer | jesper dangaard brouer | 26 | 15.66% | 2 | 14.29% |
krishna kumar | krishna kumar | 9 | 5.42% | 1 | 7.14% |
david s. miller | david s. miller | 9 | 5.42% | 3 | 21.43% |
americo wang | americo wang | 7 | 4.22% | 1 | 7.14% |
daniel borkmann | daniel borkmann | 1 | 0.60% | 1 | 7.14% |
tom herbert | tom herbert | 1 | 0.60% | 1 | 7.14% |
| Total | 166 | 100.00% | 14 | 100.00% |
/*
* Transmit possibly several skbs, and handle the return status as
* required. Holding the __QDISC___STATE_RUNNING bit guarantees that
* only one CPU can execute this function.
*
* Returns to the caller:
* 0 - queue is empty or throttled.
* >0 - queue is not empty.
*/
int 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;
/* And release qdisc */
spin_unlock(root_lock);
/* Note that we validate skb (GSO, checksum, ...) outside of locks */
if (validate)
skb = validate_xmit_skb_list(skb, dev);
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 {
spin_lock(root_lock);
return qdisc_qlen(q);
}
spin_lock(root_lock);
if (dev_xmit_complete(ret)) {
/* Driver sent out skb successfully or skb was consumed */
ret = qdisc_qlen(q);
} else {
/* 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);
ret = dev_requeue_skb(skb, q);
}
if (ret && netif_xmit_frozen_or_stopped(txq))
ret = 0;
return ret;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jamal hadi salim | jamal hadi salim | 45 | 22.96% | 2 | 8.00% |
krishna kumar | krishna kumar | 31 | 15.82% | 2 | 8.00% |
david s. miller | david s. miller | 31 | 15.82% | 6 | 24.00% |
eric dumazet | eric dumazet | 23 | 11.73% | 1 | 4.00% |
lars persson | lars persson | 17 | 8.67% | 1 | 4.00% |
pre-git | pre-git | 16 | 8.16% | 4 | 16.00% |
jarek poplawski | jarek poplawski | 8 | 4.08% | 1 | 4.00% |
stephen hemminger | stephen hemminger | 8 | 4.08% | 1 | 4.00% |
peter p waskiewicz | peter p waskiewicz | 7 | 3.57% | 1 | 4.00% |
herbert xu | herbert xu | 5 | 2.55% | 3 | 12.00% |
thomas graf | thomas graf | 2 | 1.02% | 1 | 4.00% |
tom herbert | tom herbert | 2 | 1.02% | 1 | 4.00% |
joe perches | joe perches | 1 | 0.51% | 1 | 4.00% |
| Total | 196 | 100.00% | 25 | 100.00% |
/*
* NOTE: Called under qdisc_lock(q) with locally disabled BH.
*
* __QDISC___STATE_RUNNING 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 int qdisc_restart(struct Qdisc *q, int *packets)
{
struct netdev_queue *txq;
struct net_device *dev;
spinlock_t *root_lock;
struct sk_buff *skb;
bool validate;
/* Dequeue packet */
skb = dequeue_skb(q, &validate, packets);
if (unlikely(!skb))
return 0;
root_lock = qdisc_lock(q);
dev = qdisc_dev(q);
txq = skb_get_tx_queue(dev, skb);
return sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
krishna kumar | krishna kumar | 86 | 85.15% | 1 | 25.00% |
eric dumazet | eric dumazet | 8 | 7.92% | 1 | 25.00% |
jesper dangaard brouer | jesper dangaard brouer | 6 | 5.94% | 1 | 25.00% |
daniel borkmann | daniel borkmann | 1 | 0.99% | 1 | 25.00% |
| Total | 101 | 100.00% | 4 | 100.00% |
void __qdisc_run(struct Qdisc *q)
{
int quota = weight_p;
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;
}
}
qdisc_run_end(q);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
herbert xu | herbert xu | 31 | 54.39% | 3 | 33.33% |
jesper dangaard brouer | jesper dangaard brouer | 10 | 17.54% | 1 | 11.11% |
jamal hadi salim | jamal hadi salim | 7 | 12.28% | 1 | 11.11% |
david s. miller | david s. miller | 6 | 10.53% | 2 | 22.22% |
krishna kumar | krishna kumar | 2 | 3.51% | 1 | 11.11% |
eric dumazet | eric dumazet | 1 | 1.75% | 1 | 11.11% |
| Total | 57 | 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);
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 | eric dumazet | 66 | 71.74% | 1 | 33.33% |
nikolay aleksandrov | nikolay aleksandrov | 20 | 21.74% | 1 | 33.33% |
florian westphal | florian westphal | 6 | 6.52% | 1 | 33.33% |
| Total | 92 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(dev_trans_start);
static void dev_watchdog(unsigned long arg)
{
struct net_device *dev = (struct net_device *)arg;
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 |
pre-git | pre-git | 108 | 52.17% | 6 | 37.50% |
david s. miller | david s. miller | 46 | 22.22% | 1 | 6.25% |
eric dumazet | eric dumazet | 26 | 12.56% | 1 | 6.25% |
arjan van de ven | arjan van de ven | 11 | 5.31% | 3 | 18.75% |
stephen hemminger | stephen hemminger | 8 | 3.86% | 2 | 12.50% |
david decotigny | david decotigny | 5 | 2.42% | 1 | 6.25% |
herbert xu | herbert xu | 2 | 0.97% | 1 | 6.25% |
tom herbert | tom herbert | 1 | 0.48% | 1 | 6.25% |
| Total | 207 | 100.00% | 16 | 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 |
pre-git | pre-git | 55 | 90.16% | 7 | 77.78% |
stephen hemminger | stephen hemminger | 3 | 4.92% | 1 | 11.11% |
venkatesh pallipadi | venkatesh pallipadi | 3 | 4.92% | 1 | 11.11% |
| Total | 61 | 100.00% | 9 | 100.00% |
static void dev_watchdog_up(struct net_device *dev)
{
__netdev_watchdog_up(dev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 16 | 100.00% | 5 | 100.00% |
| Total | 16 | 100.00% | 5 | 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 |
pre-git | pre-git | 33 | 91.67% | 5 | 71.43% |
herbert xu | herbert xu | 2 | 5.56% | 1 | 14.29% |
stephen hemminger | 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_changes);
linkwatch_fire_event(dev);
if (netif_running(dev))
__netdev_watchdog_up(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
denys vlasenko | denys vlasenko | 39 | 67.24% | 1 | 25.00% |
david s. miller | david s. miller | 9 | 15.52% | 1 | 25.00% |
david decotigny | david decotigny | 8 | 13.79% | 1 | 25.00% |
jeff garzik | jeff garzik | 2 | 3.45% | 1 | 25.00% |
| Total | 58 | 100.00% | 4 | 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_changes);
linkwatch_fire_event(dev);
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
denys vlasenko | denys vlasenko | 28 | 59.57% | 1 | 33.33% |
david s. miller | david s. miller | 11 | 23.40% | 1 | 33.33% |
david decotigny | david decotigny | 8 | 17.02% | 1 | 33.33% |
| Total | 47 | 100.00% | 3 | 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)
{
kfree_skb(skb);
return NET_XMIT_CN;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 24 | 100.00% | 2 | 100.00% |
| Total | 24 | 100.00% | 2 | 100.00% |
static struct sk_buff *noop_dequeue(struct Qdisc *qdisc)
{
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | 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,
.list = LIST_HEAD_INIT(noop_qdisc.list),
.q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
.dev_queue = &noop_netdev_queue,
.busylock = __SPIN_LOCK_UNLOCKED(noop_qdisc.busylock),
};
EXPORT_SYMBOL(noop_qdisc);
static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt)
{
/* 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 | phil sutter | 26 | 100.00% | 1 | 100.00% |
| Total | 26 | 100.00% | 1 | 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:
* - queues for the three band
* - bitmap indicating which of the bands contain skbs
*/
struct pfifo_fast_priv {
u32 bitmap;
struct sk_buff_head q[PFIFO_FAST_BANDS];
};
/*
* Convert a bitmap to the first band number where an skb is queued, where:
* bitmap=0 means there are no skbs on any band.
* bitmap=1 means there is an skb on band 0.
* bitmap=7 means there are skbs on all 3 bands, etc.
*/
static const int bitmap2band[] = {-1, 0, 1, 0, 2, 0, 1, 0};
static inline struct sk_buff_head *band2list(struct pfifo_fast_priv *priv,
int band)
{
return priv->q + band;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
krishna kumar | krishna kumar | 9 | 37.50% | 1 | 25.00% |
david s. miller | david s. miller | 8 | 33.33% | 2 | 50.00% |
thomas graf | thomas graf | 7 | 29.17% | 1 | 25.00% |
| Total | 24 | 100.00% | 4 | 100.00% |
static int pfifo_fast_enqueue(struct sk_buff *skb, struct Qdisc *qdisc)
{
if (skb_queue_len(&qdisc->q) < qdisc_dev(qdisc)->tx_queue_len) {
int band = prio2band[skb->priority & TC_PRIO_MAX];
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
struct sk_buff_head *list = band2list(priv, band);
priv->bitmap |= (1 << band);
qdisc->q.qlen++;
return __qdisc_enqueue_tail(skb, qdisc, list);
}
return qdisc_drop(skb, qdisc);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
krishna kumar | krishna kumar | 53 | 50.96% | 2 | 28.57% |
david s. miller | david s. miller | 31 | 29.81% | 1 | 14.29% |
thomas graf | thomas graf | 12 | 11.54% | 2 | 28.57% |
pre-git | pre-git | 6 | 5.77% | 1 | 14.29% |
jamal hadi salim | jamal hadi salim | 2 | 1.92% | 1 | 14.29% |
| Total | 104 | 100.00% | 7 | 100.00% |
static struct sk_buff *pfifo_fast_dequeue(struct Qdisc *qdisc)
{
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
int band = bitmap2band[priv->bitmap];
if (likely(band >= 0)) {
struct sk_buff_head *list = band2list(priv, band);
struct sk_buff *skb = __qdisc_dequeue_head(qdisc, list);
qdisc->q.qlen--;
if (skb_queue_empty(list))
priv->bitmap &= ~(1 << band);
return skb;
}
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
krishna kumar | krishna kumar | 57 | 57.58% | 1 | 25.00% |
pre-git | pre-git | 24 | 24.24% | 1 | 25.00% |
david s. miller | david s. miller | 13 | 13.13% | 1 | 25.00% |
thomas graf | thomas graf | 5 | 5.05% | 1 | 25.00% |
| Total | 99 | 100.00% | 4 | 100.00% |
static struct sk_buff *pfifo_fast_peek(struct Qdisc *qdisc)
{
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
int band = bitmap2band[priv->bitmap];
if (band >= 0) {
struct sk_buff_head *list = band2list(priv, band);
return skb_peek(list);
}
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
jarek poplawski | jarek poplawski | 35 | 56.45% | 1 | 50.00% |
krishna kumar | krishna kumar | 27 | 43.55% | 1 | 50.00% |
| Total | 62 | 100.00% | 2 | 100.00% |
static void pfifo_fast_reset(struct Qdisc *qdisc)
{
int prio;
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
__qdisc_reset_queue(qdisc, band2list(priv, prio));
priv->bitmap = 0;
qdisc->qstats.backlog = 0;
qdisc->q.qlen = 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david s. miller | david s. miller | 35 | 49.30% | 1 | 16.67% |
pre-git | pre-git | 14 | 19.72% | 3 | 50.00% |
krishna kumar | krishna kumar | 13 | 18.31% | 1 | 16.67% |
thomas graf | thomas graf | 9 | 12.68% | 1 | 16.67% |
| Total | 71 | 100.00% | 6 | 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 | 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)
{
int prio;
struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
__skb_queue_head_init(band2list(priv, prio));
/* Can by-pass the queue discipline */
qdisc->flags |= TCQ_F_CAN_BYPASS;
return 0;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david s. miller | david s. miller | 46 | 74.19% | 1 | 20.00% |
eric dumazet | eric dumazet | 8 | 12.90% | 2 | 40.00% |
krishna kumar | krishna kumar | 7 | 11.29% | 1 | 20.00% |
pre-git | pre-git | 1 | 1.61% | 1 | 20.00% |
| Total | 62 | 100.00% | 5 | 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,
.reset = pfifo_fast_reset,
.dump = pfifo_fast_dump,
.owner = THIS_MODULE,
};
EXPORT_SYMBOL(pfifo_fast_ops);
static struct lock_class_key qdisc_tx_busylock;
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops)
{
void *p;
struct Qdisc *sch;
unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size;
int err = -ENOBUFS;
struct net_device *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;
}
INIT_LIST_HEAD(&sch->list);
skb_queue_head_init(&sch->q);
spin_lock_init(&sch->busylock);
lockdep_set_class(&sch->busylock,
dev->qdisc_tx_busylock ?: &qdisc_tx_busylock);
sch->ops = ops;
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev_queue = dev_queue;
dev_hold(dev);
atomic_set(&sch->refcnt, 1);
return sch;
errout:
return ERR_PTR(err);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
eric dumazet | eric dumazet | 100 | 38.02% | 4 | 30.77% |
pre-git | pre-git | 72 | 27.38% | 3 | 23.08% |
stephen hemminger | stephen hemminger | 40 | 15.21% | 2 | 15.38% |
thomas graf | thomas graf | 30 | 11.41% | 1 | 7.69% |
patrick mchardy | patrick mchardy | 12 | 4.56% | 2 | 15.38% |
david s. miller | david s. miller | 9 | 3.42% | 1 | 7.69% |
| Total | 263 | 100.00% | 13 | 100.00% |
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
unsigned int parentid)
{
struct Qdisc *sch;
if (!try_module_get(ops->owner))
goto errout;
sch = qdisc_alloc(dev_queue, ops);
if (IS_ERR(sch))
goto errout;
sch->parent = parentid;
if (!ops->init || ops->init(sch, NULL) == 0)
return sch;
qdisc_destroy(sch);
errout:
return NULL;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
thomas graf | thomas graf | 40 | 41.67% | 2 | 22.22% |
pre-git | pre-git | 25 | 26.04% | 3 | 33.33% |
stephen hemminger | stephen hemminger | 14 | 14.58% | 2 | 22.22% |
patrick mchardy | patrick mchardy | 10 | 10.42% | 1 | 11.11% |
david s. miller | david s. miller | 7 | 7.29% | 1 | 11.11% |
| Total | 96 | 100.00% | 9 | 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;
if (ops->reset)
ops->reset(qdisc);
if (qdisc->gso_skb) {
kfree_skb_list(qdisc->gso_skb);
qdisc->gso_skb = NULL;
qdisc->q.qlen = 0;
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 32 | 51.61% | 1 | 20.00% |
krishna kumar | krishna kumar | 16 | 25.81% | 1 | 20.00% |
jarek poplawski | jarek poplawski | 12 | 19.35% | 1 | 20.00% |
jesper dangaard brouer | jesper dangaard brouer | 1 | 1.61% | 1 | 20.00% |
eric dumazet | eric dumazet | 1 | 1.61% | 1 | 20.00% |
| Total | 62 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(qdisc_reset);
static void qdisc_rcu_free(struct rcu_head *head)
{
struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
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 |
eric dumazet | eric dumazet | 39 | 62.90% | 1 | 33.33% |
john fastabend | john fastabend | 23 | 37.10% | 2 | 66.67% |
| Total | 62 | 100.00% | 3 | 100.00% |
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);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
patrick mchardy | patrick mchardy | 60 | 46.15% | 2 | 13.33% |
david s. miller | david s. miller | 36 | 27.69% | 4 | 26.67% |
jarek poplawski | jarek poplawski | 10 | 7.69% | 2 | 13.33% |
eric dumazet | eric dumazet | 10 | 7.69% | 3 | 20.00% |
jussi kivilinna | jussi kivilinna | 7 | 5.38% | 1 | 6.67% |
pre-git | pre-git | 5 | 3.85% | 1 | 6.67% |
jesper dangaard brouer | jesper dangaard brouer | 1 | 0.77% | 1 | 6.67% |
andrew morton | andrew morton | 1 | 0.77% | 1 | 6.67% |
| Total | 130 | 100.00% | 15 | 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);
/* 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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
patrick mchardy | patrick mchardy | 98 | 100.00% | 1 | 100.00% |
| Total | 98 | 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);
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 |
pre-git | pre-git | 32 | 34.04% | 3 | 27.27% |
david s. miller | david s. miller | 22 | 23.40% | 2 | 18.18% |
eric dumazet | eric dumazet | 20 | 21.28% | 3 | 27.27% |
phil sutter | phil sutter | 18 | 19.15% | 2 | 18.18% |
patrick mchardy | patrick mchardy | 2 | 2.13% | 1 | 9.09% |
| Total | 94 | 100.00% | 11 | 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;
atomic_inc(&dev->qdisc->refcnt);
} else {
qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
if (qdisc) {
dev->qdisc = qdisc;
qdisc->ops->attach(qdisc);
}
}
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david s. miller | david s. miller | 100 | 91.74% | 1 | 33.33% |
eric dumazet | eric dumazet | 6 | 5.50% | 1 | 33.33% |
phil sutter | phil sutter | 3 | 2.75% | 1 | 33.33% |
| Total | 109 | 100.00% | 3 | 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 | david s. miller | 63 | 76.83% | 4 | 50.00% |
eric dumazet | eric dumazet | 8 | 9.76% | 1 | 12.50% |
patrick mchardy | patrick mchardy | 7 | 8.54% | 1 | 12.50% |
pre-git | pre-git | 3 | 3.66% | 1 | 12.50% |
tommy s. christensen | 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 | david s. miller | 58 | 66.67% | 3 | 33.33% |
eric dumazet | eric dumazet | 10 | 11.49% | 1 | 11.11% |
pre-git | pre-git | 10 | 11.49% | 2 | 22.22% |
patrick mchardy | patrick mchardy | 5 | 5.75% | 1 | 11.11% |
florian westphal | florian westphal | 3 | 3.45% | 1 | 11.11% |
stephen hemminger | 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 | david s. miller | 87 | 88.78% | 6 | 66.67% |
pre-git | pre-git | 4 | 4.08% | 1 | 11.11% |
jarek poplawski | jarek poplawski | 4 | 4.08% | 1 | 11.11% |
john fastabend | 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;
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 | david s. miller | 107 | 97.27% | 7 | 77.78% |
herbert xu | herbert xu | 2 | 1.82% | 1 | 11.11% |
eric dumazet | eric dumazet | 1 | 0.91% | 1 | 11.11% |
| Total | 110 | 100.00% | 9 | 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;
bool sync_needed = false;
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);
sync_needed |= !dev->dismantle;
}
/* 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
*/
if (sync_needed)
synchronize_net();
/* Wait for outstanding qdisc_run calls. */
list_for_each_entry(dev, head, close_list)
while (some_qdisc_is_busy(dev))
yield();
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
eric dumazet | eric dumazet | 28 | 28.28% | 2 | 14.29% |
david s. miller | david s. miller | 25 | 25.25% | 4 | 28.57% |
octavian purdila | octavian purdila | 23 | 23.23% | 1 | 7.14% |
pre-git | pre-git | 17 | 17.17% | 4 | 28.57% |
herbert xu | herbert xu | 3 | 3.03% | 1 | 7.14% |
eric w. biederman | eric w. biederman | 2 | 2.02% | 1 | 7.14% |
linus torvalds | linus torvalds | 1 | 1.01% | 1 | 7.14% |
| Total | 99 | 100.00% | 14 | 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 | octavian purdila | 31 | 81.58% | 1 | 33.33% |
eric w. biederman | eric w. biederman | 7 | 18.42% | 2 | 66.67% |
| Total | 38 | 100.00% | 3 | 100.00% |
EXPORT_SYMBOL(dev_deactivate);
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;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david s. miller | david s. miller | 38 | 90.48% | 2 | 66.67% |
john fastabend | john fastabend | 4 | 9.52% | 1 | 33.33% |
| Total | 42 | 100.00% | 3 | 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);
setup_timer(&dev->watchdog_timer, dev_watchdog, (unsigned long)dev);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
pre-git | pre-git | 20 | 31.75% | 4 | 36.36% |
david s. miller | david s. miller | 12 | 19.05% | 3 | 27.27% |
pavel emelianov | pavel emelianov | 12 | 19.05% | 1 | 9.09% |
eric dumazet | eric dumazet | 10 | 15.87% | 1 | 9.09% |
patrick mchardy | patrick mchardy | 9 | 14.29% | 2 | 18.18% |
| Total | 63 | 100.00% | 11 | 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 | david s. miller | 32 | 51.61% | 2 | 33.33% |
pre-git | pre-git | 26 | 41.94% | 3 | 50.00% |
jarek poplawski | 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 | david s. miller | 23 | 35.38% | 3 | 25.00% |
pre-git | pre-git | 17 | 26.15% | 6 | 50.00% |
patrick mchardy | patrick mchardy | 14 | 21.54% | 1 | 8.33% |
eric dumazet | eric dumazet | 10 | 15.38% | 1 | 8.33% |
ilpo jarvinen | ilpo jarvinen | 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 | eric dumazet | 66 | 47.48% | 3 | 60.00% |
jiri pirko | jiri pirko | 61 | 43.88% | 1 | 20.00% |
jesper dangaard brouer | jesper dangaard brouer | 12 | 8.63% | 1 | 20.00% |
| Total | 139 | 100.00% | 5 | 100.00% |
EXPORT_SYMBOL(psched_ratecfg_precompute);
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
david s. miller | david s. miller | 1051 | 26.27% | 31 | 18.45% |
pre-git | pre-git | 666 | 16.65% | 15 | 8.93% |
eric dumazet | eric dumazet | 550 | 13.75% | 24 | 14.29% |
krishna kumar | krishna kumar | 362 | 9.05% | 5 | 2.98% |
patrick mchardy | patrick mchardy | 251 | 6.27% | 9 | 5.36% |
jarek poplawski | jarek poplawski | 146 | 3.65% | 9 | 5.36% |
jesper dangaard brouer | jesper dangaard brouer | 120 | 3.00% | 6 | 3.57% |
thomas graf | thomas graf | 116 | 2.90% | 7 | 4.17% |
jamal hadi salim | jamal hadi salim | 105 | 2.62% | 4 | 2.38% |
stephen hemminger | stephen hemminger | 92 | 2.30% | 9 | 5.36% |
jiri pirko | jiri pirko | 69 | 1.72% | 1 | 0.60% |
denys vlasenko | denys vlasenko | 67 | 1.67% | 1 | 0.60% |
dave jones | dave jones | 55 | 1.37% | 1 | 0.60% |
octavian purdila | octavian purdila | 54 | 1.35% | 1 | 0.60% |
phil sutter | phil sutter | 52 | 1.30% | 3 | 1.79% |
john fastabend | john fastabend | 45 | 1.12% | 4 | 2.38% |
herbert xu | herbert xu | 45 | 1.12% | 9 | 5.36% |
nikolay aleksandrov | nikolay aleksandrov | 23 | 0.57% | 1 | 0.60% |
david decotigny | david decotigny | 21 | 0.52% | 2 | 1.19% |
lars persson | lars persson | 17 | 0.42% | 1 | 0.60% |
americo wang | americo wang | 14 | 0.35% | 1 | 0.60% |
pavel emelianov | pavel emelianov | 12 | 0.30% | 1 | 0.60% |
arjan van de ven | arjan van de ven | 11 | 0.27% | 3 | 1.79% |
eric w. biederman | eric w. biederman | 9 | 0.22% | 2 | 1.19% |
florian westphal | florian westphal | 9 | 0.22% | 2 | 1.19% |
jussi kivilinna | jussi kivilinna | 7 | 0.17% | 1 | 0.60% |
peter p waskiewicz | peter p waskiewicz | 7 | 0.17% | 1 | 0.60% |
tom herbert | tom herbert | 4 | 0.10% | 1 | 0.60% |
venkatesh pallipadi | venkatesh pallipadi | 3 | 0.07% | 1 | 0.60% |
arthur kepner | arthur kepner | 3 | 0.07% | 1 | 0.60% |
tejun heo | tejun heo | 3 | 0.07% | 1 | 0.60% |
jeff garzik | jeff garzik | 2 | 0.05% | 1 | 0.60% |
daniel borkmann | daniel borkmann | 2 | 0.05% | 1 | 0.60% |
adrian bunk | adrian bunk | 1 | 0.02% | 1 | 0.60% |
andrew morton | andrew morton | 1 | 0.02% | 1 | 0.60% |
linus torvalds | linus torvalds | 1 | 0.02% | 1 | 0.60% |
tommy s. christensen | tommy s. christensen | 1 | 0.02% | 1 | 0.60% |
joe perches | joe perches | 1 | 0.02% | 1 | 0.60% |
ilpo jarvinen | ilpo jarvinen | 1 | 0.02% | 1 | 0.60% |
andi kleen | andi kleen | 1 | 0.02% | 1 | 0.60% |
ying xue | ying xue | 1 | 0.02% | 1 | 0.60% |
| Total | 4001 | 100.00% | 168 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.