Commit 52a5a22d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'io_uring-6.13-20250111' of git://git.kernel.dk/linux

Pull io_uring fixes from Jens Axboe:

 - Fix for multishot timeout updates only using the updated value for
   the first invocation, not subsequent ones

 - Silence a false positive lockdep warning

 - Fix the eventfd signaling and putting RCU logic

 - Fix fault injected SQPOLL setup not clearing the task pointer in the
   error path

 - Fix local task_work looking at the SQPOLL thread rather than just
   signaling the safe variant. Again one of those theoretical issues,
   which should be closed up none the less.

* tag 'io_uring-6.13-20250111' of git://git.kernel.dk/linux:
  io_uring: don't touch sqd->thread off tw add
  io_uring/sqpoll: zero sqd->thread on tctx errors
  io_uring/eventfd: ensure io_eventfd_signal() defers another RCU period
  io_uring: silence false positive warnings
  io_uring/timeout: fix multishot updates
parents 57162361 bd2703b4
Loading
Loading
Loading
Loading
+7 −9
Original line number Diff line number Diff line
@@ -33,20 +33,18 @@ static void io_eventfd_free(struct rcu_head *rcu)
	kfree(ev_fd);
}

static void io_eventfd_do_signal(struct rcu_head *rcu)
static void io_eventfd_put(struct io_ev_fd *ev_fd)
{
	struct io_ev_fd *ev_fd = container_of(rcu, struct io_ev_fd, rcu);

	eventfd_signal_mask(ev_fd->cq_ev_fd, EPOLL_URING_WAKE);

	if (refcount_dec_and_test(&ev_fd->refs))
		io_eventfd_free(rcu);
		call_rcu(&ev_fd->rcu, io_eventfd_free);
}

static void io_eventfd_put(struct io_ev_fd *ev_fd)
static void io_eventfd_do_signal(struct rcu_head *rcu)
{
	if (refcount_dec_and_test(&ev_fd->refs))
		call_rcu(&ev_fd->rcu, io_eventfd_free);
	struct io_ev_fd *ev_fd = container_of(rcu, struct io_ev_fd, rcu);

	eventfd_signal_mask(ev_fd->cq_ev_fd, EPOLL_URING_WAKE);
	io_eventfd_put(ev_fd);
}

static void io_eventfd_release(struct io_ev_fd *ev_fd, bool put_ref)
+1 −4
Original line number Diff line number Diff line
@@ -1226,10 +1226,7 @@ static void io_req_normal_work_add(struct io_kiocb *req)

	/* SQPOLL doesn't need the task_work added, it'll run it itself */
	if (ctx->flags & IORING_SETUP_SQPOLL) {
		struct io_sq_data *sqd = ctx->sq_data;

		if (sqd->thread)
			__set_notify_signal(sqd->thread);
		__set_notify_signal(tctx->task);
		return;
	}

+4 −3
Original line number Diff line number Diff line
@@ -125,6 +125,9 @@ static inline void io_lockdep_assert_cq_locked(struct io_ring_ctx *ctx)
#if defined(CONFIG_PROVE_LOCKING)
	lockdep_assert(in_task());

	if (ctx->flags & IORING_SETUP_DEFER_TASKRUN)
		lockdep_assert_held(&ctx->uring_lock);

	if (ctx->flags & IORING_SETUP_IOPOLL) {
		lockdep_assert_held(&ctx->uring_lock);
	} else if (!ctx->task_complete) {
@@ -136,9 +139,7 @@ static inline void io_lockdep_assert_cq_locked(struct io_ring_ctx *ctx)
		 * Not from an SQE, as those cannot be submitted, but via
		 * updating tagged resources.
		 */
		if (percpu_ref_is_dying(&ctx->refs))
			lockdep_assert(current_work());
		else
		if (!percpu_ref_is_dying(&ctx->refs))
			lockdep_assert(current == ctx->submitter_task);
	}
#endif
+5 −1
Original line number Diff line number Diff line
@@ -268,8 +268,12 @@ static int io_sq_thread(void *data)
	DEFINE_WAIT(wait);

	/* offload context creation failed, just exit */
	if (!current->io_uring)
	if (!current->io_uring) {
		mutex_lock(&sqd->lock);
		sqd->thread = NULL;
		mutex_unlock(&sqd->lock);
		goto err_out;
	}

	snprintf(buf, sizeof(buf), "iou-sqp-%d", sqd->task_pid);
	set_task_comm(current, buf);
+3 −1
Original line number Diff line number Diff line
@@ -427,10 +427,12 @@ static int io_timeout_update(struct io_ring_ctx *ctx, __u64 user_data,

	timeout->off = 0; /* noseq */
	data = req->async_data;
	data->ts = *ts;

	list_add_tail(&timeout->list, &ctx->timeout_list);
	hrtimer_init(&data->timer, io_timeout_get_clock(data), mode);
	data->timer.function = io_timeout_fn;
	hrtimer_start(&data->timer, timespec64_to_ktime(*ts), mode);
	hrtimer_start(&data->timer, timespec64_to_ktime(data->ts), mode);
	return 0;
}