diff options
| author | Ingo Molnar <mingo@kernel.org> | 2014-01-16 03:33:30 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2014-01-16 03:33:30 -0500 |
| commit | 860fc2f2640ec348b9520ca4649b1bfd23d91bc2 (patch) | |
| tree | 73d90d6ef86893c89bb70e78a2b63295d531f371 /drivers/net/xen-netback | |
| parent | 197749981e539c1eb5863f417de6dd4e2c02b76c (diff) | |
| parent | bee09ed91cacdbffdbcd3b05de8409c77ec9fcd6 (diff) | |
Merge branch 'perf/urgent' into perf/core
Pick up the latest fixes, refresh the development tree.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'drivers/net/xen-netback')
| -rw-r--r-- | drivers/net/xen-netback/common.h | 19 | ||||
| -rw-r--r-- | drivers/net/xen-netback/interface.c | 11 | ||||
| -rw-r--r-- | drivers/net/xen-netback/netback.c | 21 |
3 files changed, 40 insertions, 11 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 | |||
| 104 | struct xenvif { | 111 | struct 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..fff8cddfed81 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -34,6 +34,7 @@ | |||
| 34 | #include <linux/ethtool.h> | 34 | #include <linux/ethtool.h> |
| 35 | #include <linux/rtnetlink.h> | 35 | #include <linux/rtnetlink.h> |
| 36 | #include <linux/if_vlan.h> | 36 | #include <linux/if_vlan.h> |
| 37 | #include <linux/vmalloc.h> | ||
| 37 | 38 | ||
| 38 | #include <xen/events.h> | 39 | #include <xen/events.h> |
| 39 | #include <asm/xen/hypercall.h> | 40 | #include <asm/xen/hypercall.h> |
| @@ -307,6 +308,15 @@ struct xenvif *xenvif_alloc(struct device *parent, domid_t domid, | |||
| 307 | SET_NETDEV_DEV(dev, parent); | 308 | SET_NETDEV_DEV(dev, parent); |
| 308 | 309 | ||
| 309 | vif = netdev_priv(dev); | 310 | vif = netdev_priv(dev); |
| 311 | |||
| 312 | vif->grant_copy_op = vmalloc(sizeof(struct gnttab_copy) * | ||
| 313 | MAX_GRANT_COPY_OPS); | ||
| 314 | if (vif->grant_copy_op == NULL) { | ||
| 315 | pr_warn("Could not allocate grant copy space for %s\n", name); | ||
| 316 | free_netdev(dev); | ||
| 317 | return ERR_PTR(-ENOMEM); | ||
| 318 | } | ||
| 319 | |||
| 310 | vif->domid = domid; | 320 | vif->domid = domid; |
| 311 | vif->handle = handle; | 321 | vif->handle = handle; |
| 312 | vif->can_sg = 1; | 322 | vif->can_sg = 1; |
| @@ -487,6 +497,7 @@ void xenvif_free(struct xenvif *vif) | |||
| 487 | 497 | ||
| 488 | unregister_netdev(vif->dev); | 498 | unregister_netdev(vif->dev); |
| 489 | 499 | ||
| 500 | vfree(vif->grant_copy_op); | ||
| 490 | free_netdev(vif->dev); | 501 | free_netdev(vif->dev); |
| 491 | 502 | ||
| 492 | module_put(THIS_MODULE); | 503 | module_put(THIS_MODULE); |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index e884ee1fe7ed..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) { |
| @@ -1197,6 +1197,9 @@ static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | |||
| 1197 | 1197 | ||
| 1198 | err = -EPROTO; | 1198 | err = -EPROTO; |
| 1199 | 1199 | ||
| 1200 | if (fragment) | ||
| 1201 | goto out; | ||
| 1202 | |||
| 1200 | switch (ip_hdr(skb)->protocol) { | 1203 | switch (ip_hdr(skb)->protocol) { |
| 1201 | case IPPROTO_TCP: | 1204 | case IPPROTO_TCP: |
| 1202 | err = maybe_pull_tail(skb, | 1205 | err = maybe_pull_tail(skb, |
| @@ -1206,8 +1209,10 @@ static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | |||
| 1206 | goto out; | 1209 | goto out; |
| 1207 | 1210 | ||
| 1208 | if (!skb_partial_csum_set(skb, off, | 1211 | if (!skb_partial_csum_set(skb, off, |
| 1209 | offsetof(struct tcphdr, check))) | 1212 | offsetof(struct tcphdr, check))) { |
| 1213 | err = -EPROTO; | ||
| 1210 | goto out; | 1214 | goto out; |
| 1215 | } | ||
| 1211 | 1216 | ||
| 1212 | if (recalculate_partial_csum) | 1217 | if (recalculate_partial_csum) |
| 1213 | tcp_hdr(skb)->check = | 1218 | tcp_hdr(skb)->check = |
| @@ -1224,8 +1229,10 @@ static int checksum_setup_ip(struct xenvif *vif, struct sk_buff *skb, | |||
| 1224 | goto out; | 1229 | goto out; |
| 1225 | 1230 | ||
| 1226 | if (!skb_partial_csum_set(skb, off, | 1231 | if (!skb_partial_csum_set(skb, off, |
| 1227 | offsetof(struct udphdr, check))) | 1232 | offsetof(struct udphdr, check))) { |
| 1233 | err = -EPROTO; | ||
| 1228 | goto out; | 1234 | goto out; |
| 1235 | } | ||
| 1229 | 1236 | ||
| 1230 | if (recalculate_partial_csum) | 1237 | if (recalculate_partial_csum) |
| 1231 | udp_hdr(skb)->check = | 1238 | udp_hdr(skb)->check = |
| @@ -1347,8 +1354,10 @@ static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, | |||
| 1347 | goto out; | 1354 | goto out; |
| 1348 | 1355 | ||
| 1349 | if (!skb_partial_csum_set(skb, off, | 1356 | if (!skb_partial_csum_set(skb, off, |
| 1350 | offsetof(struct tcphdr, check))) | 1357 | offsetof(struct tcphdr, check))) { |
| 1358 | err = -EPROTO; | ||
| 1351 | goto out; | 1359 | goto out; |
| 1360 | } | ||
| 1352 | 1361 | ||
| 1353 | if (recalculate_partial_csum) | 1362 | if (recalculate_partial_csum) |
| 1354 | tcp_hdr(skb)->check = | 1363 | tcp_hdr(skb)->check = |
| @@ -1365,8 +1374,10 @@ static int checksum_setup_ipv6(struct xenvif *vif, struct sk_buff *skb, | |||
| 1365 | goto out; | 1374 | goto out; |
| 1366 | 1375 | ||
| 1367 | if (!skb_partial_csum_set(skb, off, | 1376 | if (!skb_partial_csum_set(skb, off, |
| 1368 | offsetof(struct udphdr, check))) | 1377 | offsetof(struct udphdr, check))) { |
| 1378 | err = -EPROTO; | ||
| 1369 | goto out; | 1379 | goto out; |
| 1380 | } | ||
| 1370 | 1381 | ||
| 1371 | if (recalculate_partial_csum) | 1382 | if (recalculate_partial_csum) |
| 1372 | udp_hdr(skb)->check = | 1383 | udp_hdr(skb)->check = |
