virtio_net.c (f1d4884d6871ded0592604b0e72e4a7bd292eab9) | virtio_net.c (503d539a6e417b018616bf3060e0b5814fafce47) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* A network driver using virtio. 3 * 4 * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 5 */ 6//#define DEBUG 7#include <linux/netdevice.h> 8#include <linux/etherdevice.h> --- 357 unchanged lines hidden (view full) --- 366 return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1); 367} 368 369/* Called from bottom half context */ 370static struct sk_buff *page_to_skb(struct virtnet_info *vi, 371 struct receive_queue *rq, 372 struct page *page, unsigned int offset, 373 unsigned int len, unsigned int truesize, | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* A network driver using virtio. 3 * 4 * Copyright 2007 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation 5 */ 6//#define DEBUG 7#include <linux/netdevice.h> 8#include <linux/etherdevice.h> --- 357 unchanged lines hidden (view full) --- 366 return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1); 367} 368 369/* Called from bottom half context */ 370static struct sk_buff *page_to_skb(struct virtnet_info *vi, 371 struct receive_queue *rq, 372 struct page *page, unsigned int offset, 373 unsigned int len, unsigned int truesize, |
374 bool hdr_valid) | 374 bool hdr_valid, unsigned int metasize) |
375{ 376 struct sk_buff *skb; 377 struct virtio_net_hdr_mrg_rxbuf *hdr; 378 unsigned int copy, hdr_len, hdr_padded_len; 379 char *p; 380 381 p = page_address(page) + offset; 382 --- 5 unchanged lines hidden (view full) --- 388 hdr = skb_vnet_hdr(skb); 389 390 hdr_len = vi->hdr_len; 391 if (vi->mergeable_rx_bufs) 392 hdr_padded_len = sizeof(*hdr); 393 else 394 hdr_padded_len = sizeof(struct padded_vnet_hdr); 395 | 375{ 376 struct sk_buff *skb; 377 struct virtio_net_hdr_mrg_rxbuf *hdr; 378 unsigned int copy, hdr_len, hdr_padded_len; 379 char *p; 380 381 p = page_address(page) + offset; 382 --- 5 unchanged lines hidden (view full) --- 388 hdr = skb_vnet_hdr(skb); 389 390 hdr_len = vi->hdr_len; 391 if (vi->mergeable_rx_bufs) 392 hdr_padded_len = sizeof(*hdr); 393 else 394 hdr_padded_len = sizeof(struct padded_vnet_hdr); 395 |
396 /* hdr_valid means no XDP, so we can copy the vnet header */ |
|
396 if (hdr_valid) 397 memcpy(hdr, p, hdr_len); 398 399 len -= hdr_len; 400 offset += hdr_padded_len; 401 p += hdr_padded_len; 402 403 copy = len; 404 if (copy > skb_tailroom(skb)) 405 copy = skb_tailroom(skb); 406 skb_put_data(skb, p, copy); 407 | 397 if (hdr_valid) 398 memcpy(hdr, p, hdr_len); 399 400 len -= hdr_len; 401 offset += hdr_padded_len; 402 p += hdr_padded_len; 403 404 copy = len; 405 if (copy > skb_tailroom(skb)) 406 copy = skb_tailroom(skb); 407 skb_put_data(skb, p, copy); 408 |
409 if (metasize) { 410 __skb_pull(skb, metasize); 411 skb_metadata_set(skb, metasize); 412 } 413 |
|
408 len -= copy; 409 offset += copy; 410 411 if (vi->mergeable_rx_bufs) { 412 if (len) 413 skb_add_rx_frag(skb, 0, page, offset, len, truesize); 414 else 415 put_page(page); --- 29 unchanged lines hidden (view full) --- 445 446static int __virtnet_xdp_xmit_one(struct virtnet_info *vi, 447 struct send_queue *sq, 448 struct xdp_frame *xdpf) 449{ 450 struct virtio_net_hdr_mrg_rxbuf *hdr; 451 int err; 452 | 414 len -= copy; 415 offset += copy; 416 417 if (vi->mergeable_rx_bufs) { 418 if (len) 419 skb_add_rx_frag(skb, 0, page, offset, len, truesize); 420 else 421 put_page(page); --- 29 unchanged lines hidden (view full) --- 451 452static int __virtnet_xdp_xmit_one(struct virtnet_info *vi, 453 struct send_queue *sq, 454 struct xdp_frame *xdpf) 455{ 456 struct virtio_net_hdr_mrg_rxbuf *hdr; 457 int err; 458 |
453 /* virtqueue want to use data area in-front of packet */ 454 if (unlikely(xdpf->metasize > 0)) 455 return -EOPNOTSUPP; 456 | |
457 if (unlikely(xdpf->headroom < vi->hdr_len)) 458 return -EOVERFLOW; 459 460 /* Make room for virtqueue hdr (also change xdpf->headroom?) */ 461 xdpf->data -= vi->hdr_len; 462 /* Zero header and leave csum up to XDP layers */ 463 hdr = xdpf->data; 464 memset(hdr, 0, vi->hdr_len); --- 174 unchanged lines hidden (view full) --- 639 unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom; 640 unsigned int headroom = vi->hdr_len + header_offset; 641 unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + 642 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 643 struct page *page = virt_to_head_page(buf); 644 unsigned int delta = 0; 645 struct page *xdp_page; 646 int err; | 459 if (unlikely(xdpf->headroom < vi->hdr_len)) 460 return -EOVERFLOW; 461 462 /* Make room for virtqueue hdr (also change xdpf->headroom?) */ 463 xdpf->data -= vi->hdr_len; 464 /* Zero header and leave csum up to XDP layers */ 465 hdr = xdpf->data; 466 memset(hdr, 0, vi->hdr_len); --- 174 unchanged lines hidden (view full) --- 641 unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom; 642 unsigned int headroom = vi->hdr_len + header_offset; 643 unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) + 644 SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); 645 struct page *page = virt_to_head_page(buf); 646 unsigned int delta = 0; 647 struct page *xdp_page; 648 int err; |
649 unsigned int metasize = 0; |
|
647 648 len -= vi->hdr_len; 649 stats->bytes += len; 650 651 rcu_read_lock(); 652 xdp_prog = rcu_dereference(rq->xdp_prog); 653 if (xdp_prog) { 654 struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset; --- 23 unchanged lines hidden (view full) --- 678 679 buf = page_address(xdp_page); 680 put_page(page); 681 page = xdp_page; 682 } 683 684 xdp.data_hard_start = buf + VIRTNET_RX_PAD + vi->hdr_len; 685 xdp.data = xdp.data_hard_start + xdp_headroom; | 650 651 len -= vi->hdr_len; 652 stats->bytes += len; 653 654 rcu_read_lock(); 655 xdp_prog = rcu_dereference(rq->xdp_prog); 656 if (xdp_prog) { 657 struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset; --- 23 unchanged lines hidden (view full) --- 681 682 buf = page_address(xdp_page); 683 put_page(page); 684 page = xdp_page; 685 } 686 687 xdp.data_hard_start = buf + VIRTNET_RX_PAD + vi->hdr_len; 688 xdp.data = xdp.data_hard_start + xdp_headroom; |
686 xdp_set_data_meta_invalid(&xdp); | |
687 xdp.data_end = xdp.data + len; | 689 xdp.data_end = xdp.data + len; |
690 xdp.data_meta = xdp.data; |
|
688 xdp.rxq = &rq->xdp_rxq; 689 orig_data = xdp.data; 690 act = bpf_prog_run_xdp(xdp_prog, &xdp); 691 stats->xdp_packets++; 692 693 switch (act) { 694 case XDP_PASS: 695 /* Recalculate length in case bpf program changed it */ 696 delta = orig_data - xdp.data; 697 len = xdp.data_end - xdp.data; | 691 xdp.rxq = &rq->xdp_rxq; 692 orig_data = xdp.data; 693 act = bpf_prog_run_xdp(xdp_prog, &xdp); 694 stats->xdp_packets++; 695 696 switch (act) { 697 case XDP_PASS: 698 /* Recalculate length in case bpf program changed it */ 699 delta = orig_data - xdp.data; 700 len = xdp.data_end - xdp.data; |
701 metasize = xdp.data - xdp.data_meta; |
|
698 break; 699 case XDP_TX: 700 stats->xdp_tx++; 701 xdpf = convert_to_xdp_frame(&xdp); 702 if (unlikely(!xdpf)) 703 goto err_xdp; 704 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0); 705 if (unlikely(err < 0)) { --- 29 unchanged lines hidden (view full) --- 735 } 736 skb_reserve(skb, headroom - delta); 737 skb_put(skb, len); 738 if (!xdp_prog) { 739 buf += header_offset; 740 memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len); 741 } /* keep zeroed vnet hdr since XDP is loaded */ 742 | 702 break; 703 case XDP_TX: 704 stats->xdp_tx++; 705 xdpf = convert_to_xdp_frame(&xdp); 706 if (unlikely(!xdpf)) 707 goto err_xdp; 708 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0); 709 if (unlikely(err < 0)) { --- 29 unchanged lines hidden (view full) --- 739 } 740 skb_reserve(skb, headroom - delta); 741 skb_put(skb, len); 742 if (!xdp_prog) { 743 buf += header_offset; 744 memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len); 745 } /* keep zeroed vnet hdr since XDP is loaded */ 746 |
747 if (metasize) 748 skb_metadata_set(skb, metasize); 749 |
|
743err: 744 return skb; 745 746err_xdp: 747 rcu_read_unlock(); 748 stats->xdp_drops++; 749 stats->drops++; 750 put_page(page); --- 4 unchanged lines hidden (view full) --- 755static struct sk_buff *receive_big(struct net_device *dev, 756 struct virtnet_info *vi, 757 struct receive_queue *rq, 758 void *buf, 759 unsigned int len, 760 struct virtnet_rq_stats *stats) 761{ 762 struct page *page = buf; | 750err: 751 return skb; 752 753err_xdp: 754 rcu_read_unlock(); 755 stats->xdp_drops++; 756 stats->drops++; 757 put_page(page); --- 4 unchanged lines hidden (view full) --- 762static struct sk_buff *receive_big(struct net_device *dev, 763 struct virtnet_info *vi, 764 struct receive_queue *rq, 765 void *buf, 766 unsigned int len, 767 struct virtnet_rq_stats *stats) 768{ 769 struct page *page = buf; |
763 struct sk_buff *skb = page_to_skb(vi, rq, page, 0, len, 764 PAGE_SIZE, true); | 770 struct sk_buff *skb = 771 page_to_skb(vi, rq, page, 0, len, PAGE_SIZE, true, 0); |
765 766 stats->bytes += len - vi->hdr_len; 767 if (unlikely(!skb)) 768 goto err; 769 770 return skb; 771 772err: --- 15 unchanged lines hidden (view full) --- 788 u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers); 789 struct page *page = virt_to_head_page(buf); 790 int offset = buf - page_address(page); 791 struct sk_buff *head_skb, *curr_skb; 792 struct bpf_prog *xdp_prog; 793 unsigned int truesize; 794 unsigned int headroom = mergeable_ctx_to_headroom(ctx); 795 int err; | 772 773 stats->bytes += len - vi->hdr_len; 774 if (unlikely(!skb)) 775 goto err; 776 777 return skb; 778 779err: --- 15 unchanged lines hidden (view full) --- 795 u16 num_buf = virtio16_to_cpu(vi->vdev, hdr->num_buffers); 796 struct page *page = virt_to_head_page(buf); 797 int offset = buf - page_address(page); 798 struct sk_buff *head_skb, *curr_skb; 799 struct bpf_prog *xdp_prog; 800 unsigned int truesize; 801 unsigned int headroom = mergeable_ctx_to_headroom(ctx); 802 int err; |
803 unsigned int metasize = 0; |
|
796 797 head_skb = NULL; 798 stats->bytes += len - vi->hdr_len; 799 800 rcu_read_lock(); 801 xdp_prog = rcu_dereference(rq->xdp_prog); 802 if (xdp_prog) { 803 struct xdp_frame *xdpf; --- 30 unchanged lines hidden (view full) --- 834 } 835 836 /* Allow consuming headroom but reserve enough space to push 837 * the descriptor on if we get an XDP_TX return code. 838 */ 839 data = page_address(xdp_page) + offset; 840 xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM + vi->hdr_len; 841 xdp.data = data + vi->hdr_len; | 804 805 head_skb = NULL; 806 stats->bytes += len - vi->hdr_len; 807 808 rcu_read_lock(); 809 xdp_prog = rcu_dereference(rq->xdp_prog); 810 if (xdp_prog) { 811 struct xdp_frame *xdpf; --- 30 unchanged lines hidden (view full) --- 842 } 843 844 /* Allow consuming headroom but reserve enough space to push 845 * the descriptor on if we get an XDP_TX return code. 846 */ 847 data = page_address(xdp_page) + offset; 848 xdp.data_hard_start = data - VIRTIO_XDP_HEADROOM + vi->hdr_len; 849 xdp.data = data + vi->hdr_len; |
842 xdp_set_data_meta_invalid(&xdp); | |
843 xdp.data_end = xdp.data + (len - vi->hdr_len); | 850 xdp.data_end = xdp.data + (len - vi->hdr_len); |
851 xdp.data_meta = xdp.data; |
|
844 xdp.rxq = &rq->xdp_rxq; 845 846 act = bpf_prog_run_xdp(xdp_prog, &xdp); 847 stats->xdp_packets++; 848 849 switch (act) { 850 case XDP_PASS: | 852 xdp.rxq = &rq->xdp_rxq; 853 854 act = bpf_prog_run_xdp(xdp_prog, &xdp); 855 stats->xdp_packets++; 856 857 switch (act) { 858 case XDP_PASS: |
859 metasize = xdp.data - xdp.data_meta; 860 |
|
851 /* recalculate offset to account for any header | 861 /* recalculate offset to account for any header |
852 * adjustments. Note other cases do not build an 853 * skb and avoid using offset | 862 * adjustments and minus the metasize to copy the 863 * metadata in page_to_skb(). Note other cases do not 864 * build an skb and avoid using offset |
854 */ | 865 */ |
855 offset = xdp.data - 856 page_address(xdp_page) - vi->hdr_len; | 866 offset = xdp.data - page_address(xdp_page) - 867 vi->hdr_len - metasize; |
857 | 868 |
858 /* recalculate len if xdp.data or xdp.data_end were 859 * adjusted | 869 /* recalculate len if xdp.data, xdp.data_end or 870 * xdp.data_meta were adjusted |
860 */ | 871 */ |
861 len = xdp.data_end - xdp.data + vi->hdr_len; | 872 len = xdp.data_end - xdp.data + vi->hdr_len + metasize; |
862 /* We can only create skb based on xdp_page. */ 863 if (unlikely(xdp_page != page)) { 864 rcu_read_unlock(); 865 put_page(page); | 873 /* We can only create skb based on xdp_page. */ 874 if (unlikely(xdp_page != page)) { 875 rcu_read_unlock(); 876 put_page(page); |
866 head_skb = page_to_skb(vi, rq, xdp_page, 867 offset, len, 868 PAGE_SIZE, false); | 877 head_skb = page_to_skb(vi, rq, xdp_page, offset, 878 len, PAGE_SIZE, false, 879 metasize); |
869 return head_skb; 870 } 871 break; 872 case XDP_TX: 873 stats->xdp_tx++; 874 xdpf = convert_to_xdp_frame(&xdp); 875 if (unlikely(!xdpf)) 876 goto err_xdp; --- 39 unchanged lines hidden (view full) --- 916 truesize = mergeable_ctx_to_truesize(ctx); 917 if (unlikely(len > truesize)) { 918 pr_debug("%s: rx error: len %u exceeds truesize %lu\n", 919 dev->name, len, (unsigned long)ctx); 920 dev->stats.rx_length_errors++; 921 goto err_skb; 922 } 923 | 880 return head_skb; 881 } 882 break; 883 case XDP_TX: 884 stats->xdp_tx++; 885 xdpf = convert_to_xdp_frame(&xdp); 886 if (unlikely(!xdpf)) 887 goto err_xdp; --- 39 unchanged lines hidden (view full) --- 927 truesize = mergeable_ctx_to_truesize(ctx); 928 if (unlikely(len > truesize)) { 929 pr_debug("%s: rx error: len %u exceeds truesize %lu\n", 930 dev->name, len, (unsigned long)ctx); 931 dev->stats.rx_length_errors++; 932 goto err_skb; 933 } 934 |
924 head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog); | 935 head_skb = page_to_skb(vi, rq, page, offset, len, truesize, !xdp_prog, 936 metasize); |
925 curr_skb = head_skb; 926 927 if (unlikely(!curr_skb)) 928 goto err_skb; 929 while (--num_buf) { 930 int num_skb_frags; 931 932 buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx); --- 2413 unchanged lines hidden --- | 937 curr_skb = head_skb; 938 939 if (unlikely(!curr_skb)) 940 goto err_skb; 941 while (--num_buf) { 942 int num_skb_frags; 943 944 buf = virtqueue_get_buf_ctx(rq->vq, &len, &ctx); --- 2413 unchanged lines hidden --- |