aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/virtio_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/virtio_net.c')
-rw-r--r--drivers/net/virtio_net.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 25dc77ccbf58..b0a85d038796 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -25,6 +25,7 @@
25#include <linux/virtio_net.h> 25#include <linux/virtio_net.h>
26#include <linux/scatterlist.h> 26#include <linux/scatterlist.h>
27#include <linux/if_vlan.h> 27#include <linux/if_vlan.h>
28#include <linux/slab.h>
28 29
29static int napi_weight = 128; 30static int napi_weight = 128;
30module_param(napi_weight, int, 0444); 31module_param(napi_weight, int, 0444);
@@ -39,8 +40,7 @@ module_param(gso, bool, 0444);
39 40
40#define VIRTNET_SEND_COMMAND_SG_MAX 2 41#define VIRTNET_SEND_COMMAND_SG_MAX 2
41 42
42struct virtnet_info 43struct virtnet_info {
43{
44 struct virtio_device *vdev; 44 struct virtio_device *vdev;
45 struct virtqueue *rvq, *svq, *cvq; 45 struct virtqueue *rvq, *svq, *cvq;
46 struct net_device *dev; 46 struct net_device *dev;
@@ -61,6 +61,10 @@ struct virtnet_info
61 61
62 /* Chain pages by the private ptr. */ 62 /* Chain pages by the private ptr. */
63 struct page *pages; 63 struct page *pages;
64
65 /* fragments + linear part + virtio header */
66 struct scatterlist rx_sg[MAX_SKB_FRAGS + 2];
67 struct scatterlist tx_sg[MAX_SKB_FRAGS + 2];
64}; 68};
65 69
66struct skb_vnet_hdr { 70struct skb_vnet_hdr {
@@ -323,7 +327,6 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
323{ 327{
324 struct sk_buff *skb; 328 struct sk_buff *skb;
325 struct skb_vnet_hdr *hdr; 329 struct skb_vnet_hdr *hdr;
326 struct scatterlist sg[2];
327 int err; 330 int err;
328 331
329 skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN); 332 skb = netdev_alloc_skb_ip_align(vi->dev, MAX_PACKET_LEN);
@@ -333,11 +336,11 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
333 skb_put(skb, MAX_PACKET_LEN); 336 skb_put(skb, MAX_PACKET_LEN);
334 337
335 hdr = skb_vnet_hdr(skb); 338 hdr = skb_vnet_hdr(skb);
336 sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr); 339 sg_set_buf(vi->rx_sg, &hdr->hdr, sizeof hdr->hdr);
337 340
338 skb_to_sgvec(skb, sg + 1, 0, skb->len); 341 skb_to_sgvec(skb, vi->rx_sg + 1, 0, skb->len);
339 342
340 err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, 2, skb); 343 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, 2, skb);
341 if (err < 0) 344 if (err < 0)
342 dev_kfree_skb(skb); 345 dev_kfree_skb(skb);
343 346
@@ -346,12 +349,11 @@ static int add_recvbuf_small(struct virtnet_info *vi, gfp_t gfp)
346 349
347static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp) 350static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
348{ 351{
349 struct scatterlist sg[MAX_SKB_FRAGS + 2];
350 struct page *first, *list = NULL; 352 struct page *first, *list = NULL;
351 char *p; 353 char *p;
352 int i, err, offset; 354 int i, err, offset;
353 355
354 /* page in sg[MAX_SKB_FRAGS + 1] is list tail */ 356 /* page in vi->rx_sg[MAX_SKB_FRAGS + 1] is list tail */
355 for (i = MAX_SKB_FRAGS + 1; i > 1; --i) { 357 for (i = MAX_SKB_FRAGS + 1; i > 1; --i) {
356 first = get_a_page(vi, gfp); 358 first = get_a_page(vi, gfp);
357 if (!first) { 359 if (!first) {
@@ -359,7 +361,7 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
359 give_pages(vi, list); 361 give_pages(vi, list);
360 return -ENOMEM; 362 return -ENOMEM;
361 } 363 }
362 sg_set_buf(&sg[i], page_address(first), PAGE_SIZE); 364 sg_set_buf(&vi->rx_sg[i], page_address(first), PAGE_SIZE);
363 365
364 /* chain new page in list head to match sg */ 366 /* chain new page in list head to match sg */
365 first->private = (unsigned long)list; 367 first->private = (unsigned long)list;
@@ -373,17 +375,17 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
373 } 375 }
374 p = page_address(first); 376 p = page_address(first);
375 377
376 /* sg[0], sg[1] share the same page */ 378 /* vi->rx_sg[0], vi->rx_sg[1] share the same page */
377 /* a separated sg[0] for virtio_net_hdr only during to QEMU bug*/ 379 /* a separated vi->rx_sg[0] for virtio_net_hdr only due to QEMU bug */
378 sg_set_buf(&sg[0], p, sizeof(struct virtio_net_hdr)); 380 sg_set_buf(&vi->rx_sg[0], p, sizeof(struct virtio_net_hdr));
379 381
380 /* sg[1] for data packet, from offset */ 382 /* vi->rx_sg[1] for data packet, from offset */
381 offset = sizeof(struct padded_vnet_hdr); 383 offset = sizeof(struct padded_vnet_hdr);
382 sg_set_buf(&sg[1], p + offset, PAGE_SIZE - offset); 384 sg_set_buf(&vi->rx_sg[1], p + offset, PAGE_SIZE - offset);
383 385
384 /* chain first in list head */ 386 /* chain first in list head */
385 first->private = (unsigned long)list; 387 first->private = (unsigned long)list;
386 err = vi->rvq->vq_ops->add_buf(vi->rvq, sg, 0, MAX_SKB_FRAGS + 2, 388 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, MAX_SKB_FRAGS + 2,
387 first); 389 first);
388 if (err < 0) 390 if (err < 0)
389 give_pages(vi, first); 391 give_pages(vi, first);
@@ -394,16 +396,15 @@ static int add_recvbuf_big(struct virtnet_info *vi, gfp_t gfp)
394static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp) 396static int add_recvbuf_mergeable(struct virtnet_info *vi, gfp_t gfp)
395{ 397{
396 struct page *page; 398 struct page *page;
397 struct scatterlist sg;
398 int err; 399 int err;
399 400
400 page = get_a_page(vi, gfp); 401 page = get_a_page(vi, gfp);
401 if (!page) 402 if (!page)
402 return -ENOMEM; 403 return -ENOMEM;
403 404
404 sg_init_one(&sg, page_address(page), PAGE_SIZE); 405 sg_init_one(vi->rx_sg, page_address(page), PAGE_SIZE);
405 406
406 err = vi->rvq->vq_ops->add_buf(vi->rvq, &sg, 0, 1, page); 407 err = vi->rvq->vq_ops->add_buf(vi->rvq, vi->rx_sg, 0, 1, page);
407 if (err < 0) 408 if (err < 0)
408 give_pages(vi, page); 409 give_pages(vi, page);
409 410
@@ -512,12 +513,9 @@ static unsigned int free_old_xmit_skbs(struct virtnet_info *vi)
512 513
513static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb) 514static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
514{ 515{
515 struct scatterlist sg[2+MAX_SKB_FRAGS];
516 struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb); 516 struct skb_vnet_hdr *hdr = skb_vnet_hdr(skb);
517 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; 517 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
518 518
519 sg_init_table(sg, 2+MAX_SKB_FRAGS);
520
521 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); 519 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
522 520
523 if (skb->ip_summed == CHECKSUM_PARTIAL) { 521 if (skb->ip_summed == CHECKSUM_PARTIAL) {
@@ -551,12 +549,13 @@ static int xmit_skb(struct virtnet_info *vi, struct sk_buff *skb)
551 549
552 /* Encode metadata header at front. */ 550 /* Encode metadata header at front. */
553 if (vi->mergeable_rx_bufs) 551 if (vi->mergeable_rx_bufs)
554 sg_set_buf(sg, &hdr->mhdr, sizeof hdr->mhdr); 552 sg_set_buf(vi->tx_sg, &hdr->mhdr, sizeof hdr->mhdr);
555 else 553 else
556 sg_set_buf(sg, &hdr->hdr, sizeof hdr->hdr); 554 sg_set_buf(vi->tx_sg, &hdr->hdr, sizeof hdr->hdr);
557 555
558 hdr->num_sg = skb_to_sgvec(skb, sg+1, 0, skb->len) + 1; 556 hdr->num_sg = skb_to_sgvec(skb, vi->tx_sg + 1, 0, skb->len) + 1;
559 return vi->svq->vq_ops->add_buf(vi->svq, sg, hdr->num_sg, 0, skb); 557 return vi->svq->vq_ops->add_buf(vi->svq, vi->tx_sg, hdr->num_sg,
558 0, skb);
560} 559}
561 560
562static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) 561static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -719,7 +718,6 @@ static void virtnet_set_rx_mode(struct net_device *dev)
719 struct scatterlist sg[2]; 718 struct scatterlist sg[2];
720 u8 promisc, allmulti; 719 u8 promisc, allmulti;
721 struct virtio_net_ctrl_mac *mac_data; 720 struct virtio_net_ctrl_mac *mac_data;
722 struct dev_addr_list *addr;
723 struct netdev_hw_addr *ha; 721 struct netdev_hw_addr *ha;
724 int uc_count; 722 int uc_count;
725 int mc_count; 723 int mc_count;
@@ -776,8 +774,8 @@ static void virtnet_set_rx_mode(struct net_device *dev)
776 774
777 mac_data->entries = mc_count; 775 mac_data->entries = mc_count;
778 i = 0; 776 i = 0;
779 netdev_for_each_mc_addr(addr, dev) 777 netdev_for_each_mc_addr(ha, dev)
780 memcpy(&mac_data->macs[i++][0], addr->da_addr, ETH_ALEN); 778 memcpy(&mac_data->macs[i++][0], ha->addr, ETH_ALEN);
781 779
782 sg_set_buf(&sg[1], mac_data, 780 sg_set_buf(&sg[1], mac_data,
783 sizeof(mac_data->entries) + (mc_count * ETH_ALEN)); 781 sizeof(mac_data->entries) + (mc_count * ETH_ALEN));
@@ -939,6 +937,8 @@ static int virtnet_probe(struct virtio_device *vdev)
939 vdev->priv = vi; 937 vdev->priv = vi;
940 vi->pages = NULL; 938 vi->pages = NULL;
941 INIT_DELAYED_WORK(&vi->refill, refill_work); 939 INIT_DELAYED_WORK(&vi->refill, refill_work);
940 sg_init_table(vi->rx_sg, ARRAY_SIZE(vi->rx_sg));
941 sg_init_table(vi->tx_sg, ARRAY_SIZE(vi->tx_sg));
942 942
943 /* If we can receive ANY GSO packets, we must allocate large ones. */ 943 /* If we can receive ANY GSO packets, we must allocate large ones. */
944 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) || 944 if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||