From: Guangshuo Li __octep_vf_oq_process_rx() clears buff_info->page before building an skb from the RX page. On the success path the page is consumed by the skb, either as the skb head or as an RX fragment. If napi_build_skb() fails, however, the page is not consumed by an skb. The error path advances the descriptor and leaves the ring slot cleared, so the page is no longer tracked and is leaked. In the multi-fragment case, the remaining fragment pages are also unmapped and removed from their ring slots without being released. Release the head page when napi_build_skb() fails, and release each remaining fragment page before clearing its ring slot. Fixes: dd66b4285470 ("octeon_ep_vf: add NULL check for napi_build_skb()") Signed-off-by: Guangshuo Li --- drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c index d982474082..302559b16b 100644 --- a/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c +++ b/drivers/net/ethernet/marvell/octeon_ep_vf/octep_vf_rx.c @@ -418,6 +418,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct, skb = napi_build_skb((void *)resp_hw, PAGE_SIZE); if (!skb) { oq->stats->alloc_failures++; + put_page(virt_to_page(resp_hw)); desc_used++; read_idx = octep_vf_oq_next_idx(oq, read_idx); continue; @@ -434,6 +435,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct, skb = napi_build_skb((void *)resp_hw, PAGE_SIZE); if (!skb) { oq->stats->alloc_failures++; + put_page(virt_to_page(resp_hw)); desc_used++; read_idx = octep_vf_oq_next_idx(oq, read_idx); data_len = buff_info->len - oq->max_single_buffer_size; @@ -442,6 +444,7 @@ static int __octep_vf_oq_process_rx(struct octep_vf_device *oct, PAGE_SIZE, DMA_FROM_DEVICE); buff_info = (struct octep_vf_rx_buffer *) &oq->buff_info[read_idx]; + put_page(buff_info->page); buff_info->page = NULL; if (data_len < oq->buffer_size) data_len = 0; -- 2.34.1