1 From 38bca2d5bd6fdaa0b8e1e415f79d89322c6825a8 Mon Sep 17 00:00:00 2001
2 From: KY Srinivasan <kys@microsoft.com>
3 Date: Sun, 5 Oct 2014 10:42:51 -0700
4 Subject: [PATCH 24/25] hyperv: Fix a bug in netvsc_send()
6 [ Upstream commit 3a67c9ccad926a168d8b7891537a452018368a5b ]
8 After the packet is successfully sent, we should not touch the packet
9 as it may have been freed. This patch is based on the work done by
10 Long Li <longli@microsoft.com>.
12 David, please queue this up for stable.
14 Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
15 Reported-by: Sitsofe Wheeler <sitsofe@yahoo.com>
16 Signed-off-by: David S. Miller <davem@davemloft.net>
17 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
19 drivers/net/hyperv/netvsc.c | 15 ++++++++-------
20 1 file changed, 8 insertions(+), 7 deletions(-)
22 diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
23 index d97d5f39a04e..7edf976ecfa0 100644
24 --- a/drivers/net/hyperv/netvsc.c
25 +++ b/drivers/net/hyperv/netvsc.c
26 @@ -708,6 +708,7 @@ int netvsc_send(struct hv_device *device,
27 unsigned int section_index = NETVSC_INVALID_INDEX;
30 + u16 q_idx = packet->q_idx;
33 net_device = get_outbound_net_device(device);
34 @@ -772,24 +773,24 @@ int netvsc_send(struct hv_device *device,
37 atomic_inc(&net_device->num_outstanding_sends);
38 - atomic_inc(&net_device->queue_sends[packet->q_idx]);
39 + atomic_inc(&net_device->queue_sends[q_idx]);
41 if (hv_ringbuf_avail_percent(&out_channel->outbound) <
42 RING_AVAIL_PERCENT_LOWATER) {
43 netif_tx_stop_queue(netdev_get_tx_queue(
44 - ndev, packet->q_idx));
47 if (atomic_read(&net_device->
48 - queue_sends[packet->q_idx]) < 1)
49 + queue_sends[q_idx]) < 1)
50 netif_tx_wake_queue(netdev_get_tx_queue(
51 - ndev, packet->q_idx));
54 } else if (ret == -EAGAIN) {
55 netif_tx_stop_queue(netdev_get_tx_queue(
56 - ndev, packet->q_idx));
57 - if (atomic_read(&net_device->queue_sends[packet->q_idx]) < 1) {
59 + if (atomic_read(&net_device->queue_sends[q_idx]) < 1) {
60 netif_tx_wake_queue(netdev_get_tx_queue(
61 - ndev, packet->q_idx));