aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Durrant <Paul.Durrant@citrix.com>2013-12-23 04:27:17 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-29 22:31:30 -0500
commitac3d5ac277352fe6e27809286768e9f1f8aa388d (patch)
tree1291e41ffe15d90e5e7f6b6d019b62b9d1bbdaa6
parent7a399e3a2e05bc580a78ea72371b3896827f72e1 (diff)
xen-netback: fix guest-receive-side array sizes
The sizes chosen for the metadata and grant_copy_op arrays on the guest receive size are wrong; - The meta array is needlessly twice the ring size, when we only ever consume a single array element per RX ring slot - The grant_copy_op array is way too small. It's sized based on a bogus assumption: that at most two copy ops will be used per ring slot. This may have been true at some point in the past but it's clear from looking at start_new_rx_buffer() that a new ring slot is only consumed if a frag would overflow the current slot (plus some other conditions) so the actual limit is MAX_SKB_FRAGS grant_copy_ops per ring slot. This patch fixes those two sizing issues and, because grant_copy_ops grows so much, it pulls it out into a separate chunk of vmalloc()ed memory. Signed-off-by: Paul Durrant <paul.durrant@citrix.com> Acked-by: Wei Liu <wei.liu2@citrix.com> Cc: Ian Campbell <ian.campbell@citrix.com> Cc: David Vrabel <david.vrabel@citrix.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/xen-netback/common.h19
-rw-r--r--drivers/net/xen-netback/interface.c10
-rw-r--r--drivers/net/xen-netback/netback.c2
3 files changed, 24 insertions, 7 deletions
diff --git a/drivers/net/xen-netback/common.h b/drivers/net/xen-netback/common.h
index 08ae01b41c83..c47794b9d42f 100644
--- a/drivers/net/xen-netback/common.h
+++ b/drivers/net/xen-netback/common.h
@@ -101,6 +101,13 @@ struct xenvif_rx_meta {
101 101
102#define MAX_PENDING_REQS 256 102#define MAX_PENDING_REQS 256
103 103
104/* It's possible for an skb to have a maximal number of frags
105 * but still be less than MAX_BUFFER_OFFSET in size. Thus the
106 * worst-case number of copy operations is MAX_SKB_FRAGS per
107 * ring slot.
108 */
109#define MAX_GRANT_COPY_OPS (MAX_SKB_FRAGS * XEN_NETIF_RX_RING_SIZE)
110
104struct xenvif { 111struct xenvif {
105 /* Unique identifier for this interface. */ 112 /* Unique identifier for this interface. */
106 domid_t domid; 113 domid_t domid;
@@ -143,13 +150,13 @@ struct xenvif {
143 */ 150 */
144 RING_IDX rx_req_cons_peek; 151 RING_IDX rx_req_cons_peek;
145 152
146 /* Given MAX_BUFFER_OFFSET of 4096 the worst case is that each 153 /* This array is allocated seperately as it is large */
147 * head/fragment page uses 2 copy operations because it 154 struct gnttab_copy *grant_copy_op;
148 * straddles two buffers in the frontend.
149 */
150 struct gnttab_copy grant_copy_op[2*XEN_NETIF_RX_RING_SIZE];
151 struct xenvif_rx_meta meta[2*XEN_NETIF_RX_RING_SIZE];
152 155
156 /* We create one meta structure per ring request we consume, so
157 * the maximum number is the same as the ring size.
158 */
159 struct xenvif_rx_meta meta[XEN_NETIF_RX_RING_SIZE];
153 160
154 u8 fe_dev_addr[6]; 161 u8 fe_dev_addr[6];
155 162
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c
index 870f1fa58370..34ca4e58a43d 100644
--- a/drivers/net/xen-netback/interface.c
+++ b/drivers/net/xen-netback/interface.c
@@ -307,6 +307,15 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid,
307 SET_NETDEV_DEV(dev, parent); 307 SET_NETDEV_DEV(dev, parent);
308 308
309 vif = netdev_priv(dev); 309 vif = netdev_priv(dev);
310
311 vif->grant_copy_op = vmalloc(sizeof(struct gnttab_copy) *
312 MAX_GRANT_COPY_OPS);
313 if (vif->grant_copy_op == NULL) {
314 pr_warn("Could not allocate grant copy space for %s\n", name);
315 free_netdev(dev);
316 return ERR_PTR(-ENOMEM);
317 }
318
310 vif->domid = domid; 319 vif->domid = domid;
311 vif->handle = handle; 320 vif->handle = handle;
312 vif->can_sg = 1; 321 vif->can_sg = 1;
@@ -487,6 +496,7 @@ void xenvif_free(struct xenvif *vif)
487 496
488 unregister_netdev(vif->dev); 497 unregister_netdev(vif->dev);
489 498
499 vfree(vif->grant_copy_op);
490 free_netdev(vif->dev); 500 free_netdev(vif->dev);
491 501
492 module_put(THIS_MODULE); 502 module_put(THIS_MODULE);
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
index 7b4fd93be76d..78425554a537 100644
--- a/drivers/net/xen-netback/netback.c
+++ b/drivers/net/xen-netback/netback.c
@@ -608,7 +608,7 @@ void xenvif_rx_action(struct xenvif *vif)
608 if (!npo.copy_prod) 608 if (!npo.copy_prod)
609 return; 609 return;
610 610
611 BUG_ON(npo.copy_prod > ARRAY_SIZE(vif->grant_copy_op)); 611 BUG_ON(npo.copy_prod > MAX_GRANT_COPY_OPS);
612 gnttab_batch_copy(vif->grant_copy_op, npo.copy_prod); 612 gnttab_batch_copy(vif->grant_copy_op, npo.copy_prod);
613 613
614 while ((skb = __skb_dequeue(&rxq)) != NULL) { 614 while ((skb = __skb_dequeue(&rxq)) != NULL) {