Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vmxnet3: Fix memory leaks in rx path (fwd)

If rcd length was zero, the page used for frag was not being released. It
was being replaced with a newly allocated page. This change takes care
of that memory leak.

Signed-off-by: Guolin Yang <gyang@vmware.com>
Signed-off-by: Shreyas N Bhatewara <sbhatewara@vmware.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Shreyas Bhatewara and committed by
David S. Miller
c41fcce9 e9ba47bf

+21 -18
+21 -18
drivers/net/vmxnet3/vmxnet3_drv.c
··· 861 861 , skb_headlen(skb)); 862 862 } 863 863 864 + if (skb->len <= VMXNET3_HDR_COPY_SIZE) 865 + ctx->copy_size = skb->len; 866 + 864 867 /* make sure headers are accessible directly */ 865 868 if (unlikely(!pskb_may_pull(skb, ctx->copy_size))) 866 869 goto err; ··· 1276 1273 if (skip_page_frags) 1277 1274 goto rcd_done; 1278 1275 1279 - new_page = alloc_page(GFP_ATOMIC); 1280 - if (unlikely(new_page == NULL)) { 1276 + if (rcd->len) { 1277 + new_page = alloc_page(GFP_ATOMIC); 1281 1278 /* Replacement page frag could not be allocated. 1282 1279 * Reuse this page. Drop the pkt and free the 1283 1280 * skb which contained this page as a frag. Skip 1284 1281 * processing all the following non-sop frags. 1285 1282 */ 1286 - rq->stats.rx_buf_alloc_failure++; 1287 - dev_kfree_skb(ctx->skb); 1288 - ctx->skb = NULL; 1289 - skip_page_frags = true; 1290 - goto rcd_done; 1291 - } 1283 + if (unlikely(!new_page)) { 1284 + rq->stats.rx_buf_alloc_failure++; 1285 + dev_kfree_skb(ctx->skb); 1286 + ctx->skb = NULL; 1287 + skip_page_frags = true; 1288 + goto rcd_done; 1289 + } 1292 1290 1293 - if (rcd->len) { 1294 1291 dma_unmap_page(&adapter->pdev->dev, 1295 1292 rbi->dma_addr, rbi->len, 1296 1293 PCI_DMA_FROMDEVICE); 1297 1294 1298 1295 vmxnet3_append_frag(ctx->skb, rcd, rbi); 1299 - } 1300 1296 1301 - /* Immediate refill */ 1302 - rbi->page = new_page; 1303 - rbi->dma_addr = dma_map_page(&adapter->pdev->dev, 1304 - rbi->page, 1305 - 0, PAGE_SIZE, 1306 - PCI_DMA_FROMDEVICE); 1307 - rxd->addr = cpu_to_le64(rbi->dma_addr); 1308 - rxd->len = rbi->len; 1297 + /* Immediate refill */ 1298 + rbi->page = new_page; 1299 + rbi->dma_addr = dma_map_page(&adapter->pdev->dev 1300 + , rbi->page, 1301 + 0, PAGE_SIZE, 1302 + PCI_DMA_FROMDEVICE); 1303 + rxd->addr = cpu_to_le64(rbi->dma_addr); 1304 + rxd->len = rbi->len; 1305 + } 1309 1306 } 1310 1307 1311 1308