Make sure we unmap areas while closing a queue. Signed-off-by: Pavel Begunkov --- io_uring/zcrx.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index 91d0d823f482..be3560739bbc 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -311,6 +311,9 @@ static void io_zcrx_unmap_area(struct io_zcrx_ifq *ifq, { int i; + if (!area) + return; + guard(mutex)(&ifq->pp_lock); if (!area->is_mapped) return; @@ -437,7 +440,8 @@ static void io_free_rbuf_ring(struct io_zcrx_ifq *ifq) static void io_zcrx_free_area(struct io_zcrx_ifq *ifq, struct io_zcrx_area *area) { - io_zcrx_unmap_area(ifq, area); + if (WARN_ON_ONCE(area->is_mapped)) + return; io_release_area_mem(&area->mem); if (area->mem.account_pages) @@ -544,8 +548,10 @@ static int __zcrx_create_area(struct io_zcrx_ifq *ifq, if (!ret) return 0; err: - if (area) + if (area) { + io_zcrx_unmap_area(ifq, area); io_zcrx_free_area(ifq, area); + } return ret; } @@ -599,11 +605,12 @@ static void io_close_queue(struct io_zcrx_ifq *ifq) } if (netdev) { - if (ifq->if_rxq != -1) { - netdev_lock(netdev); + netdev_lock(netdev); + if (ifq->if_rxq != -1) netif_mp_close_rxq(netdev, ifq->if_rxq, &p); - netdev_unlock(netdev); - } + + io_zcrx_unmap_area(ifq, ifq->area); + netdev_unlock(netdev); netdev_put(netdev, &netdev_tracker); } ifq->if_rxq = -1; @@ -1397,8 +1404,7 @@ static void io_pp_uninstall(void *mp_priv, struct netdev_rx_queue *rxq) struct io_zcrx_ifq *ifq = mp_priv; io_zcrx_drop_netdev(ifq); - if (ifq->area) - io_zcrx_unmap_area(ifq, ifq->area); + io_zcrx_unmap_area(ifq, ifq->area); p->mp_ops = NULL; p->mp_priv = NULL; -- 2.54.0