io_uring-5.16-2021-12-10
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmG0PwYQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgphbiEACv95PrGVuOzgXwC1Ydk4Km5Yyt8vANKcxA LFzeScrRhGG28vHCLZuPSxtFn9nGjBJPDKscDWQE0tpq8NwB6BAjr3Ps2AR4tI3M 2bn1ssHIHADdkaV1ixwTtQynHgCvOtKSTmLJ+TTDIYdgwAyRVlRBtpke/nXn5VCR kUdQ/3hHSPbEY+WvrDz7yAvDIMxTrBHmt8TbDiI1FXzNf8AOd32ekpBNzwe2hTQi OLhpaQ60S74UG78c4OGg6SV+twW0nkp1DyTf8MhC3WoBBnTwQdc/BpLNJbnUwH57 lJVJTz0sknbnQCtifJ8/Wjzn6r95cOwbYvaGgXyi7KtTGn0QXLcK+FohNVizFR0x qTMWlFJ5aPmzqed6oMZ2m8iaGxR9813I0GP54Hsqw4PmoPb1GDN5FvZIN+MKdaJd PSp9YH7RDHsusYZjjaUtHIcxhxztblf5wNVAkmkfrFZzNArnwsw0k9gX7DI0f+GX +TazZzX8gLRonAskBHgoSDT+8WOzDOHYYIVVe0g/8TR+jW8oGDd9D0sJbH74dV1Y 3C4WLbJCquBzatotmcmgkt9CJzZz9y373cVVNu4HZgH49qjEZCJuFgBaTpanvwHk Qk5KTl9yIfjs+H2FDWa2Pd6LnsVvuIpwOd4R37RDLGM2ZiX100eX1VbD6RxtIehQ PPKP13kYAQ== =BUVd -----END PGP SIGNATURE----- Merge tag 'io_uring-5.16-2021-12-10' of git://git.kernel.dk/linux-block Pull io_uring fixes from Jens Axboe: "A few fixes that are all bound for stable: - Two syzbot reports for io-wq that turned out to be separate fixes, but ultimately very closely related - io_uring task_work running on cancelations" * tag 'io_uring-5.16-2021-12-10' of git://git.kernel.dk/linux-block: io-wq: check for wq exit after adding new worker task_work io_uring: ensure task_work gets run as part of cancelations io-wq: remove spurious bit clear on task_work addition
This commit is contained in:
commit
f152165ada
29
fs/io-wq.c
29
fs/io-wq.c
@ -142,6 +142,7 @@ static bool io_acct_cancel_pending_work(struct io_wqe *wqe,
|
||||
struct io_wqe_acct *acct,
|
||||
struct io_cb_cancel_data *match);
|
||||
static void create_worker_cb(struct callback_head *cb);
|
||||
static void io_wq_cancel_tw_create(struct io_wq *wq);
|
||||
|
||||
static bool io_worker_get(struct io_worker *worker)
|
||||
{
|
||||
@ -357,12 +358,22 @@ static bool io_queue_worker_create(struct io_worker *worker,
|
||||
test_and_set_bit_lock(0, &worker->create_state))
|
||||
goto fail_release;
|
||||
|
||||
atomic_inc(&wq->worker_refs);
|
||||
init_task_work(&worker->create_work, func);
|
||||
worker->create_index = acct->index;
|
||||
if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) {
|
||||
clear_bit_unlock(0, &worker->create_state);
|
||||
/*
|
||||
* EXIT may have been set after checking it above, check after
|
||||
* adding the task_work and remove any creation item if it is
|
||||
* now set. wq exit does that too, but we can have added this
|
||||
* work item after we canceled in io_wq_exit_workers().
|
||||
*/
|
||||
if (test_bit(IO_WQ_BIT_EXIT, &wq->state))
|
||||
io_wq_cancel_tw_create(wq);
|
||||
io_worker_ref_put(wq);
|
||||
return true;
|
||||
}
|
||||
io_worker_ref_put(wq);
|
||||
clear_bit_unlock(0, &worker->create_state);
|
||||
fail_release:
|
||||
io_worker_release(worker);
|
||||
@ -1198,13 +1209,9 @@ void io_wq_exit_start(struct io_wq *wq)
|
||||
set_bit(IO_WQ_BIT_EXIT, &wq->state);
|
||||
}
|
||||
|
||||
static void io_wq_exit_workers(struct io_wq *wq)
|
||||
static void io_wq_cancel_tw_create(struct io_wq *wq)
|
||||
{
|
||||
struct callback_head *cb;
|
||||
int node;
|
||||
|
||||
if (!wq->task)
|
||||
return;
|
||||
|
||||
while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) {
|
||||
struct io_worker *worker;
|
||||
@ -1212,6 +1219,16 @@ static void io_wq_exit_workers(struct io_wq *wq)
|
||||
worker = container_of(cb, struct io_worker, create_work);
|
||||
io_worker_cancel_cb(worker);
|
||||
}
|
||||
}
|
||||
|
||||
static void io_wq_exit_workers(struct io_wq *wq)
|
||||
{
|
||||
int node;
|
||||
|
||||
if (!wq->task)
|
||||
return;
|
||||
|
||||
io_wq_cancel_tw_create(wq);
|
||||
|
||||
rcu_read_lock();
|
||||
for_each_node(node) {
|
||||
|
@ -9824,7 +9824,7 @@ static __cold void io_uring_drop_tctx_refs(struct task_struct *task)
|
||||
|
||||
/*
|
||||
* Find any io_uring ctx that this task has registered or done IO on, and cancel
|
||||
* requests. @sqd should be not-null IIF it's an SQPOLL thread cancellation.
|
||||
* requests. @sqd should be not-null IFF it's an SQPOLL thread cancellation.
|
||||
*/
|
||||
static __cold void io_uring_cancel_generic(bool cancel_all,
|
||||
struct io_sq_data *sqd)
|
||||
@ -9866,8 +9866,10 @@ static __cold void io_uring_cancel_generic(bool cancel_all,
|
||||
cancel_all);
|
||||
}
|
||||
|
||||
prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
|
||||
prepare_to_wait(&tctx->wait, &wait, TASK_INTERRUPTIBLE);
|
||||
io_run_task_work();
|
||||
io_uring_drop_tctx_refs(current);
|
||||
|
||||
/*
|
||||
* If we've seen completions, retry without waiting. This
|
||||
* avoids a race where a completion comes in before we did
|
||||
|
Loading…
Reference in New Issue
Block a user