aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hyperv
diff options
context:
space:
mode:
authorHaiyang Zhang <haiyangz@microsoft.com>2015-04-06 18:22:54 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-07 18:45:33 -0400
commitee90b81203a91d4e5385622811ee7872b5bcfe76 (patch)
tree50d211e19cbda5786e09ddcfe287da64d6d2c91a /drivers/net/hyperv
parent721514222db13498613706709409c21c105e0f4a (diff)
hv_netvsc: Fix the packet free when it is in skb headroom
In the two places changed, we now use netvsc_xmit_completion() which properly frees hv_netvsc_packet in or not in skb headroom. Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com> Reviewed-by: K. Y. Srinivasan <kys@microsoft.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/hyperv')
-rw-r--r--drivers/net/hyperv/hyperv_net.h1
-rw-r--r--drivers/net/hyperv/netvsc.c6
-rw-r--r--drivers/net/hyperv/netvsc_drv.c2
3 files changed, 6 insertions, 3 deletions
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index 80bc52eb000c..f0b8b3e0ed7c 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -188,6 +188,7 @@ int netvsc_send(struct hv_device *device,
188 struct hv_netvsc_packet *packet); 188 struct hv_netvsc_packet *packet);
189void netvsc_linkstatus_callback(struct hv_device *device_obj, 189void netvsc_linkstatus_callback(struct hv_device *device_obj,
190 struct rndis_message *resp); 190 struct rndis_message *resp);
191void netvsc_xmit_completion(void *context);
191int netvsc_recv_callback(struct hv_device *device_obj, 192int netvsc_recv_callback(struct hv_device *device_obj,
192 struct hv_netvsc_packet *packet, 193 struct hv_netvsc_packet *packet,
193 struct ndis_tcp_ip_checksum_info *csum_info); 194 struct ndis_tcp_ip_checksum_info *csum_info);
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index 7e83c6ad4bb5..4d4d497d5762 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -878,7 +878,9 @@ int netvsc_send(struct hv_device *device,
878 packet->send_buf_index = section_index; 878 packet->send_buf_index = section_index;
879 packet->total_data_buflen += msd_len; 879 packet->total_data_buflen += msd_len;
880 880
881 kfree(msdp->pkt); 881 if (msdp->pkt)
882 netvsc_xmit_completion(msdp->pkt);
883
882 if (packet->xmit_more) { 884 if (packet->xmit_more) {
883 msdp->pkt = packet; 885 msdp->pkt = packet;
884 msdp->count++; 886 msdp->count++;
@@ -902,7 +904,7 @@ int netvsc_send(struct hv_device *device,
902 if (m_ret != 0) { 904 if (m_ret != 0) {
903 netvsc_free_send_slot(net_device, 905 netvsc_free_send_slot(net_device,
904 msd_send->send_buf_index); 906 msd_send->send_buf_index);
905 kfree(msd_send); 907 netvsc_xmit_completion(msd_send);
906 } 908 }
907 } 909 }
908 910
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 73f8fba62a52..e5fa094e6fe2 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -229,7 +229,7 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
229 return q_idx; 229 return q_idx;
230} 230}
231 231
232static void netvsc_xmit_completion(void *context) 232void netvsc_xmit_completion(void *context)
233{ 233{
234 struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; 234 struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
235 struct sk_buff *skb = (struct sk_buff *) 235 struct sk_buff *skb = (struct sk_buff *)