aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/xen-netfront.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-09-13 10:41:01 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-09-13 10:41:01 -0400
commit78890b5989d96ddce989cde929c45ceeded0fcaf (patch)
tree4e2da81fc7c97f11aee174b1eedac110c9a68b3a /drivers/net/xen-netfront.c
parent1959ec5f82acbdf91425b41600f119ebecb5f6a8 (diff)
parent55d512e245bc7699a8800e23df1a24195dd08217 (diff)
Merge commit 'v3.6-rc5' into next
* commit 'v3.6-rc5': (1098 commits) Linux 3.6-rc5 HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured Remove user-triggerable BUG from mpol_to_str xen/pciback: Fix proper FLR steps. uml: fix compile error in deliver_alarm() dj: memory scribble in logi_dj Fix order of arguments to compat_put_time[spec|val] xen: Use correct masking in xen_swiotlb_alloc_coherent. xen: fix logical error in tlb flushing xen/p2m: Fix one-off error in checking the P2M tree directory. powerpc: Don't use __put_user() in patch_instruction powerpc: Make sure IPI handlers see data written by IPI senders powerpc: Restore correct DSCR in context switch powerpc: Fix DSCR inheritance in copy_thread() powerpc: Keep thread.dscr and thread.dscr_inherit in sync powerpc: Update DSCR on all CPUs when writing sysfs dscr_default powerpc/powernv: Always go into nap mode when CPU is offline powerpc: Give hypervisor decrementer interrupts their own handler powerpc/vphn: Fix arch_update_cpu_topology() return value ARM: gemini: fix the gemini build ... Conflicts: drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c drivers/rapidio/devices/tsi721.c
Diffstat (limited to 'drivers/net/xen-netfront.c')
-rw-r--r--drivers/net/xen-netfront.c39
1 files changed, 10 insertions, 29 deletions
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 30899901aef5..650f79a1f2bd 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -57,8 +57,7 @@
57static const struct ethtool_ops xennet_ethtool_ops; 57static const struct ethtool_ops xennet_ethtool_ops;
58 58
59struct netfront_cb { 59struct netfront_cb {
60 struct page *page; 60 int pull_to;
61 unsigned offset;
62}; 61};
63 62
64#define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb)) 63#define NETFRONT_SKB_CB(skb) ((struct netfront_cb *)((skb)->cb))
@@ -867,15 +866,9 @@ static int handle_incoming_queue(struct net_device *dev,
867 struct sk_buff *skb; 866 struct sk_buff *skb;
868 867
869 while ((skb = __skb_dequeue(rxq)) != NULL) { 868 while ((skb = __skb_dequeue(rxq)) != NULL) {
870 struct page *page = NETFRONT_SKB_CB(skb)->page; 869 int pull_to = NETFRONT_SKB_CB(skb)->pull_to;
871 void *vaddr = page_address(page);
872 unsigned offset = NETFRONT_SKB_CB(skb)->offset;
873
874 memcpy(skb->data, vaddr + offset,
875 skb_headlen(skb));
876 870
877 if (page != skb_frag_page(&skb_shinfo(skb)->frags[0])) 871 __pskb_pull_tail(skb, pull_to - skb_headlen(skb));
878 __free_page(page);
879 872
880 /* Ethernet work: Delayed to here as it peeks the header. */ 873 /* Ethernet work: Delayed to here as it peeks the header. */
881 skb->protocol = eth_type_trans(skb, dev); 874 skb->protocol = eth_type_trans(skb, dev);
@@ -913,7 +906,6 @@ static int xennet_poll(struct napi_struct *napi, int budget)
913 struct sk_buff_head errq; 906 struct sk_buff_head errq;
914 struct sk_buff_head tmpq; 907 struct sk_buff_head tmpq;
915 unsigned long flags; 908 unsigned long flags;
916 unsigned int len;
917 int err; 909 int err;
918 910
919 spin_lock(&np->rx_lock); 911 spin_lock(&np->rx_lock);
@@ -955,24 +947,13 @@ err:
955 } 947 }
956 } 948 }
957 949
958 NETFRONT_SKB_CB(skb)->page = 950 NETFRONT_SKB_CB(skb)->pull_to = rx->status;
959 skb_frag_page(&skb_shinfo(skb)->frags[0]); 951 if (NETFRONT_SKB_CB(skb)->pull_to > RX_COPY_THRESHOLD)
960 NETFRONT_SKB_CB(skb)->offset = rx->offset; 952 NETFRONT_SKB_CB(skb)->pull_to = RX_COPY_THRESHOLD;
961
962 len = rx->status;
963 if (len > RX_COPY_THRESHOLD)
964 len = RX_COPY_THRESHOLD;
965 skb_put(skb, len);
966 953
967 if (rx->status > len) { 954 skb_shinfo(skb)->frags[0].page_offset = rx->offset;
968 skb_shinfo(skb)->frags[0].page_offset = 955 skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status);
969 rx->offset + len; 956 skb->data_len = rx->status;
970 skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status - len);
971 skb->data_len = rx->status - len;
972 } else {
973 __skb_fill_page_desc(skb, 0, NULL, 0, 0);
974 skb_shinfo(skb)->nr_frags = 0;
975 }
976 957
977 i = xennet_fill_frags(np, skb, &tmpq); 958 i = xennet_fill_frags(np, skb, &tmpq);
978 959
@@ -999,7 +980,7 @@ err:
999 * receive throughout using the standard receive 980 * receive throughout using the standard receive
1000 * buffer size was cut by 25%(!!!). 981 * buffer size was cut by 25%(!!!).
1001 */ 982 */
1002 skb->truesize += skb->data_len - (RX_COPY_THRESHOLD - len); 983 skb->truesize += skb->data_len - RX_COPY_THRESHOLD;
1003 skb->len += skb->data_len; 984 skb->len += skb->data_len;
1004 985
1005 if (rx->flags & XEN_NETRXF_csum_blank) 986 if (rx->flags & XEN_NETRXF_csum_blank)