diff options
Diffstat (limited to 'drivers/net/hyperv/netvsc.c')
-rw-r--r-- | drivers/net/hyperv/netvsc.c | 33 |
1 files changed, 22 insertions, 11 deletions
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 059fc5231601..ec313fc08d82 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c | |||
@@ -841,6 +841,18 @@ static inline int netvsc_send_pkt( | |||
841 | return ret; | 841 | return ret; |
842 | } | 842 | } |
843 | 843 | ||
844 | /* Move packet out of multi send data (msd), and clear msd */ | ||
845 | static inline void move_pkt_msd(struct hv_netvsc_packet **msd_send, | ||
846 | struct sk_buff **msd_skb, | ||
847 | struct multi_send_data *msdp) | ||
848 | { | ||
849 | *msd_skb = msdp->skb; | ||
850 | *msd_send = msdp->pkt; | ||
851 | msdp->skb = NULL; | ||
852 | msdp->pkt = NULL; | ||
853 | msdp->count = 0; | ||
854 | } | ||
855 | |||
844 | int netvsc_send(struct hv_device *device, | 856 | int netvsc_send(struct hv_device *device, |
845 | struct hv_netvsc_packet *packet, | 857 | struct hv_netvsc_packet *packet, |
846 | struct rndis_message *rndis_msg, | 858 | struct rndis_message *rndis_msg, |
@@ -855,6 +867,7 @@ int netvsc_send(struct hv_device *device, | |||
855 | unsigned int section_index = NETVSC_INVALID_INDEX; | 867 | unsigned int section_index = NETVSC_INVALID_INDEX; |
856 | struct multi_send_data *msdp; | 868 | struct multi_send_data *msdp; |
857 | struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; | 869 | struct hv_netvsc_packet *msd_send = NULL, *cur_send = NULL; |
870 | struct sk_buff *msd_skb = NULL; | ||
858 | bool try_batch; | 871 | bool try_batch; |
859 | bool xmit_more = (skb != NULL) ? skb->xmit_more : false; | 872 | bool xmit_more = (skb != NULL) ? skb->xmit_more : false; |
860 | 873 | ||
@@ -897,10 +910,8 @@ int netvsc_send(struct hv_device *device, | |||
897 | net_device->send_section_size) { | 910 | net_device->send_section_size) { |
898 | section_index = netvsc_get_next_send_section(net_device); | 911 | section_index = netvsc_get_next_send_section(net_device); |
899 | if (section_index != NETVSC_INVALID_INDEX) { | 912 | if (section_index != NETVSC_INVALID_INDEX) { |
900 | msd_send = msdp->pkt; | 913 | move_pkt_msd(&msd_send, &msd_skb, msdp); |
901 | msdp->pkt = NULL; | 914 | msd_len = 0; |
902 | msdp->count = 0; | ||
903 | msd_len = 0; | ||
904 | } | 915 | } |
905 | } | 916 | } |
906 | 917 | ||
@@ -919,31 +930,31 @@ int netvsc_send(struct hv_device *device, | |||
919 | packet->total_data_buflen += msd_len; | 930 | packet->total_data_buflen += msd_len; |
920 | } | 931 | } |
921 | 932 | ||
922 | if (msdp->pkt) | 933 | if (msdp->skb) |
923 | dev_kfree_skb_any(skb); | 934 | dev_kfree_skb_any(msdp->skb); |
924 | 935 | ||
925 | if (xmit_more && !packet->cp_partial) { | 936 | if (xmit_more && !packet->cp_partial) { |
937 | msdp->skb = skb; | ||
926 | msdp->pkt = packet; | 938 | msdp->pkt = packet; |
927 | msdp->count++; | 939 | msdp->count++; |
928 | } else { | 940 | } else { |
929 | cur_send = packet; | 941 | cur_send = packet; |
942 | msdp->skb = NULL; | ||
930 | msdp->pkt = NULL; | 943 | msdp->pkt = NULL; |
931 | msdp->count = 0; | 944 | msdp->count = 0; |
932 | } | 945 | } |
933 | } else { | 946 | } else { |
934 | msd_send = msdp->pkt; | 947 | move_pkt_msd(&msd_send, &msd_skb, msdp); |
935 | msdp->pkt = NULL; | ||
936 | msdp->count = 0; | ||
937 | cur_send = packet; | 948 | cur_send = packet; |
938 | } | 949 | } |
939 | 950 | ||
940 | if (msd_send) { | 951 | if (msd_send) { |
941 | m_ret = netvsc_send_pkt(msd_send, net_device, pb, skb); | 952 | m_ret = netvsc_send_pkt(msd_send, net_device, NULL, msd_skb); |
942 | 953 | ||
943 | if (m_ret != 0) { | 954 | if (m_ret != 0) { |
944 | netvsc_free_send_slot(net_device, | 955 | netvsc_free_send_slot(net_device, |
945 | msd_send->send_buf_index); | 956 | msd_send->send_buf_index); |
946 | dev_kfree_skb_any(skb); | 957 | dev_kfree_skb_any(msd_skb); |
947 | } | 958 | } |
948 | } | 959 | } |
949 | 960 | ||