diff options
author | Zoltan Kiss <zoltan.kiss@citrix.com> | 2014-03-06 22:48:28 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-07 21:56:35 +0100 |
commit | 1bb332af4cd889e4b64dacbf4a793ceb3a70445d (patch) | |
tree | 1aef36c3aa0f6366562e169fbfe7589190d9387e | |
parent | xen-netback: Remove old TX grant copy definitons and fix indentations (diff) | |
download | linux-1bb332af4cd889e4b64dacbf4a793ceb3a70445d.tar.xz linux-1bb332af4cd889e4b64dacbf4a793ceb3a70445d.zip |
xen-netback: Add stat counters for zerocopy
These counters help determine how often the buffers had to be copied. Also
they help find out if packets are leaked, as if "sent != success + fail",
there are probably packets never freed up properly.
NOTE: if bisect brought you here, you should apply the series up until
"xen-netback: Timeout packets in RX path", otherwise Windows guests can't work
properly and malicious guests can block other guests by not releasing their sent
packets.
Signed-off-by: Zoltan Kiss <zoltan.kiss@citrix.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/xen-netback/common.h | 3 | ||||
-rw-r--r-- | drivers/net/xen-netback/interface.c | 15 | ||||
-rw-r--r-- | drivers/net/xen-netback/netback.c | 9 |
3 files changed, 26 insertions, 1 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h index 49109afa2253..683d30160a7c 100644 --- a/drivers/net/xen-netback/common.h +++ b/drivers/net/xen-netback/common.h @@ -179,6 +179,9 @@ struct xenvif { /* Statistics */ unsigned long rx_gso_checksum_fixup; + unsigned long tx_zerocopy_sent; + unsigned long tx_zerocopy_success; + unsigned long tx_zerocopy_fail; /* Miscellaneous private stuff. */ struct net_device *dev; diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 1fe9fe523cc8..44df8581b4d7 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c @@ -238,6 +238,21 @@ static const struct xenvif_stat { "rx_gso_checksum_fixup", offsetof(struct xenvif, rx_gso_checksum_fixup) }, + /* If (sent != success + fail), there are probably packets never + * freed up properly! + */ + { + "tx_zerocopy_sent", + offsetof(struct xenvif, tx_zerocopy_sent), + }, + { + "tx_zerocopy_success", + offsetof(struct xenvif, tx_zerocopy_success), + }, + { + "tx_zerocopy_fail", + offsetof(struct xenvif, tx_zerocopy_fail) + }, }; static int xenvif_get_sset_count(struct net_device *dev, int string_set) diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 46a75706cb78..3cb586357df7 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1323,8 +1323,10 @@ static int xenvif_tx_submit(struct xenvif *vif) * do a skb_copy_ubufs while we are still in control of the * skb. E.g. the __pskb_pull_tail earlier can do such thing. */ - if (skb_shinfo(skb)->destructor_arg) + if (skb_shinfo(skb)->destructor_arg) { skb_shinfo(skb)->tx_flags |= SKBTX_DEV_ZEROCOPY; + vif->tx_zerocopy_sent++; + } netif_receive_skb(skb); } @@ -1364,6 +1366,11 @@ void xenvif_zerocopy_callback(struct ubuf_info *ubuf, bool zerocopy_success) napi_schedule(&vif->napi); local_bh_enable(); } + + if (likely(zerocopy_success)) + vif->tx_zerocopy_success++; + else + vif->tx_zerocopy_fail++; } static inline void xenvif_tx_dealloc_action(struct xenvif *vif) |