7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Chris Mason Commit 51bab09b7ca1a9a6dd9303a3b7ee346f8128c963 upstream. A failed xa_store() can leave nodes without entries in the tree, and erasing every entry doesn't free those. An XArray needs xa_destroy() before it goes away, even an empty one. That was dropped for tctx->xa in commit ca6484cd308a ("io_uring: no need to call xa_destroy() on empty xarray") over a lockdep report from freeing the tctx in softirq context, and ctx->personalities never had it. Now that the nodes are charged, a store can fail at memory.max and the leaked nodes stay charged. Call xa_destroy() in io_uring_clean_tctx(), which the task runs itself in process context before the tctx is freed, in the error path of __io_uring_add_tctx_node(), and for ctx->personalities in io_ring_ctx_free(). Fixes: ca6484cd308a ("io_uring: no need to call xa_destroy() on empty xarray") Signed-off-by: Chris Mason Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- io_uring/io_uring.c | 1 + io_uring/tctx.c | 3 +++ 2 files changed, 4 insertions(+) --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -2297,6 +2297,7 @@ static __cold void io_ring_ctx_free(stru kvfree(ctx->cancel_table.hbs); xa_destroy(&ctx->io_bl_xa); xa_destroy(&ctx->hpage_acct); + xa_destroy(&ctx->personalities); kfree(ctx); } --- a/io_uring/tctx.c +++ b/io_uring/tctx.c @@ -189,6 +189,7 @@ err_free: io_wq_exit_start(tctx->io_wq); io_wq_put_and_exit(tctx->io_wq); } + xa_destroy(&tctx->xa); percpu_counter_destroy(&tctx->inflight); kfree(tctx); } @@ -250,6 +251,8 @@ __cold void io_uring_clean_tctx(struct i io_uring_del_tctx_node(index); cond_resched(); } + /* A failed xa_store() leaves nodes with no entry behind. */ + xa_destroy(&tctx->xa); if (wq) { /* * Must be after io_uring_del_tctx_node() (removes nodes under