Commit 45b3941d authored by Olivier Langlois's avatar Olivier Langlois Committed by Jens Axboe
Browse files

io_uring/napi: fix io_napi_entry RCU accesses



correct 3 RCU structures modifications that were not using the RCU
functions to make their update.

Signed-off-by: default avatarOlivier Langlois <olivier@trillion01.com>
Link: https://lore.kernel.org/r/9f53b5169afa8c7bf3665a0b19dc2f7061173530.1728828877.git.olivier@trillion01.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 2f3cc8e4
Loading
Loading
Loading
Loading
+11 −6
Original line number Diff line number Diff line
@@ -81,19 +81,24 @@ void __io_napi_add(struct io_ring_ctx *ctx, struct socket *sock)
	}

	hlist_add_tail_rcu(&e->node, hash_list);
	list_add_tail(&e->list, &ctx->napi_list);
	list_add_tail_rcu(&e->list, &ctx->napi_list);
	spin_unlock(&ctx->napi_lock);
}

static void __io_napi_remove_stale(struct io_ring_ctx *ctx)
{
	struct io_napi_entry *e;
	unsigned int i;

	spin_lock(&ctx->napi_lock);
	hash_for_each(ctx->napi_ht, i, e, node) {
	/*
	 * list_for_each_entry_safe() is not required as long as:
	 * 1. list_del_rcu() does not reset the deleted node next pointer
	 * 2. kfree_rcu() delays the memory freeing until the next quiescent
	 *    state
	 */
	list_for_each_entry(e, &ctx->napi_list, list) {
		if (time_after(jiffies, READ_ONCE(e->timeout))) {
			list_del(&e->list);
			list_del_rcu(&e->list);
			hash_del_rcu(&e->node);
			kfree_rcu(e, rcu);
		}
@@ -204,13 +209,13 @@ void io_napi_init(struct io_ring_ctx *ctx)
void io_napi_free(struct io_ring_ctx *ctx)
{
	struct io_napi_entry *e;
	unsigned int i;

	spin_lock(&ctx->napi_lock);
	hash_for_each(ctx->napi_ht, i, e, node) {
	list_for_each_entry(e, &ctx->napi_list, list) {
		hash_del_rcu(&e->node);
		kfree_rcu(e, rcu);
	}
	INIT_LIST_HEAD_RCU(&ctx->napi_list);
	spin_unlock(&ctx->napi_lock);
}