sfc: free multiple Rx buffers when required
Subsystems (3)
PATCH 1/1 sfc: free multiple Rx buffers when required
From: Daniel Pieczko <[email protected]>
When Rx packet data must be dropped, all the buffers associated with that Rx packet must be freed. Extend and rename efx_free_rx_buffer() to efx_free_rx_buffers() and loop through all the fragments.
By doing so this patch fixes a possible memory leak.
Signed-off-by Shradha Shah <[email protected]>
--- drivers/net/ethernet/sfc/rx.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-)
drivers/net/ethernet/sfc/rx.c +25 -17
@@ -224,12 +224,17 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, } } -static void efx_free_rx_buffer (struct efx_rx_buffer *rx_buf) +static void efx_free_rx_buffers (struct efx_rx_queue *rx_queue, +struct efx_rx_buffer *rx_buf, +unsigned int num_bufs) { -if (rx_buf->page) { -put_page (rx_buf->page); - rx_buf->page =NULL ; - } +do { +if (rx_buf->page) { +put_page (rx_buf->page); + rx_buf->page =NULL ; + } + rx_buf =efx_rx_buf_next (rx_queue, rx_buf); + }while (--num_bufs); }/* Attempt to recycle the page if there is an RX recycle ring; the page can
@@ -278,7 +283,7 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,/* If this is the last buffer in a page, unmap and free it. */ if (rx_buf->flags &EFX_RX_BUF_LAST_IN_PAGE ) {efx_unmap_rx_buffer (rx_queue->efx, rx_buf); -efx_free_rx_buffer (rx_buf); +efx_free_rx_buffers (rx_queue, rx_buf,1 ); } rx_buf->page =NULL ; }
@@ -304,10 +309,7 @@ static void efx_discard_rx_packet(struct efx_channel *channel,efx_recycle_rx_pages (channel, rx_buf, n_frags); -do { -efx_free_rx_buffer (rx_buf); - rx_buf =efx_rx_buf_next (rx_queue, rx_buf); - }while (--n_frags); +efx_free_rx_buffers (rx_queue, rx_buf, n_frags); }/**
@@ -431,11 +433,10 @@ efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, skb =napi_get_frags (napi);if (unlikely (!skb)) { -while (n_frags--) { -put_page (rx_buf->page); - rx_buf->page =NULL ; - rx_buf =efx_rx_buf_next (&channel->rx_queue, rx_buf); - } +struct efx_rx_queue *rx_queue; + + rx_queue =efx_channel_get_rx_queue (channel); +efx_free_rx_buffers (rx_queue, rx_buf, n_frags);return ; }
@@ -622,7 +623,10 @@ static void efx_rx_deliver(struct efx_channel *channel, u8 *eh, skb =efx_rx_mk_skb (channel, rx_buf, n_frags, eh, hdr_len);if (unlikely (skb ==NULL )) { -efx_free_rx_buffer (rx_buf); +struct efx_rx_queue *rx_queue; + + rx_queue =efx_channel_get_rx_queue (channel); +efx_free_rx_buffers (rx_queue, rx_buf, n_frags);return ; }skb_record_rx_queue (skb, channel->rx_queue.core_index);
@@ -661,8 +665,12 @@ void __efx_rx_packet(struct efx_channel *channel)* loopback layer, and free the rx_buf here */ if (unlikely (efx->loopback_selftest)) { +struct efx_rx_queue *rx_queue; +efx_loopback_rx_packet (efx, eh, rx_buf->len); -efx_free_rx_buffer (rx_buf); + rx_queue =efx_channel_get_rx_queue (channel); +efx_free_rx_buffers (rx_queue, rx_buf, + channel->rx_pkt_n_frags); goto out; }
From: Shradha Shah <[email protected]>
Date: Fri, 29 May 2015 12:25:54 +0100
Quoted 9 lines
From: Daniel Pieczko <[email protected]>
When Rx packet data must be dropped, all the buffers associated with that Rx packet must be freed. Extend and rename
efx_free_rx_buffer()toefx_free_rx_buffers()and loop through all the fragments.
By doing so this patch fixes a possible memory leak.Signed-off-by Shradha Shah <[email protected]>
Applied, thanks.