diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-09-03 00:39:16 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-03 20:02:17 -0700 |
commit | 1a123a3168566b10f87f228ae963770b26f27420 (patch) | |
tree | cebf893e0ae4de5ee5077b69002f41d8f61d45f9 /net | |
parent | 2c11455321f37da6fe6cc36353149f9ac9183334 (diff) | |
download | linux-3.10-1a123a3168566b10f87f228ae963770b26f27420.tar.gz linux-3.10-1a123a3168566b10f87f228ae963770b26f27420.tar.bz2 linux-3.10-1a123a3168566b10f87f228ae963770b26f27420.zip |
vlan: adds drops accounting
Its hard to tell if vlans are dropping frames, since
every frame given to vlan_???_start_xmit() functions
is accounted as fully transmitted by lower device.
We can test dev_queue_xmit() return values to
properly account for dropped frames.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/8021q/vlan_dev.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 3938c3e50fb..4198ec5c8ab 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c @@ -294,6 +294,8 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, int i = skb_get_queue_mapping(skb); struct netdev_queue *txq = netdev_get_tx_queue(dev, i); struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); + unsigned int len; + int ret; /* Handle non-VLAN frames if they are sent to us, for example by DHCP. * @@ -319,11 +321,17 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, vlan_dev_info(dev)->cnt_inc_headroom_on_tx++; } - txq->tx_packets++; - txq->tx_bytes += skb->len; skb->dev = vlan_dev_info(dev)->real_dev; - dev_queue_xmit(skb); + len = skb->len; + ret = dev_queue_xmit(skb); + + if (likely(ret == NET_XMIT_SUCCESS)) { + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; + return NETDEV_TX_OK; } @@ -333,16 +341,23 @@ static netdev_tx_t vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, int i = skb_get_queue_mapping(skb); struct netdev_queue *txq = netdev_get_tx_queue(dev, i); u16 vlan_tci; + unsigned int len; + int ret; vlan_tci = vlan_dev_info(dev)->vlan_id; vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); skb = __vlan_hwaccel_put_tag(skb, vlan_tci); - txq->tx_packets++; - txq->tx_bytes += skb->len; - skb->dev = vlan_dev_info(dev)->real_dev; - dev_queue_xmit(skb); + len = skb->len; + ret = dev_queue_xmit(skb); + + if (likely(ret == NET_XMIT_SUCCESS)) { + txq->tx_packets++; + txq->tx_bytes += len; + } else + txq->tx_dropped++; + return NETDEV_TX_OK; } |