diff options
Diffstat (limited to 'drivers/net')
| -rw-r--r-- | drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 24 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/emulex/benet/be_main.c | 14 | ||||
| -rw-r--r-- | drivers/net/ethernet/mellanox/mlx5/core/debugfs.c | 2 | ||||
| -rw-r--r-- | drivers/net/hyperv/netvsc_drv.c | 4 | ||||
| -rw-r--r-- | drivers/net/macvtap.c | 65 | ||||
| -rw-r--r-- | drivers/net/tun.c | 62 | ||||
| -rw-r--r-- | drivers/net/vxlan.c | 6 | ||||
| -rw-r--r-- | drivers/net/xen-netfront.c | 31 |
9 files changed, 133 insertions, 76 deletions
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 6d1a62a84c9d..1966444590f6 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c | |||
| @@ -1678,6 +1678,7 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, | |||
| 1678 | u16 f; | 1678 | u16 f; |
| 1679 | int segment; | 1679 | int segment; |
| 1680 | int ring_start = adapter->tx_ring.next_to_use; | 1680 | int ring_start = adapter->tx_ring.next_to_use; |
| 1681 | int ring_end; | ||
| 1681 | 1682 | ||
| 1682 | nr_frags = skb_shinfo(skb)->nr_frags; | 1683 | nr_frags = skb_shinfo(skb)->nr_frags; |
| 1683 | segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; | 1684 | segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; |
| @@ -1721,6 +1722,15 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, | |||
| 1721 | map_len, PCI_DMA_TODEVICE); | 1722 | map_len, PCI_DMA_TODEVICE); |
| 1722 | 1723 | ||
| 1723 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { | 1724 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { |
| 1725 | /* We need to unwind the mappings we've done */ | ||
| 1726 | ring_end = adapter->tx_ring.next_to_use; | ||
| 1727 | adapter->tx_ring.next_to_use = ring_start; | ||
| 1728 | while (adapter->tx_ring.next_to_use != ring_end) { | ||
| 1729 | tpd = atl1e_get_tpd(adapter); | ||
| 1730 | tx_buffer = atl1e_get_tx_buffer(adapter, tpd); | ||
| 1731 | pci_unmap_single(adapter->pdev, tx_buffer->dma, | ||
| 1732 | tx_buffer->length, PCI_DMA_TODEVICE); | ||
| 1733 | } | ||
| 1724 | /* Reset the tx rings next pointer */ | 1734 | /* Reset the tx rings next pointer */ |
| 1725 | adapter->tx_ring.next_to_use = ring_start; | 1735 | adapter->tx_ring.next_to_use = ring_start; |
| 1726 | return -ENOSPC; | 1736 | return -ENOSPC; |
| @@ -1763,6 +1773,16 @@ static int atl1e_tx_map(struct atl1e_adapter *adapter, | |||
| 1763 | DMA_TO_DEVICE); | 1773 | DMA_TO_DEVICE); |
| 1764 | 1774 | ||
| 1765 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { | 1775 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { |
| 1776 | /* We need to unwind the mappings we've done */ | ||
| 1777 | ring_end = adapter->tx_ring.next_to_use; | ||
| 1778 | adapter->tx_ring.next_to_use = ring_start; | ||
| 1779 | while (adapter->tx_ring.next_to_use != ring_end) { | ||
| 1780 | tpd = atl1e_get_tpd(adapter); | ||
| 1781 | tx_buffer = atl1e_get_tx_buffer(adapter, tpd); | ||
| 1782 | dma_unmap_page(&adapter->pdev->dev, tx_buffer->dma, | ||
| 1783 | tx_buffer->length, DMA_TO_DEVICE); | ||
| 1784 | } | ||
| 1785 | |||
| 1766 | /* Reset the ring next to use pointer */ | 1786 | /* Reset the ring next to use pointer */ |
| 1767 | adapter->tx_ring.next_to_use = ring_start; | 1787 | adapter->tx_ring.next_to_use = ring_start; |
| 1768 | return -ENOSPC; | 1788 | return -ENOSPC; |
| @@ -1853,8 +1873,10 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, | |||
| 1853 | return NETDEV_TX_OK; | 1873 | return NETDEV_TX_OK; |
| 1854 | } | 1874 | } |
| 1855 | 1875 | ||
| 1856 | if (atl1e_tx_map(adapter, skb, tpd)) | 1876 | if (atl1e_tx_map(adapter, skb, tpd)) { |
| 1877 | dev_kfree_skb_any(skb); | ||
| 1857 | goto out; | 1878 | goto out; |
| 1879 | } | ||
| 1858 | 1880 | ||
| 1859 | atl1e_tx_queue(adapter, tpd_req, tpd); | 1881 | atl1e_tx_queue(adapter, tpd_req, tpd); |
| 1860 | 1882 | ||
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig index 1d680baf43d6..52c96036dcc4 100644 --- a/drivers/net/ethernet/broadcom/Kconfig +++ b/drivers/net/ethernet/broadcom/Kconfig | |||
| @@ -131,6 +131,7 @@ config BNX2X_SRIOV | |||
| 131 | config BGMAC | 131 | config BGMAC |
| 132 | tristate "BCMA bus GBit core support" | 132 | tristate "BCMA bus GBit core support" |
| 133 | depends on BCMA_HOST_SOC && HAS_DMA | 133 | depends on BCMA_HOST_SOC && HAS_DMA |
| 134 | select PHYLIB | ||
| 134 | ---help--- | 135 | ---help--- |
| 135 | This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. | 136 | This driver supports GBit MAC and BCM4706 GBit MAC cores on BCMA bus. |
| 136 | They can be found on BCM47xx SoCs and provide gigabit ethernet. | 137 | They can be found on BCM47xx SoCs and provide gigabit ethernet. |
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 2df48bb0f1ca..181edb522450 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c | |||
| @@ -782,16 +782,22 @@ static struct sk_buff *be_insert_vlan_in_pkt(struct be_adapter *adapter, | |||
| 782 | 782 | ||
| 783 | if (vlan_tx_tag_present(skb)) | 783 | if (vlan_tx_tag_present(skb)) |
| 784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); | 784 | vlan_tag = be_get_tx_vlan_tag(adapter, skb); |
| 785 | else if (qnq_async_evt_rcvd(adapter) && adapter->pvid) | 785 | |
| 786 | vlan_tag = adapter->pvid; | 786 | if (qnq_async_evt_rcvd(adapter) && adapter->pvid) { |
| 787 | if (!vlan_tag) | ||
| 788 | vlan_tag = adapter->pvid; | ||
| 789 | /* f/w workaround to set skip_hw_vlan = 1, informs the F/W to | ||
| 790 | * skip VLAN insertion | ||
| 791 | */ | ||
| 792 | if (skip_hw_vlan) | ||
| 793 | *skip_hw_vlan = true; | ||
| 794 | } | ||
| 787 | 795 | ||
| 788 | if (vlan_tag) { | 796 | if (vlan_tag) { |
| 789 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); | 797 | skb = __vlan_put_tag(skb, htons(ETH_P_8021Q), vlan_tag); |
| 790 | if (unlikely(!skb)) | 798 | if (unlikely(!skb)) |
| 791 | return skb; | 799 | return skb; |
| 792 | skb->vlan_tci = 0; | 800 | skb->vlan_tci = 0; |
| 793 | if (skip_hw_vlan) | ||
| 794 | *skip_hw_vlan = true; | ||
| 795 | } | 801 | } |
| 796 | 802 | ||
| 797 | /* Insert the outer VLAN, if any */ | 803 | /* Insert the outer VLAN, if any */ |
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c index 4273c06e2e96..9c7194b26ee2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/debugfs.c | |||
| @@ -156,7 +156,7 @@ static ssize_t average_read(struct file *filp, char __user *buf, size_t count, | |||
| 156 | stats = filp->private_data; | 156 | stats = filp->private_data; |
| 157 | spin_lock(&stats->lock); | 157 | spin_lock(&stats->lock); |
| 158 | if (stats->n) | 158 | if (stats->n) |
| 159 | field = stats->sum / stats->n; | 159 | field = div64_u64(stats->sum, stats->n); |
| 160 | spin_unlock(&stats->lock); | 160 | spin_unlock(&stats->lock); |
| 161 | ret = snprintf(tbuf, sizeof(tbuf), "%llu\n", field); | 161 | ret = snprintf(tbuf, sizeof(tbuf), "%llu\n", field); |
| 162 | if (ret > 0) { | 162 | if (ret > 0) { |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 4dccead586be..23a0fff0df52 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -431,8 +431,8 @@ static int netvsc_probe(struct hv_device *dev, | |||
| 431 | net->netdev_ops = &device_ops; | 431 | net->netdev_ops = &device_ops; |
| 432 | 432 | ||
| 433 | /* TODO: Add GSO and Checksum offload */ | 433 | /* TODO: Add GSO and Checksum offload */ |
| 434 | net->hw_features = NETIF_F_SG; | 434 | net->hw_features = 0; |
| 435 | net->features = NETIF_F_SG | NETIF_F_HW_VLAN_CTAG_TX; | 435 | net->features = NETIF_F_HW_VLAN_CTAG_TX; |
| 436 | 436 | ||
| 437 | SET_ETHTOOL_OPS(net, ðtool_ops); | 437 | SET_ETHTOOL_OPS(net, ðtool_ops); |
| 438 | SET_NETDEV_DEV(net, &dev->device); | 438 | SET_NETDEV_DEV(net, &dev->device); |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 876c72246ae9..a98fb0ed6aef 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
| @@ -698,6 +698,28 @@ static int macvtap_skb_to_vnet_hdr(const struct sk_buff *skb, | |||
| 698 | return 0; | 698 | return 0; |
| 699 | } | 699 | } |
| 700 | 700 | ||
| 701 | static unsigned long iov_pages(const struct iovec *iv, int offset, | ||
| 702 | unsigned long nr_segs) | ||
| 703 | { | ||
| 704 | unsigned long seg, base; | ||
| 705 | int pages = 0, len, size; | ||
| 706 | |||
| 707 | while (nr_segs && (offset >= iv->iov_len)) { | ||
| 708 | offset -= iv->iov_len; | ||
| 709 | ++iv; | ||
| 710 | --nr_segs; | ||
| 711 | } | ||
| 712 | |||
| 713 | for (seg = 0; seg < nr_segs; seg++) { | ||
| 714 | base = (unsigned long)iv[seg].iov_base + offset; | ||
| 715 | len = iv[seg].iov_len - offset; | ||
| 716 | size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; | ||
| 717 | pages += size; | ||
| 718 | offset = 0; | ||
| 719 | } | ||
| 720 | |||
| 721 | return pages; | ||
| 722 | } | ||
| 701 | 723 | ||
| 702 | /* Get packet from user space buffer */ | 724 | /* Get packet from user space buffer */ |
| 703 | static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | 725 | static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, |
| @@ -744,31 +766,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
| 744 | if (unlikely(count > UIO_MAXIOV)) | 766 | if (unlikely(count > UIO_MAXIOV)) |
| 745 | goto err; | 767 | goto err; |
| 746 | 768 | ||
| 747 | if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) | 769 | if (m && m->msg_control && sock_flag(&q->sk, SOCK_ZEROCOPY)) { |
| 748 | zerocopy = true; | 770 | copylen = vnet_hdr.hdr_len ? vnet_hdr.hdr_len : GOODCOPY_LEN; |
| 749 | |||
| 750 | if (zerocopy) { | ||
| 751 | /* Userspace may produce vectors with count greater than | ||
| 752 | * MAX_SKB_FRAGS, so we need to linearize parts of the skb | ||
| 753 | * to let the rest of data to be fit in the frags. | ||
| 754 | */ | ||
| 755 | if (count > MAX_SKB_FRAGS) { | ||
| 756 | copylen = iov_length(iv, count - MAX_SKB_FRAGS); | ||
| 757 | if (copylen < vnet_hdr_len) | ||
| 758 | copylen = 0; | ||
| 759 | else | ||
| 760 | copylen -= vnet_hdr_len; | ||
| 761 | } | ||
| 762 | /* There are 256 bytes to be copied in skb, so there is enough | ||
| 763 | * room for skb expand head in case it is used. | ||
| 764 | * The rest buffer is mapped from userspace. | ||
| 765 | */ | ||
| 766 | if (copylen < vnet_hdr.hdr_len) | ||
| 767 | copylen = vnet_hdr.hdr_len; | ||
| 768 | if (!copylen) | ||
| 769 | copylen = GOODCOPY_LEN; | ||
| 770 | linear = copylen; | 771 | linear = copylen; |
| 771 | } else { | 772 | if (iov_pages(iv, vnet_hdr_len + copylen, count) |
| 773 | <= MAX_SKB_FRAGS) | ||
| 774 | zerocopy = true; | ||
| 775 | } | ||
| 776 | |||
| 777 | if (!zerocopy) { | ||
| 772 | copylen = len; | 778 | copylen = len; |
| 773 | linear = vnet_hdr.hdr_len; | 779 | linear = vnet_hdr.hdr_len; |
| 774 | } | 780 | } |
| @@ -780,9 +786,15 @@ static ssize_t macvtap_get_user(struct macvtap_queue *q, struct msghdr *m, | |||
| 780 | 786 | ||
| 781 | if (zerocopy) | 787 | if (zerocopy) |
| 782 | err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); | 788 | err = zerocopy_sg_from_iovec(skb, iv, vnet_hdr_len, count); |
| 783 | else | 789 | else { |
| 784 | err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, | 790 | err = skb_copy_datagram_from_iovec(skb, 0, iv, vnet_hdr_len, |
| 785 | len); | 791 | len); |
| 792 | if (!err && m && m->msg_control) { | ||
| 793 | struct ubuf_info *uarg = m->msg_control; | ||
| 794 | uarg->callback(uarg, false); | ||
| 795 | } | ||
| 796 | } | ||
| 797 | |||
| 786 | if (err) | 798 | if (err) |
| 787 | goto err_kfree; | 799 | goto err_kfree; |
| 788 | 800 | ||
| @@ -873,7 +885,7 @@ static ssize_t macvtap_put_user(struct macvtap_queue *q, | |||
| 873 | __be16 h_vlan_proto; | 885 | __be16 h_vlan_proto; |
| 874 | __be16 h_vlan_TCI; | 886 | __be16 h_vlan_TCI; |
| 875 | } veth; | 887 | } veth; |
| 876 | veth.h_vlan_proto = htons(ETH_P_8021Q); | 888 | veth.h_vlan_proto = skb->vlan_proto; |
| 877 | veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); | 889 | veth.h_vlan_TCI = htons(vlan_tx_tag_get(skb)); |
| 878 | 890 | ||
| 879 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); | 891 | vlan_offset = offsetof(struct vlan_ethhdr, h_vlan_proto); |
| @@ -1107,6 +1119,7 @@ static long macvtap_ioctl(struct file *file, unsigned int cmd, | |||
| 1107 | rtnl_lock(); | 1119 | rtnl_lock(); |
| 1108 | ret = macvtap_ioctl_set_queue(file, u); | 1120 | ret = macvtap_ioctl_set_queue(file, u); |
| 1109 | rtnl_unlock(); | 1121 | rtnl_unlock(); |
| 1122 | return ret; | ||
| 1110 | 1123 | ||
| 1111 | case TUNGETFEATURES: | 1124 | case TUNGETFEATURES: |
| 1112 | if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR | | 1125 | if (put_user(IFF_TAP | IFF_NO_PI | IFF_VNET_HDR | |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 5cdcf92eb310..db690a372260 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -1035,6 +1035,29 @@ static int zerocopy_sg_from_iovec(struct sk_buff *skb, const struct iovec *from, | |||
| 1035 | return 0; | 1035 | return 0; |
| 1036 | } | 1036 | } |
| 1037 | 1037 | ||
| 1038 | static unsigned long iov_pages(const struct iovec *iv, int offset, | ||
| 1039 | unsigned long nr_segs) | ||
| 1040 | { | ||
| 1041 | unsigned long seg, base; | ||
| 1042 | int pages = 0, len, size; | ||
| 1043 | |||
| 1044 | while (nr_segs && (offset >= iv->iov_len)) { | ||
| 1045 | offset -= iv->iov_len; | ||
| 1046 | ++iv; | ||
| 1047 | --nr_segs; | ||
| 1048 | } | ||
| 1049 | |||
| 1050 | for (seg = 0; seg < nr_segs; seg++) { | ||
| 1051 | base = (unsigned long)iv[seg].iov_base + offset; | ||
| 1052 | len = iv[seg].iov_len - offset; | ||
| 1053 | size = ((base & ~PAGE_MASK) + len + ~PAGE_MASK) >> PAGE_SHIFT; | ||
| 1054 | pages += size; | ||
| 1055 | offset = 0; | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | return pages; | ||
| 1059 | } | ||
| 1060 | |||
| 1038 | /* Get packet from user space buffer */ | 1061 | /* Get packet from user space buffer */ |
| 1039 | static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | 1062 | static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, |
| 1040 | void *msg_control, const struct iovec *iv, | 1063 | void *msg_control, const struct iovec *iv, |
| @@ -1082,32 +1105,18 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
| 1082 | return -EINVAL; | 1105 | return -EINVAL; |
| 1083 | } | 1106 | } |
| 1084 | 1107 | ||
| 1085 | if (msg_control) | 1108 | if (msg_control) { |
| 1086 | zerocopy = true; | 1109 | /* There are 256 bytes to be copied in skb, so there is |
| 1087 | 1110 | * enough room for skb expand head in case it is used. | |
| 1088 | if (zerocopy) { | ||
| 1089 | /* Userspace may produce vectors with count greater than | ||
| 1090 | * MAX_SKB_FRAGS, so we need to linearize parts of the skb | ||
| 1091 | * to let the rest of data to be fit in the frags. | ||
| 1092 | */ | ||
| 1093 | if (count > MAX_SKB_FRAGS) { | ||
| 1094 | copylen = iov_length(iv, count - MAX_SKB_FRAGS); | ||
| 1095 | if (copylen < offset) | ||
| 1096 | copylen = 0; | ||
| 1097 | else | ||
| 1098 | copylen -= offset; | ||
| 1099 | } else | ||
| 1100 | copylen = 0; | ||
| 1101 | /* There are 256 bytes to be copied in skb, so there is enough | ||
| 1102 | * room for skb expand head in case it is used. | ||
| 1103 | * The rest of the buffer is mapped from userspace. | 1111 | * The rest of the buffer is mapped from userspace. |
| 1104 | */ | 1112 | */ |
| 1105 | if (copylen < gso.hdr_len) | 1113 | copylen = gso.hdr_len ? gso.hdr_len : GOODCOPY_LEN; |
| 1106 | copylen = gso.hdr_len; | ||
| 1107 | if (!copylen) | ||
| 1108 | copylen = GOODCOPY_LEN; | ||
| 1109 | linear = copylen; | 1114 | linear = copylen; |
| 1110 | } else { | 1115 | if (iov_pages(iv, offset + copylen, count) <= MAX_SKB_FRAGS) |
| 1116 | zerocopy = true; | ||
| 1117 | } | ||
| 1118 | |||
| 1119 | if (!zerocopy) { | ||
| 1111 | copylen = len; | 1120 | copylen = len; |
| 1112 | linear = gso.hdr_len; | 1121 | linear = gso.hdr_len; |
| 1113 | } | 1122 | } |
| @@ -1121,8 +1130,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile, | |||
| 1121 | 1130 | ||
| 1122 | if (zerocopy) | 1131 | if (zerocopy) |
| 1123 | err = zerocopy_sg_from_iovec(skb, iv, offset, count); | 1132 | err = zerocopy_sg_from_iovec(skb, iv, offset, count); |
| 1124 | else | 1133 | else { |
| 1125 | err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); | 1134 | err = skb_copy_datagram_from_iovec(skb, 0, iv, offset, len); |
| 1135 | if (!err && msg_control) { | ||
| 1136 | struct ubuf_info *uarg = msg_control; | ||
| 1137 | uarg->callback(uarg, false); | ||
| 1138 | } | ||
| 1139 | } | ||
| 1126 | 1140 | ||
| 1127 | if (err) { | 1141 | if (err) { |
| 1128 | tun->dev->stats.rx_dropped++; | 1142 | tun->dev->stats.rx_dropped++; |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 0ba1e7edbb1b..a5ba8dd7e6be 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
| @@ -1767,9 +1767,15 @@ static int vxlan_newlink(struct net *net, struct net_device *dev, | |||
| 1767 | 1767 | ||
| 1768 | static void vxlan_dellink(struct net_device *dev, struct list_head *head) | 1768 | static void vxlan_dellink(struct net_device *dev, struct list_head *head) |
| 1769 | { | 1769 | { |
| 1770 | struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); | ||
| 1770 | struct vxlan_dev *vxlan = netdev_priv(dev); | 1771 | struct vxlan_dev *vxlan = netdev_priv(dev); |
| 1771 | 1772 | ||
| 1773 | flush_workqueue(vxlan_wq); | ||
| 1774 | |||
| 1775 | spin_lock(&vn->sock_lock); | ||
| 1772 | hlist_del_rcu(&vxlan->hlist); | 1776 | hlist_del_rcu(&vxlan->hlist); |
| 1777 | spin_unlock(&vn->sock_lock); | ||
| 1778 | |||
| 1773 | list_del(&vxlan->next); | 1779 | list_del(&vxlan->next); |
| 1774 | unregister_netdevice_queue(dev, head); | 1780 | unregister_netdevice_queue(dev, head); |
| 1775 | } | 1781 | } |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index ff7f111fffee..36808bf25677 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
| @@ -286,8 +286,7 @@ no_skb: | |||
| 286 | break; | 286 | break; |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | __skb_fill_page_desc(skb, 0, page, 0, 0); | 289 | skb_add_rx_frag(skb, 0, page, 0, 0, PAGE_SIZE); |
| 290 | skb_shinfo(skb)->nr_frags = 1; | ||
| 291 | __skb_queue_tail(&np->rx_batch, skb); | 290 | __skb_queue_tail(&np->rx_batch, skb); |
| 292 | } | 291 | } |
| 293 | 292 | ||
| @@ -831,7 +830,6 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np, | |||
| 831 | struct sk_buff_head *list) | 830 | struct sk_buff_head *list) |
| 832 | { | 831 | { |
| 833 | struct skb_shared_info *shinfo = skb_shinfo(skb); | 832 | struct skb_shared_info *shinfo = skb_shinfo(skb); |
| 834 | int nr_frags = shinfo->nr_frags; | ||
| 835 | RING_IDX cons = np->rx.rsp_cons; | 833 | RING_IDX cons = np->rx.rsp_cons; |
| 836 | struct sk_buff *nskb; | 834 | struct sk_buff *nskb; |
| 837 | 835 | ||
| @@ -840,19 +838,21 @@ static RING_IDX xennet_fill_frags(struct netfront_info *np, | |||
| 840 | RING_GET_RESPONSE(&np->rx, ++cons); | 838 | RING_GET_RESPONSE(&np->rx, ++cons); |
| 841 | skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; | 839 | skb_frag_t *nfrag = &skb_shinfo(nskb)->frags[0]; |
| 842 | 840 | ||
| 843 | __skb_fill_page_desc(skb, nr_frags, | 841 | if (shinfo->nr_frags == MAX_SKB_FRAGS) { |
| 844 | skb_frag_page(nfrag), | 842 | unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; |
| 845 | rx->offset, rx->status); | ||
| 846 | 843 | ||
| 847 | skb->data_len += rx->status; | 844 | BUG_ON(pull_to <= skb_headlen(skb)); |
| 845 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); | ||
| 846 | } | ||
| 847 | BUG_ON(shinfo->nr_frags >= MAX_SKB_FRAGS); | ||
| 848 | |||
| 849 | skb_add_rx_frag(skb, shinfo->nr_frags, skb_frag_page(nfrag), | ||
| 850 | rx->offset, rx->status, PAGE_SIZE); | ||
| 848 | 851 | ||
| 849 | skb_shinfo(nskb)->nr_frags = 0; | 852 | skb_shinfo(nskb)->nr_frags = 0; |
| 850 | kfree_skb(nskb); | 853 | kfree_skb(nskb); |
| 851 | |||
| 852 | nr_frags++; | ||
| 853 | } | 854 | } |
| 854 | 855 | ||
| 855 | shinfo->nr_frags = nr_frags; | ||
| 856 | return cons; | 856 | return cons; |
| 857 | } | 857 | } |
| 858 | 858 | ||
| @@ -933,7 +933,8 @@ static int handle_incoming_queue(struct net_device *dev, | |||
| 933 | while ((skb = __skb_dequeue(rxq)) != NULL) { | 933 | while ((skb = __skb_dequeue(rxq)) != NULL) { |
| 934 | int pull_to = NETFRONT_SKB_CB(skb)->pull_to; | 934 | int pull_to = NETFRONT_SKB_CB(skb)->pull_to; |
| 935 | 935 | ||
| 936 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); | 936 | if (pull_to > skb_headlen(skb)) |
| 937 | __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); | ||
| 937 | 938 | ||
| 938 | /* Ethernet work: Delayed to here as it peeks the header. */ | 939 | /* Ethernet work: Delayed to here as it peeks the header. */ |
| 939 | skb->protocol = eth_type_trans(skb, dev); | 940 | skb->protocol = eth_type_trans(skb, dev); |
| @@ -1019,16 +1020,10 @@ err: | |||
| 1019 | skb_shinfo(skb)->frags[0].page_offset = rx->offset; | 1020 | skb_shinfo(skb)->frags[0].page_offset = rx->offset; |
| 1020 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); | 1021 | skb_frag_size_set(&skb_shinfo(skb)->frags[0], rx->status); |
| 1021 | skb->data_len = rx->status; | 1022 | skb->data_len = rx->status; |
| 1023 | skb->len += rx->status; | ||
| 1022 | 1024 | ||
| 1023 | i = xennet_fill_frags(np, skb, &tmpq); | 1025 | i = xennet_fill_frags(np, skb, &tmpq); |
| 1024 | 1026 | ||
| 1025 | /* | ||
| 1026 | * Truesize is the actual allocation size, even if the | ||
| 1027 | * allocation is only partially used. | ||
| 1028 | */ | ||
| 1029 | skb->truesize += PAGE_SIZE * skb_shinfo(skb)->nr_frags; | ||
| 1030 | skb->len += skb->data_len; | ||
| 1031 | |||
| 1032 | if (rx->flags & XEN_NETRXF_csum_blank) | 1027 | if (rx->flags & XEN_NETRXF_csum_blank) |
| 1033 | skb->ip_summed = CHECKSUM_PARTIAL; | 1028 | skb->ip_summed = CHECKSUM_PARTIAL; |
| 1034 | else if (rx->flags & XEN_NETRXF_data_validated) | 1029 | else if (rx->flags & XEN_NETRXF_data_validated) |
