diff options
author | Zoltan Kiss <zoltan.kiss@citrix.com> | 2014-03-06 16:48:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-07 15:56:35 -0500 |
commit | e3377f36ca20a034dce56335dc9b89f41094d845 (patch) | |
tree | 2a2c0d898afae8176b1561a4480f454893fc24ef /drivers/net/xen-netback/interface.c | |
parent | 1bb332af4cd889e4b64dacbf4a793ceb3a70445d (diff) |
xen-netback: Handle guests with too many frags
Xen network protocol had implicit dependency on MAX_SKB_FRAGS. Netback has to
handle guests sending up to XEN_NETBK_LEGACY_SLOTS_MAX slots. To achieve that:
- create a new skb
- map the leftover slots to its frags (no linear buffer here!)
- chain it to the previous through skb_shinfo(skb)->frag_list
- map them
- copy and coalesce the frags into a brand new one and send it to the stack
- unmap the 2 old skb's pages
It's also introduces new stat counters, which help determine how often the guest
sends a packet with more than MAX_SKB_FRAGS frags.
NOTE: if bisect brought you here, you should apply the series up until
"xen-netback: Timeout packets in RX path", otherwise 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>
Diffstat (limited to 'drivers/net/xen-netback/interface.c')
-rw-r--r-- | drivers/net/xen-netback/interface.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 44df8581b4d7..b646039e539b 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
@@ -253,6 +253,13 @@ static const struct xenvif_stat { | |||
253 | "tx_zerocopy_fail", | 253 | "tx_zerocopy_fail", |
254 | offsetof(struct xenvif, tx_zerocopy_fail) | 254 | offsetof(struct xenvif, tx_zerocopy_fail) |
255 | }, | 255 | }, |
256 | /* Number of packets exceeding MAX_SKB_FRAG slots. You should use | ||
257 | * a guest with the same MAX_SKB_FRAG | ||
258 | */ | ||
259 | { | ||
260 | "tx_frag_overflow", | ||
261 | offsetof(struct xenvif, tx_frag_overflow) | ||
262 | }, | ||
256 | }; | 263 | }; |
257 | 264 | ||
258 | static int xenvif_get_sset_count(struct net_device *dev, int string_set) | 265 | static int xenvif_get_sset_count(struct net_device *dev, int string_set) |