File tree Expand file tree Collapse file tree 2 files changed +26
-5
lines changed Expand file tree Collapse file tree 2 files changed +26
-5
lines changed Original file line number Diff line number Diff line change @@ -491,26 +491,46 @@ static void io_worker_handle_work(struct io_worker *worker)
491
491
} while (1 );
492
492
}
493
493
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
+
494
507
static int io_wqe_worker (void * data )
495
508
{
496
509
struct io_worker * worker = data ;
497
510
struct io_wqe * wqe = worker -> wqe ;
498
511
struct io_wq * wq = wqe -> wq ;
512
+ bool did_work ;
499
513
500
514
io_worker_start (wqe , worker );
501
515
516
+ did_work = false;
502
517
while (!test_bit (IO_WQ_BIT_EXIT , & wq -> state )) {
503
518
set_current_state (TASK_INTERRUPTIBLE );
519
+ loop :
520
+ if (did_work )
521
+ io_worker_spin_for_work (wqe );
504
522
spin_lock_irq (& wqe -> lock );
505
523
if (io_wqe_run_queue (wqe )) {
506
524
__set_current_state (TASK_RUNNING );
507
525
io_worker_handle_work (worker );
508
- continue ;
526
+ did_work = true;
527
+ goto loop ;
509
528
}
529
+ did_work = false;
510
530
/* drops the lock on success, retry */
511
531
if (__io_worker_idle (wqe , worker )) {
512
532
__release (& wqe -> lock );
513
- continue ;
533
+ goto loop ;
514
534
}
515
535
spin_unlock_irq (& wqe -> lock );
516
536
if (signal_pending (current ))
Original file line number Diff line number Diff line change @@ -35,7 +35,8 @@ static inline void wq_list_add_tail(struct io_wq_work_node *node,
35
35
struct io_wq_work_list * list )
36
36
{
37
37
if (!list -> first ) {
38
- list -> first = list -> last = node ;
38
+ list -> last = node ;
39
+ WRITE_ONCE (list -> first , node );
39
40
} else {
40
41
list -> last -> next = node ;
41
42
list -> last = node ;
@@ -47,7 +48,7 @@ static inline void wq_node_del(struct io_wq_work_list *list,
47
48
struct io_wq_work_node * prev )
48
49
{
49
50
if (node == list -> first )
50
- list -> first = node -> next ;
51
+ WRITE_ONCE ( list -> first , node -> next ) ;
51
52
if (node == list -> last )
52
53
list -> last = prev ;
53
54
if (prev )
@@ -58,7 +59,7 @@ static inline void wq_node_del(struct io_wq_work_list *list,
58
59
#define wq_list_for_each (pos , prv , head ) \
59
60
for (pos = (head)->first, prv = NULL; pos; prv = pos, pos = (pos)->next)
60
61
61
- #define wq_list_empty (list ) (( list)->first == NULL)
62
+ #define wq_list_empty (list ) (READ_ONCE(( list)->first) == NULL)
62
63
#define INIT_WQ_LIST (list ) do { \
63
64
(list)->first = NULL; \
64
65
(list)->last = NULL; \
You can’t perform that action at this time.
0 commit comments