Skip to content

Commit

Permalink
hyperv: Fix a bug in netvsc_send()
Browse files Browse the repository at this point in the history
After the packet is successfully sent, we should not touch the packet
as it may have been freed. This patch is based on the work done by
Long Li <longli@microsoft.com>.

David, please queue this up for stable.

Signed-off-by: K. Y. Srinivasan <kys@microsoft.com>
Reported-by: Sitsofe Wheeler <sitsofe@yahoo.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
KY Srinivasan authored and David S. Miller committed Oct 6, 2014
1 parent 4754965 commit 3a67c9c
Showing 1 changed file with 8 additions and 7 deletions.
15 changes: 8 additions & 7 deletions drivers/net/hyperv/netvsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,7 @@ int netvsc_send(struct hv_device *device,
unsigned int section_index = NETVSC_INVALID_INDEX;
u32 msg_size = 0;
struct sk_buff *skb;
u16 q_idx = packet->q_idx;


net_device = get_outbound_net_device(device);
Expand Down Expand Up @@ -769,24 +770,24 @@ int netvsc_send(struct hv_device *device,

if (ret == 0) {
atomic_inc(&net_device->num_outstanding_sends);
atomic_inc(&net_device->queue_sends[packet->q_idx]);
atomic_inc(&net_device->queue_sends[q_idx]);

if (hv_ringbuf_avail_percent(&out_channel->outbound) <
RING_AVAIL_PERCENT_LOWATER) {
netif_tx_stop_queue(netdev_get_tx_queue(
ndev, packet->q_idx));
ndev, q_idx));

if (atomic_read(&net_device->
queue_sends[packet->q_idx]) < 1)
queue_sends[q_idx]) < 1)
netif_tx_wake_queue(netdev_get_tx_queue(
ndev, packet->q_idx));
ndev, q_idx));
}
} else if (ret == -EAGAIN) {
netif_tx_stop_queue(netdev_get_tx_queue(
ndev, packet->q_idx));
if (atomic_read(&net_device->queue_sends[packet->q_idx]) < 1) {
ndev, q_idx));
if (atomic_read(&net_device->queue_sends[q_idx]) < 1) {
netif_tx_wake_queue(netdev_get_tx_queue(
ndev, packet->q_idx));
ndev, q_idx));
ret = -ENOSPC;
}
} else {
Expand Down

0 comments on commit 3a67c9c

Please sign in to comment.