Skip to content

Commit 734d4e1

Browse files
Ben Hutchingsdavem330
authored andcommitted
sfc: Fix memory leak when discarding scattered packets
Commit 2768935 ('sfc: reuse pages to avoid DMA mapping/unmapping costs') did not fully take account of DMA scattering which was introduced immediately before. If a received packet is invalid and must be discarded, we only drop a reference to the first buffer's page, but we need to drop a reference for each buffer the packet used. I think this bug was missed partly because efx_recycle_rx_buffers() was not renamed and so no longer does what its name says. It does not change the state of buffers, but only prepares the underlying pages for recycling. Rename it accordingly. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 86bd68b commit 734d4e1

File tree

1 file changed

+20
-7
lines changed
  • drivers/net/ethernet/sfc

1 file changed

+20
-7
lines changed

drivers/net/ethernet/sfc/rx.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,9 @@ static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue,
282282
}
283283

284284
/* Recycle the pages that are used by buffers that have just been received. */
285-
static void efx_recycle_rx_buffers(struct efx_channel *channel,
286-
struct efx_rx_buffer *rx_buf,
287-
unsigned int n_frags)
285+
static void efx_recycle_rx_pages(struct efx_channel *channel,
286+
struct efx_rx_buffer *rx_buf,
287+
unsigned int n_frags)
288288
{
289289
struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
290290

@@ -294,6 +294,20 @@ static void efx_recycle_rx_buffers(struct efx_channel *channel,
294294
} while (--n_frags);
295295
}
296296

297+
static void efx_discard_rx_packet(struct efx_channel *channel,
298+
struct efx_rx_buffer *rx_buf,
299+
unsigned int n_frags)
300+
{
301+
struct efx_rx_queue *rx_queue = efx_channel_get_rx_queue(channel);
302+
303+
efx_recycle_rx_pages(channel, rx_buf, n_frags);
304+
305+
do {
306+
efx_free_rx_buffer(rx_buf);
307+
rx_buf = efx_rx_buf_next(rx_queue, rx_buf);
308+
} while (--n_frags);
309+
}
310+
297311
/**
298312
* efx_fast_push_rx_descriptors - push new RX descriptors quickly
299313
* @rx_queue: RX descriptor queue
@@ -533,8 +547,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
533547
*/
534548
if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) {
535549
efx_rx_flush_packet(channel);
536-
put_page(rx_buf->page);
537-
efx_recycle_rx_buffers(channel, rx_buf, n_frags);
550+
efx_discard_rx_packet(channel, rx_buf, n_frags);
538551
return;
539552
}
540553

@@ -570,9 +583,9 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index,
570583
efx_sync_rx_buffer(efx, rx_buf, rx_buf->len);
571584
}
572585

573-
/* All fragments have been DMA-synced, so recycle buffers and pages. */
586+
/* All fragments have been DMA-synced, so recycle pages. */
574587
rx_buf = efx_rx_buffer(rx_queue, index);
575-
efx_recycle_rx_buffers(channel, rx_buf, n_frags);
588+
efx_recycle_rx_pages(channel, rx_buf, n_frags);
576589

577590
/* Pipeline receives so that we give time for packet headers to be
578591
* prefetched into cache.

0 commit comments

Comments
 (0)