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
153153 unsigned long watchdog_ts; /* L: watchdog timestamp */
154154
155155 struct list_head worklist; /* L: list of pending works */
156− int nr_workers; /* L: total number of workers */
157156
158− /* nr_idle includes the ones off idle_list for rebinding */
159− int nr_idle; /* L: currently idle ones */
157+ int nr_workers; /* L: total number of workers */
158+ int nr_idle; /* L: currently idle workers */
160159
161160 struct list_head idle_list; /* X: list of idle workers */
162161 struct timer_list idle_timer; /* L: worker idle timeout */
@@ -166,7 +165,6 @@ struct worker_pool { · 3 unmodified lines
166165 DECLARE_HASHTABLE(busy_hash, BUSY_WORKER_HASH_ORDER);
167166 /* L: hash of busy workers */
168167
169− /* see manage_workers() for details on the two manager mutexes */
170168 struct worker *manager; /* L: purely informational */
171169 struct mutex attach_mutex; /* attach/detach exclusion */
172170 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
16041602 }
16051603 EXPORT_SYMBOL_GPL(mod_delayed_work_on);
16061604
1605+static 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+ */
1625+bool 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+}
1637+EXPORT_SYMBOL(queue_rcu_work);
1638+
16071639 /**
16081640 * worker_enter_idle - enter idle state
16091641 * @worker: worker which is entering idle state
@@ -3001,6 +3033,26 @@ bool flush_delayed_work(struct delayed_work *dwork) · 1391 unmodified lines
30013033 }
30023034 EXPORT_SYMBOL(flush_delayed_work);
30033035
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+ */
3044+bool 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+}
3054+EXPORT_SYMBOL(flush_rcu_work);
3055+
30043056 static bool __cancel_work(struct work_struct *work, bool is_dwork)
30053057 {
30063058 unsigned long flags;