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_wqe_acct *acct,
|
||||||
struct io_cb_cancel_data *match);
|
struct io_cb_cancel_data *match);
|
||||||
static void create_worker_cb(struct callback_head *cb);
|
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)
|
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))
|
test_and_set_bit_lock(0, &worker->create_state))
|
||||||
goto fail_release;
|
goto fail_release;
|
||||||
|
|
||||||
|
atomic_inc(&wq->worker_refs);
|
||||||
init_task_work(&worker->create_work, func);
|
init_task_work(&worker->create_work, func);
|
||||||
worker->create_index = acct->index;
|
worker->create_index = acct->index;
|
||||||
if (!task_work_add(wq->task, &worker->create_work, TWA_SIGNAL)) {
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
io_worker_ref_put(wq);
|
||||||
clear_bit_unlock(0, &worker->create_state);
|
clear_bit_unlock(0, &worker->create_state);
|
||||||
fail_release:
|
fail_release:
|
||||||
io_worker_release(worker);
|
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);
|
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;
|
struct callback_head *cb;
|
||||||
int node;
|
|
||||||
|
|
||||||
if (!wq->task)
|
|
||||||
return;
|
|
||||||
|
|
||||||
while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) {
|
while ((cb = task_work_cancel_match(wq->task, io_task_work_match, wq)) != NULL) {
|
||||||
struct io_worker *worker;
|
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);
|
worker = container_of(cb, struct io_worker, create_work);
|
||||||
io_worker_cancel_cb(worker);
|
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();
|
rcu_read_lock();
|
||||||
for_each_node(node) {
|
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
|
* 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,
|
static __cold void io_uring_cancel_generic(bool cancel_all,
|
||||||
struct io_sq_data *sqd)
|
struct io_sq_data *sqd)
|
||||||
@ -9866,8 +9866,10 @@ static __cold void io_uring_cancel_generic(bool cancel_all,
|
|||||||
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);
|
io_uring_drop_tctx_refs(current);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we've seen completions, retry without waiting. This
|
* If we've seen completions, retry without waiting. This
|
||||||
* avoids a race where a completion comes in before we did
|
* avoids a race where a completion comes in before we did
|
||||||
|
Loading…
Reference in New Issue
Block a user