diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index b0577dd..a4e6988 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -36,7 +36,9 @@ module_param(gso, bool, 0444); /* FIXME: MTU in config. */ #define MAX_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN) -#define GOOD_COPY_LEN 128 +#define GOOD_COPY_LEN 512 #define VIRTNET_SEND_COMMAND_SG_MAX 2 @@ -147,11 +149,12 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, { struct sk_buff *skb; struct skb_vnet_hdr *hdr; - unsigned int copy, hdr_len, offset; + unsigned int copy, hdr_len, offset, end; char *p; p = page_address(page); @@ -172,14 +175,25 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi, len -= hdr_len; p += offset; - copy = len; + if (!hdr->hdr.hdr_len) + copy = len; + else { + copy = hdr->hdr.hdr_len; + end = skb_tailroom(skb); + printk(KERN_INFO "c %d, e %d\n", copy, end); + } + if (copy > skb_tailroom(skb)) copy = skb_tailroom(skb); memcpy(skb_put(skb, copy), p, copy); len -= copy; - offset += copy; + if (!hdr->hdr.hdr_len) + offset += copy; + else + offset = end; + printk(KERN_INFO "off %d\n", offset); while (len) { set_skb_frag(skb, page, offset, &len); page = (struct page *)page->private; @@ -218,7 +238,12 @@ static int receive_mergeable(struct virtnet_info *vi, struct sk_buff *skb) len = PAGE_SIZE; set_skb_frag(skb, page, 0, &len); - + if (hdr->hdr.hdr_len) + set_skb_frag(skb, page, 542, &len); + else + set_skb_frag(skb, page, 0, &len); --vi->num; } return 0; @@ -311,7 +340,15 @@ static void receive_buf(struct net_device *dev, void *buf, unsigned int len) skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY; skb_shinfo(skb)->gso_segs = 0; } - + skb->ip_summed = 1; netif_receive_skb(skb); return; @@ -479,7 +516,8 @@ again: received++; } - if (vi->num < vi->max / 2) { + if (vi->num < vi->max - 10) { if (!try_fill_recv(vi, GFP_ATOMIC)) schedule_delayed_work(&vi->refill, 0); }