History

Merge branch 'for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq

Pull workqueue updates from Tejun Heo: "rcu_work addition and a couple trivial changes" * 'for-4.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq: workqueue: remove the comment about the old manager_arb mutex workqueue: fix the comments of nr_idle fs/aio: Use rcu_work instead of explicit rcu and work item cgroup: Use rcu_work instead of explicit rcu and work item RCU, workqueue: Implement rcu_work

Linus Torvalds committed 8 years ago

Commit d92cd812 parents a23867f f75da8a5 files · +93 −34Browse files

Showing the changes to kernel/workqueue.c (1 of 5 files). Show all

Unified · Split

kernel/workqueue.c+56−4
@@ -153,10 +153,9 @@ struct worker_pool { · 152 unmodified lines
153 unsigned long watchdog_ts; /* L: watchdog timestamp */153 unsigned long watchdog_ts; /* L: watchdog timestamp */
154 154
155 struct list_head worklist; /* L: list of pending works */155 struct list_head worklist; /* L: list of pending works */
156 int nr_workers; /* L: total number of workers */
157 156
158 /* nr_idle includes the ones off idle_list for rebinding */157 int nr_workers; /* L: total number of workers */
159 int nr_idle; /* L: currently idle ones */158 int nr_idle; /* L: currently idle workers */
160 159
161 struct list_head idle_list; /* X: list of idle workers */160 struct list_head idle_list; /* X: list of idle workers */
162 struct timer_list idle_timer; /* L: worker idle timeout */161 struct timer_list idle_timer; /* L: worker idle timeout */
@@ -166,7 +165,6 @@ struct worker_pool { · 3 unmodified lines
166 DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);165 DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);
167 /* L: hash of busy workers */166 /* L: hash of busy workers */
168 167
169 /* see manage_workers() for details on the two manager mutexes */
170 struct worker *manager; /* L: purely informational */168 struct worker *manager; /* L: purely informational */
171 struct mutex attach_mutex; /* attach/detach exclusion */169 struct mutex attach_mutex; /* attach/detach exclusion */
172 struct list_head workers; /* A: attached workers */170 struct list_head workers; /* A: attached workers */
@@ -1604,6 +1602,40 @@ bool mod_delayed_work_on(int cpu, struct workqueue_struct *wq, · 1431 unmodified lines
1604}1602}
1605EXPORT_SYMBOL_GPL(mod_delayed_work_on);1603EXPORT_SYMBOL_GPL(mod_delayed_work_on);
1606 1604
1605static void rcu_work_rcufn(struct rcu_head *rcu)
1606{
1607 struct rcu_work *rwork = container_of(rcu, struct rcu_work, rcu);
1608
1609 /* read the comment in __queue_work() */
1610 local_irq_disable();
1611 __queue_work(WORK_CPU_UNBOUND, rwork->wq, &rwork->work);
1612 local_irq_enable();
1613}
1614
1615/**
1616 * queue_rcu_work - queue work after a RCU grace period
1617 * @wq: workqueue to use
1618 * @rwork: work to queue
1619 *
1620 * Return: %false if @rwork was already pending, %true otherwise. Note
1621 * that a full RCU grace period is guaranteed only after a %true return.
1622 * While @rwork is guarnateed to be executed after a %false return, the
1623 * execution may happen before a full RCU grace period has passed.
1624 */
1625bool queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork)
1626{
1627 struct work_struct *work = &rwork->work;
1628
1629 if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) {
1630 rwork->wq = wq;
1631 call_rcu(&rwork->rcu, rcu_work_rcufn);
1632 return true;
1633 }
1634
1635 return false;
1636}
1637EXPORT_SYMBOL(queue_rcu_work);
1638
1607/**1639/**
1608 * worker_enter_idle - enter idle state1640 * worker_enter_idle - enter idle state
1609 * @worker: worker which is entering idle state1641 * @worker: worker which is entering idle state
@@ -3001,6 +3033,26 @@ bool flush_delayed_work(struct delayed_work *dwork) · 1391 unmodified lines
3001}3033}
3002EXPORT_SYMBOL(flush_delayed_work);3034EXPORT_SYMBOL(flush_delayed_work);
3003 3035
3036/**
3037 * flush_rcu_work - wait for a rwork to finish executing the last queueing
3038 * @rwork: the rcu work to flush
3039 *
3040 * Return:
3041 * %true if flush_rcu_work() waited for the work to finish execution,
3042 * %false if it was already idle.
3043 */
3044bool flush_rcu_work(struct rcu_work *rwork)
3045{
3046 if (test_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(&rwork->work))) {
3047 rcu_barrier();
3048 flush_work(&rwork->work);
3049 return true;
3050 } else {
3051 return flush_work(&rwork->work);
3052 }
3053}
3054EXPORT_SYMBOL(flush_rcu_work);
3055
3004static bool __cancel_work(struct work_struct *work, bool is_dwork)3056static bool __cancel_work(struct work_struct *work, bool is_dwork)
3005{3057{
3006 unsigned long flags;3058 unsigned long flags;