aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/workqueue.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 48becaba1c94..d2fe8e77ceb7 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -977,10 +977,9 @@ static void move_linked_works(struct work_struct *work, struct list_head *head,
977 *nextp = n; 977 *nextp = n;
978} 978}
979 979
980static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq) 980static void cwq_activate_delayed_work(struct work_struct *work)
981{ 981{
982 struct work_struct *work = list_first_entry(&cwq->delayed_works, 982 struct cpu_workqueue_struct *cwq = get_work_cwq(work);
983 struct work_struct, entry);
984 983
985 trace_workqueue_activate_work(work); 984 trace_workqueue_activate_work(work);
986 move_linked_works(work, &cwq->pool->worklist, NULL); 985 move_linked_works(work, &cwq->pool->worklist, NULL);
@@ -988,6 +987,14 @@ static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq)
988 cwq->nr_active++; 987 cwq->nr_active++;
989} 988}
990 989
990static void cwq_activate_first_delayed(struct cpu_workqueue_struct *cwq)
991{
992 struct work_struct *work = list_first_entry(&cwq->delayed_works,
993 struct work_struct, entry);
994
995 cwq_activate_delayed_work(work);
996}
997
991/** 998/**
992 * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight 999 * cwq_dec_nr_in_flight - decrement cwq's nr_in_flight
993 * @cwq: cwq of interest 1000 * @cwq: cwq of interest
@@ -1106,6 +1113,18 @@ static int try_to_grab_pending(struct work_struct *work, bool is_dwork,
1106 smp_rmb(); 1113 smp_rmb();
1107 if (gcwq == get_work_gcwq(work)) { 1114 if (gcwq == get_work_gcwq(work)) {
1108 debug_work_deactivate(work); 1115 debug_work_deactivate(work);
1116
1117 /*
1118 * A delayed work item cannot be grabbed directly
1119 * because it might have linked NO_COLOR work items
1120 * which, if left on the delayed_list, will confuse
1121 * cwq->nr_active management later on and cause
1122 * stall. Make sure the work item is activated
1123 * before grabbing.
1124 */
1125 if (*work_data_bits(work) & WORK_STRUCT_DELAYED)
1126 cwq_activate_delayed_work(work);
1127
1109 list_del_init(&work->entry); 1128 list_del_init(&work->entry);
1110 cwq_dec_nr_in_flight(get_work_cwq(work), 1129 cwq_dec_nr_in_flight(get_work_cwq(work),
1111 get_work_color(work), 1130 get_work_color(work),