aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2014-10-24 09:55:57 -0400
committerMichael S. Tsirkin <mst@redhat.com>2014-12-09 05:05:28 -0500
commit012873d057a449c4480e7679e733a7daa9aa540f (patch)
treeae7c8bd666d623f1964b588d71ea4f2b8d1346b5
parent946fa5647b529402161814ca8ed1302254b6affb (diff)
virtio_net: get rid of virtio_net_hdr/skb_vnet_hdr
virtio 1.0 doesn't use virtio_net_hdr anymore, and in fact, it's not really useful since virtio_net_hdr_mrg_rxbuf includes that as the first field anyway. Let's drop it, precalculate header len and store within vi instead. This way we can also remove struct skb_vnet_hdr. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Jason Wang <jasowang@redhat.com>
-rw-r--r--drivers/net/virtio_net.c90
1 files changed, 41 insertions, 49 deletions
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 1630c217d9f7..516f2cb034b5 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -123,6 +123,9 @@ struct virtnet_info {
123 /* Host can handle any s/g split between our header and packet data */ 123 /* Host can handle any s/g split between our header and packet data */
124 bool any_header_sg; 124 bool any_header_sg;
125 125
126 /* Packet virtio header size */
127 u8 hdr_len;
128
126 /* Active statistics */ 129 /* Active statistics */
127 struct virtnet_stats __percpu *stats; 130 struct virtnet_stats __percpu *stats;
128 131
@@ -139,21 +142,14 @@ struct virtnet_info {
139 struct notifier_block nb; 142 struct notifier_block nb;
140}; 143};
141 144
142struct skb_vnet_hdr {
143 union {
144 struct virtio_net_hdr hdr;
145 struct virtio_net_hdr_mrg_rxbuf mhdr;
146 };
147};
148
149struct padded_vnet_hdr { 145struct padded_vnet_hdr {
150 struct virtio_net_hdr hdr; 146 struct virtio_net_hdr_mrg_rxbuf hdr;
151 /* 147 /*
152 * virtio_net_hdr should be in a separated sg buffer because of a 148 * hdr is in a separate sg buffer, and data sg buffer shares same page
153 * QEMU bug, and data sg buffer shares same page with this header sg. 149 * with this header sg. This padding makes next sg 16 byte aligned
154 * This padding makes next sg 16 byte aligned after virtio_net_hdr. 150 * after the header.
155 */ 151 */
156 char padding[6]; 152 char padding[4];
157}; 153};
158 154
159/* Converting between virtqueue no. and kernel tx/rx queue no. 155/* Converting between virtqueue no. and kernel tx/rx queue no.
@@ -179,9 +175,9 @@ static int rxq2vq(int rxq)
179 return rxq * 2; 175 return rxq * 2;
180} 176}
181 177
182static inline struct skb_vnet_hdr *skb_vnet_hdr(struct sk_buff *skb) 178static inline struct virtio_net_hdr_mrg_rxbuf *skb_vnet_hdr(struct sk_buff *skb)
183{ 179{
184 return (struct skb_vnet_hdr *)skb->cb; 180 return (struct virtio_net_hdr_mrg_rxbuf *)skb->cb;
185} 181}
186 182
187/* 183/*
@@ -247,7 +243,7 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
247 unsigned int len, unsigned int truesize) 243 unsigned int len, unsigned int truesize)
248{ 244{
249 struct sk_buff *skb; 245 struct sk_buff *skb;
250 struct skb_vnet_hdr *hdr; 246 struct virtio_net_hdr_mrg_rxbuf *hdr;
251 unsigned int copy, hdr_len, hdr_padded_len; 247 unsigned int copy, hdr_len, hdr_padded_len;
252 char *p; 248 char *p;
253 249
@@ -260,13 +256,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
260 256
261 hdr = skb_vnet_hdr(skb); 257 hdr = skb_vnet_hdr(skb);
262 258
263 if (vi->mergeable_rx_bufs) { 259 hdr_len = vi->hdr_len;
264 hdr_len = sizeof hdr->mhdr; 260 if (vi->mergeable_rx_bufs)
265 hdr_padded_len = sizeof hdr->mhdr; 261 hdr_padded_len = sizeof *hdr;
266 } else { 262 else
267 hdr_len = sizeof hdr->hdr;
268 hdr_padded_len = sizeof(struct padded_vnet_hdr); 263 hdr_padded_len = sizeof(struct padded_vnet_hdr);
269 }
270 264
271 memcpy(hdr, p, hdr_len); 265 memcpy(hdr, p, hdr_len);
272 266
@@ -317,11 +311,11 @@ static struct sk_buff *page_to_skb(struct virtnet_info *vi,
317 return skb; 311 return skb;
318} 312}
319 313
320static struct sk_buff *receive_small(void *buf, unsigned int len) 314static struct sk_buff *receive_small(struct virtnet_info *vi, void *buf, unsigned int len)
321{ 315{
322 struct sk_buff * skb = buf; 316 struct sk_buff * skb = buf;
323 317
324 len -= sizeof(struct virtio_net_hdr); 318 len -= vi->hdr_len;
325 skb_trim(skb, len); 319 skb_trim(skb, len);
326 320
327 return skb; 321 return skb;
@@ -354,8 +348,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
354 unsigned int len) 348 unsigned int len)
355{ 349{
356 void *buf = mergeable_ctx_to_buf_address(ctx); 350 void *buf = mergeable_ctx_to_buf_address(ctx);
357 struct skb_vnet_hdr *hdr = buf; 351 struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
358 u16 num_buf = virtio16_to_cpu(rq->vq->vdev, hdr->mhdr.num_buffers); 352 u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers);
359 struct page *page = virt_to_head_page(buf); 353 struct page *page = virt_to_head_page(buf);
360 int offset = buf - page_address(page); 354 int offset = buf - page_address(page);
361 unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx)); 355 unsigned int truesize = max(len, mergeable_ctx_to_buf_truesize(ctx));
@@ -373,8 +367,8 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
373 if (unlikely(!ctx)) { 367 if (unlikely(!ctx)) {
374 pr_debug("%s: rx error: %d buffers out of %d missing\n", 368 pr_debug("%s: rx error: %d buffers out of %d missing\n",
375 dev->name, num_buf, 369 dev->name, num_buf,
376 virtio16_to_cpu(rq->vq->vdev, 370 virtio16_to_cpu(vi->vdev,
377 hdr->mhdr.num_buffers)); 371 hdr->num_buffers));
378 dev->stats.rx_length_errors++; 372 dev->stats.rx_length_errors++;
379 goto err_buf; 373 goto err_buf;
380 } 374 }
@@ -441,7 +435,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
441 struct net_device *dev = vi->dev; 435 struct net_device *dev = vi->dev;
442 struct virtnet_stats *stats = this_cpu_ptr(vi->stats); 436 struct virtnet_stats *stats = this_cpu_ptr(vi->stats);
443 struct sk_buff *skb; 437 struct sk_buff *skb;
444 struct skb_vnet_hdr *hdr; 438 struct virtio_net_hdr_mrg_rxbuf *hdr;
445 439
446 if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) { 440 if (unlikely(len < sizeof(struct virtio_net_hdr) + ETH_HLEN)) {
447 pr_debug("%s: short packet %i\n", dev->name, len); 441 pr_debug("%s: short packet %i\n", dev->name, len);
@@ -463,7 +457,7 @@ static void receive_buf(struct virtnet_info *vi, struct receive_queue *rq,
463 else if (vi->big_packets) 457 else if (vi->big_packets)
464 skb = receive_big(dev, vi, rq, buf, len); 458 skb = receive_big(dev, vi, rq, buf, len);
465 else 459 else
466 skb = receive_small(buf, len); 460 skb = receive_small(vi, buf, len);
467 461
468 if (unlikely(!skb)) 462 if (unlikely(!skb))
469 return; 463 return;
@@ -545,7 +539,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
545 gfp_t gfp) 539 gfp_t gfp)
546{ 540{
547 struct sk_buff *skb; 541 struct sk_buff *skb;
548 struct skb_vnet_hdr *hdr; 542 struct virtio_net_hdr_mrg_rxbuf *hdr;
549 int err; 543 int err;
550 544
551 skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp); 545 skb = __netdev_alloc_skb_ip_align(vi->dev, GOOD_PACKET_LEN, gfp);
@@ -556,7 +550,7 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
556 550
557 hdr = skb_vnet_hdr(skb); 551 hdr = skb_vnet_hdr(skb);
558 sg_init_table(rq->sg, MAX_SKB_FRAGS + 2); 552 sg_init_table(rq->sg, MAX_SKB_FRAGS + 2);
559 sg_set_buf(rq->sg, &hdr->hdr, sizeof hdr->hdr); 553 sg_set_buf(rq->sg, hdr, vi->hdr_len);
560 skb_to_sgvec(skb, rq->sg + 1, 0, skb->len); 554 skb_to_sgvec(skb, rq->sg + 1, 0, skb->len);
561 555
562 err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp); 556 err = virtqueue_add_inbuf(rq->vq, rq->sg, 2, skb, gfp);
@@ -566,7 +560,8 @@ static int add_recvbuf_small(struct virtnet_info *vi, struct receive_queue *rq,
566 return err; 560 return err;
567} 561}
568 562
569static int add_recvbuf_big(struct receive_queue *rq, gfp_t gfp) 563static int add_recvbuf_big(struct virtnet_info *vi, struct receive_queue *rq,
564 gfp_t gfp)
570{ 565{
571 struct page *first, *list = NULL; 566 struct page *first, *list = NULL;
572 char *p; 567 char *p;
@@ -597,8 +592,8 @@ static int add_recvbuf_big(struct receive_queue *rq, gfp_t gfp)
597 p = page_address(first); 592 p = page_address(first);
598 593
599 /* rq->sg[0], rq->sg[1] share the same page */ 594 /* rq->sg[0], rq->sg[1] share the same page */
600 /* a separated rq->sg[0] for virtio_net_hdr only due to QEMU bug */ 595 /* a separated rq->sg[0] for header - required in case !any_header_sg */
601 sg_set_buf(&rq->sg[0], p, sizeof(struct virtio_net_hdr)); 596 sg_set_buf(&rq->sg[0], p, vi->hdr_len);
602 597
603 /* rq->sg[1] for data packet, from offset */ 598 /* rq->sg[1] for data packet, from offset */
604 offset = sizeof(struct padded_vnet_hdr); 599 offset = sizeof(struct padded_vnet_hdr);
@@ -677,7 +672,7 @@ static bool try_fill_recv(struct virtnet_info *vi, struct receive_queue *rq,
677 if (vi->mergeable_rx_bufs) 672 if (vi->mergeable_rx_bufs)
678 err = add_recvbuf_mergeable(rq, gfp); 673 err = add_recvbuf_mergeable(rq, gfp);
679 else if (vi->big_packets) 674 else if (vi->big_packets)
680 err = add_recvbuf_big(rq, gfp); 675 err = add_recvbuf_big(vi, rq, gfp);
681 else 676 else
682 err = add_recvbuf_small(vi, rq, gfp); 677 err = add_recvbuf_small(vi, rq, gfp);
683 678
@@ -857,18 +852,14 @@ static void free_old_xmit_skbs(struct send_queue *sq)
857 852
858static int xmit_skb(struct send_queue *sq, struct sk_buff *skb) 853static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
859{ 854{
860 struct skb_vnet_hdr *hdr; 855 struct virtio_net_hdr_mrg_rxbuf *hdr;
861 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest; 856 const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
862 struct virtnet_info *vi = sq->vq->vdev->priv; 857 struct virtnet_info *vi = sq->vq->vdev->priv;
863 unsigned num_sg; 858 unsigned num_sg;
864 unsigned hdr_len; 859 unsigned hdr_len = vi->hdr_len;
865 bool can_push; 860 bool can_push;
866 861
867 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest); 862 pr_debug("%s: xmit %p %pM\n", vi->dev->name, skb, dest);
868 if (vi->mergeable_rx_bufs)
869 hdr_len = sizeof hdr->mhdr;
870 else
871 hdr_len = sizeof hdr->hdr;
872 863
873 can_push = vi->any_header_sg && 864 can_push = vi->any_header_sg &&
874 !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) && 865 !((unsigned long)skb->data & (__alignof__(*hdr) - 1)) &&
@@ -876,7 +867,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
876 /* Even if we can, don't push here yet as this would skew 867 /* Even if we can, don't push here yet as this would skew
877 * csum_start offset below. */ 868 * csum_start offset below. */
878 if (can_push) 869 if (can_push)
879 hdr = (struct skb_vnet_hdr *)(skb->data - hdr_len); 870 hdr = (struct virtio_net_hdr_mrg_rxbuf *)(skb->data - hdr_len);
880 else 871 else
881 hdr = skb_vnet_hdr(skb); 872 hdr = skb_vnet_hdr(skb);
882 873
@@ -909,7 +900,7 @@ static int xmit_skb(struct send_queue *sq, struct sk_buff *skb)
909 } 900 }
910 901
911 if (vi->mergeable_rx_bufs) 902 if (vi->mergeable_rx_bufs)
912 hdr->mhdr.num_buffers = 0; 903 hdr->num_buffers = 0;
913 904
914 sg_init_table(sq->sg, MAX_SKB_FRAGS + 2); 905 sg_init_table(sq->sg, MAX_SKB_FRAGS + 2);
915 if (can_push) { 906 if (can_push) {
@@ -1814,18 +1805,19 @@ static int virtnet_probe(struct virtio_device *vdev)
1814 if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF)) 1805 if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
1815 vi->mergeable_rx_bufs = true; 1806 vi->mergeable_rx_bufs = true;
1816 1807
1808 if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
1809 vi->hdr_len = sizeof(struct virtio_net_hdr_mrg_rxbuf);
1810 else
1811 vi->hdr_len = sizeof(struct virtio_net_hdr);
1812
1817 if (virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT)) 1813 if (virtio_has_feature(vdev, VIRTIO_F_ANY_LAYOUT))
1818 vi->any_header_sg = true; 1814 vi->any_header_sg = true;
1819 1815
1820 if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ)) 1816 if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
1821 vi->has_cvq = true; 1817 vi->has_cvq = true;
1822 1818
1823 if (vi->any_header_sg) { 1819 if (vi->any_header_sg)
1824 if (vi->mergeable_rx_bufs) 1820 dev->needed_headroom = vi->hdr_len;
1825 dev->needed_headroom = sizeof(struct virtio_net_hdr_mrg_rxbuf);
1826 else
1827 dev->needed_headroom = sizeof(struct virtio_net_hdr);
1828 }
1829 1821
1830 /* Use single tx/rx queue pair as default */ 1822 /* Use single tx/rx queue pair as default */
1831 vi->curr_queue_pairs = 1; 1823 vi->curr_queue_pairs = 1;