Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e995d51

Browse files
committed
io-wq: briefly spin for new work after finishing work
To avoid going to sleep only to get woken shortly thereafter, spin briefly for new work upon completion of work. Signed-off-by: Jens Axboe <[email protected]>
1 parent 506d95f commit e995d51

File tree

2 files changed

+26
-5
lines changed

2 files changed

+26
-5
lines changed

fs/io-wq.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,26 +491,46 @@ static void io_worker_handle_work(struct io_worker *worker)
491491
} while (1);
492492
}
493493

494+
static inline void io_worker_spin_for_work(struct io_wqe *wqe)
495+
{
496+
int i = 0;
497+
498+
while (++i < 1000) {
499+
if (io_wqe_run_queue(wqe))
500+
break;
501+
if (need_resched())
502+
break;
503+
cpu_relax();
504+
}
505+
}
506+
494507
static int io_wqe_worker(void *data)
495508
{
496509
struct io_worker *worker = data;
497510
struct io_wqe *wqe = worker->wqe;
498511
struct io_wq *wq = wqe->wq;
512+
bool did_work;
499513

500514
io_worker_start(wqe, worker);
501515

516+
did_work = false;
502517
while (!test_bit(IO_WQ_BIT_EXIT, &wq->state)) {
503518
set_current_state(TASK_INTERRUPTIBLE);
519+
loop:
520+
if (did_work)
521+
io_worker_spin_for_work(wqe);
504522
spin_lock_irq(&wqe->lock);
505523
if (io_wqe_run_queue(wqe)) {
506524
__set_current_state(TASK_RUNNING);
507525
io_worker_handle_work(worker);
508-
continue;
526+
did_work = true;
527+
goto loop;
509528
}
529+
did_work = false;
510530
/* drops the lock on success, retry */
511531
if (__io_worker_idle(wqe, worker)) {
512532
__release(&wqe->lock);
513-
continue;
533+
goto loop;
514534
}
515535
spin_unlock_irq(&wqe->lock);
516536
if (signal_pending(current))

fs/io-wq.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ static inline void wq_list_add_tail(struct io_wq_work_node *node,
3535
struct io_wq_work_list *list)
3636
{
3737
if (!list->first) {
38-
list->first = list->last = node;
38+
list->last = node;
39+
WRITE_ONCE(list->first, node);
3940
} else {
4041
list->last->next = node;
4142
list->last = node;
@@ -47,7 +48,7 @@ static inline void wq_node_del(struct io_wq_work_list *list,
4748
struct io_wq_work_node *prev)
4849
{
4950
if (node == list->first)
50-
list->first = node->next;
51+
WRITE_ONCE(list->first, node->next);
5152
if (node == list->last)
5253
list->last = prev;
5354
if (prev)
@@ -58,7 +59,7 @@ static inline void wq_node_del(struct io_wq_work_list *list,
5859
#define wq_list_for_each(pos, prv, head) \
5960
for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
6061

61-
#define wq_list_empty(list) ((list)->first == NULL)
62+
#define wq_list_empty(list) (READ_ONCE((list)->first) == NULL)
6263
#define INIT_WQ_LIST(list) do { \
6364
(list)->first = NULL; \
6465
(list)->last = NULL; \

0 commit comments

Comments
 (0)