io-wq: shuffle io_worker_handle_work() code
This is a preparation patch, it adds some helpers and makes the next patches cleaner. - extract io_impersonate_work() and io_assign_current_work() - replace @next label with nested do-while - move put_work() right after NULL'ing cur_work. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
7a743e225b
commit
dc026a73c7
85
fs/io-wq.c
85
fs/io-wq.c
|
@ -440,14 +440,43 @@ static void io_wq_switch_creds(struct io_worker *worker,
|
||||||
worker->saved_creds = old_creds;
|
worker->saved_creds = old_creds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void io_impersonate_work(struct io_worker *worker,
|
||||||
|
struct io_wq_work *work)
|
||||||
|
{
|
||||||
|
if (work->files && current->files != work->files) {
|
||||||
|
task_lock(current);
|
||||||
|
current->files = work->files;
|
||||||
|
task_unlock(current);
|
||||||
|
}
|
||||||
|
if (work->fs && current->fs != work->fs)
|
||||||
|
current->fs = work->fs;
|
||||||
|
if (work->mm != worker->mm)
|
||||||
|
io_wq_switch_mm(worker, work);
|
||||||
|
if (worker->cur_creds != work->creds)
|
||||||
|
io_wq_switch_creds(worker, work);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void io_assign_current_work(struct io_worker *worker,
|
||||||
|
struct io_wq_work *work)
|
||||||
|
{
|
||||||
|
/* flush pending signals before assigning new work */
|
||||||
|
if (signal_pending(current))
|
||||||
|
flush_signals(current);
|
||||||
|
cond_resched();
|
||||||
|
|
||||||
|
spin_lock_irq(&worker->lock);
|
||||||
|
worker->cur_work = work;
|
||||||
|
spin_unlock_irq(&worker->lock);
|
||||||
|
}
|
||||||
|
|
||||||
static void io_worker_handle_work(struct io_worker *worker)
|
static void io_worker_handle_work(struct io_worker *worker)
|
||||||
__releases(wqe->lock)
|
__releases(wqe->lock)
|
||||||
{
|
{
|
||||||
struct io_wq_work *work, *old_work = NULL, *put_work = NULL;
|
|
||||||
struct io_wqe *wqe = worker->wqe;
|
struct io_wqe *wqe = worker->wqe;
|
||||||
struct io_wq *wq = wqe->wq;
|
struct io_wq *wq = wqe->wq;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
struct io_wq_work *work, *old_work;
|
||||||
unsigned hash = -1U;
|
unsigned hash = -1U;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -464,43 +493,23 @@ static void io_worker_handle_work(struct io_worker *worker)
|
||||||
wqe->flags |= IO_WQE_FLAG_STALLED;
|
wqe->flags |= IO_WQE_FLAG_STALLED;
|
||||||
|
|
||||||
spin_unlock_irq(&wqe->lock);
|
spin_unlock_irq(&wqe->lock);
|
||||||
if (put_work && wq->put_work)
|
|
||||||
wq->put_work(old_work);
|
|
||||||
if (!work)
|
if (!work)
|
||||||
break;
|
break;
|
||||||
next:
|
|
||||||
/* flush any pending signals before assigning new work */
|
|
||||||
if (signal_pending(current))
|
|
||||||
flush_signals(current);
|
|
||||||
|
|
||||||
cond_resched();
|
/* handle a whole dependent link */
|
||||||
|
do {
|
||||||
|
io_assign_current_work(worker, work);
|
||||||
|
io_impersonate_work(worker, work);
|
||||||
|
|
||||||
spin_lock_irq(&worker->lock);
|
|
||||||
worker->cur_work = work;
|
|
||||||
spin_unlock_irq(&worker->lock);
|
|
||||||
|
|
||||||
if (work->files && current->files != work->files) {
|
|
||||||
task_lock(current);
|
|
||||||
current->files = work->files;
|
|
||||||
task_unlock(current);
|
|
||||||
}
|
|
||||||
if (work->fs && current->fs != work->fs)
|
|
||||||
current->fs = work->fs;
|
|
||||||
if (work->mm != worker->mm)
|
|
||||||
io_wq_switch_mm(worker, work);
|
|
||||||
if (worker->cur_creds != work->creds)
|
|
||||||
io_wq_switch_creds(worker, work);
|
|
||||||
/*
|
/*
|
||||||
* OK to set IO_WQ_WORK_CANCEL even for uncancellable work,
|
* OK to set IO_WQ_WORK_CANCEL even for uncancellable
|
||||||
* the worker function will do the right thing.
|
* work, the worker function will do the right thing.
|
||||||
*/
|
*/
|
||||||
if (test_bit(IO_WQ_BIT_CANCEL, &wq->state))
|
if (test_bit(IO_WQ_BIT_CANCEL, &wq->state))
|
||||||
work->flags |= IO_WQ_WORK_CANCEL;
|
work->flags |= IO_WQ_WORK_CANCEL;
|
||||||
|
|
||||||
if (wq->get_work) {
|
if (wq->get_work)
|
||||||
put_work = work;
|
|
||||||
wq->get_work(work);
|
wq->get_work(work);
|
||||||
}
|
|
||||||
|
|
||||||
old_work = work;
|
old_work = work;
|
||||||
work->func(&work);
|
work->func(&work);
|
||||||
|
@ -509,24 +518,20 @@ next:
|
||||||
worker->cur_work = NULL;
|
worker->cur_work = NULL;
|
||||||
spin_unlock_irq(&worker->lock);
|
spin_unlock_irq(&worker->lock);
|
||||||
|
|
||||||
spin_lock_irq(&wqe->lock);
|
if (wq->put_work)
|
||||||
|
wq->put_work(old_work);
|
||||||
|
|
||||||
if (hash != -1U) {
|
if (hash != -1U) {
|
||||||
wqe->hash_map &= ~BIT(hash);
|
spin_lock_irq(&wqe->lock);
|
||||||
|
wqe->hash_map &= ~BIT_ULL(hash);
|
||||||
wqe->flags &= ~IO_WQE_FLAG_STALLED;
|
wqe->flags &= ~IO_WQE_FLAG_STALLED;
|
||||||
}
|
|
||||||
if (work && work != old_work) {
|
|
||||||
spin_unlock_irq(&wqe->lock);
|
spin_unlock_irq(&wqe->lock);
|
||||||
|
/* dependent work is not hashed */
|
||||||
if (put_work && wq->put_work) {
|
|
||||||
wq->put_work(put_work);
|
|
||||||
put_work = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* dependent work not hashed */
|
|
||||||
hash = -1U;
|
hash = -1U;
|
||||||
goto next;
|
|
||||||
}
|
}
|
||||||
|
} while (work && work != old_work);
|
||||||
|
|
||||||
|
spin_lock_irq(&wqe->lock);
|
||||||
} while (1);
|
} while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue