Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c41fcce9 authored by Shreyas Bhatewara's avatar Shreyas Bhatewara Committed by David S. Miller
Browse files

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: default avatarGuolin Yang <gyang@vmware.com>
Signed-off-by: default avatarShreyas N Bhatewara <sbhatewara@vmware.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e9ba47bf
Loading
Loading
Loading
Loading
+21 −18
Original line number Diff line number Diff line
@@ -861,6 +861,9 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
					     , skb_headlen(skb));
		}

		if (skb->len <= VMXNET3_HDR_COPY_SIZE)
			ctx->copy_size = skb->len;

		/* make sure headers are accessible directly */
		if (unlikely(!pskb_may_pull(skb, ctx->copy_size)))
			goto err;
@@ -1273,13 +1276,14 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
			if (skip_page_frags)
				goto rcd_done;

			if (rcd->len) {
				new_page = alloc_page(GFP_ATOMIC);
			if (unlikely(new_page == NULL)) {
				/* Replacement page frag could not be allocated.
				 * Reuse this page. Drop the pkt and free the
				 * skb which contained this page as a frag. Skip
				 * processing all the following non-sop frags.
				 */
				if (unlikely(!new_page)) {
					rq->stats.rx_buf_alloc_failure++;
					dev_kfree_skb(ctx->skb);
					ctx->skb = NULL;
@@ -1287,23 +1291,22 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
					goto rcd_done;
				}

			if (rcd->len) {
				dma_unmap_page(&adapter->pdev->dev,
					       rbi->dma_addr, rbi->len,
					       PCI_DMA_FROMDEVICE);

				vmxnet3_append_frag(ctx->skb, rcd, rbi);
			}

				/* Immediate refill */
				rbi->page = new_page;
			rbi->dma_addr = dma_map_page(&adapter->pdev->dev,
						     rbi->page,
				rbi->dma_addr = dma_map_page(&adapter->pdev->dev
							, rbi->page,
							0, PAGE_SIZE,
							PCI_DMA_FROMDEVICE);
				rxd->addr = cpu_to_le64(rbi->dma_addr);
				rxd->len = rbi->len;
			}
		}


		skb = ctx->skb;