From c11bf1c8baff170fa478adc04964da519d160e62 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Tue, 24 Jan 2012 10:21:28 +0000 Subject: net/hyperv: fix possible memory leak in do_set_multicast() do_set_multicast() may not free the memory malloc in netvsc_set_multicast_list(). Signed-off-by: Wei Yongjun Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/net/hyperv/netvsc_drv.c') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 462d05f..1a1ca6c 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -68,11 +68,11 @@ static void do_set_multicast(struct work_struct *w) nvdev = hv_get_drvdata(ndevctx->device_ctx); if (nvdev == NULL) - return; + goto out; rdev = nvdev->extension; if (rdev == NULL) - return; + goto out; if (net->flags & IFF_PROMISC) rndis_filter_set_packet_filter(rdev, @@ -83,6 +83,7 @@ static void do_set_multicast(struct work_struct *w) NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); +out: kfree(w); } -- cgit v1.1 From 48c3883999cb06246911e29356d194f96f1c75ef Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Sun, 29 Jan 2012 22:14:02 +0000 Subject: net/hyperv: rx_bytes should account the ether header size skb->len after call eth_type_trans() does not include the ether header size, but rx_bytes should account it. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/hyperv/netvsc_drv.c') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 1a1ca6c..9dccc7a 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -298,7 +298,7 @@ int netvsc_recv_callback(struct hv_device *device_obj, skb->ip_summed = CHECKSUM_NONE; net->stats.rx_packets++; - net->stats.rx_bytes += skb->len; + net->stats.rx_bytes += packet->total_data_buflen; /* * Pass the skb back up. Network stack will deallocate the skb when it -- cgit v1.1 From 0a282538cc1977655004cdb2eb25dd2b63f20637 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Thu, 2 Feb 2012 07:17:59 +0000 Subject: net/hyperv: Use netif_tx_disable() instead of netif_stop_queue() when necessary For code path not on the xmit, use netif_tx_disable() instead of netif_stop_queue() to ensure other CPUs are not doing xmit. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/hyperv/netvsc_drv.c') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 9dccc7a..69193fc 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -123,7 +123,7 @@ static int netvsc_close(struct net_device *net) struct hv_device *device_obj = net_device_ctx->device_ctx; int ret; - netif_stop_queue(net); + netif_tx_disable(net); ret = rndis_filter_close(device_obj); if (ret != 0) @@ -256,7 +256,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, schedule_delayed_work(&ndev_ctx->dwork, msecs_to_jiffies(20)); } else { netif_carrier_off(net); - netif_stop_queue(net); + netif_tx_disable(net); } } @@ -337,7 +337,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu) nvdev->start_remove = true; cancel_delayed_work_sync(&ndevctx->dwork); - netif_stop_queue(ndev); + netif_tx_disable(ndev); rndis_filter_device_remove(hdev); ndev->mtu = mtu; @@ -460,7 +460,7 @@ static int netvsc_remove(struct hv_device *dev) cancel_delayed_work_sync(&ndev_ctx->dwork); /* Stop outbound asap */ - netif_stop_queue(net); + netif_tx_disable(net); unregister_netdev(net); -- cgit v1.1 From c31c151b1c4a29da4dc92212aa8648fb4f8557b9 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Thu, 2 Feb 2012 07:18:00 +0000 Subject: net/hyperv: Fix the page buffer when an RNDIS message goes beyond page boundary There is a possible data corruption if an RNDIS message goes beyond page boundary in the sending code path. This patch fixes the problem. Signed-off-by: Haiyang Zhang Signed-off-by: K. Y. Srinivasan Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/net/hyperv/netvsc_drv.c') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 69193fc..466c58a 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -151,10 +151,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) int ret; unsigned int i, num_pages, npg_data; - /* Add multipage for skb->data and additional one for RNDIS */ + /* Add multipages for skb->data and additional 2 for RNDIS */ npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1) >> PAGE_SHIFT) - ((unsigned long)skb->data >> PAGE_SHIFT) + 1; - num_pages = skb_shinfo(skb)->nr_frags + npg_data + 1; + num_pages = skb_shinfo(skb)->nr_frags + npg_data + 2; /* Allocate a netvsc packet based on # of frags. */ packet = kzalloc(sizeof(struct hv_netvsc_packet) + @@ -173,8 +173,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) sizeof(struct hv_netvsc_packet) + (num_pages * sizeof(struct hv_page_buffer)); - /* Setup the rndis header */ - packet->page_buf_cnt = num_pages; + /* If the rndis msg goes beyond 1 page, we will add 1 later */ + packet->page_buf_cnt = num_pages - 1; /* Initialize it from the skb */ packet->total_data_buflen = skb->len; -- cgit v1.1