Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

workqueue: Move pwq_dec_nr_in_flight() to the end of work item handling

The planned shared nr_active handling for unbound workqueues will make
pwq_dec_nr_active() sometimes drop the pool lock temporarily to acquire
other pool locks, which is necessary as retirement of an nr_active count
from one pool may need kick off an inactive work item in another pool.

This patch moves pwq_dec_nr_in_flight() call in try_to_grab_pending() to the
end of work item handling so that work item state changes stay atomic.
process_one_work() which is the other user of pwq_dec_nr_in_flight() already
calls it at the end of work item handling. Comments are added to both call
sites and pwq_dec_nr_in_flight().

This shouldn't cause any behavior changes.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>

+10 -1
+10 -1
kernel/workqueue.c
··· 1587 1587 * A work either has completed or is removed from pending queue, 1588 1588 * decrement nr_in_flight of its pwq and handle workqueue flushing. 1589 1589 * 1590 + * NOTE: 1591 + * For unbound workqueues, this function may temporarily drop @pwq->pool->lock 1592 + * and thus should be called after all other state updates for the in-flight 1593 + * work item is complete. 1594 + * 1590 1595 * CONTEXT: 1591 1596 * raw_spin_lock_irq(pool->lock). 1592 1597 */ ··· 1716 1711 pwq_activate_work(pwq, work); 1717 1712 1718 1713 list_del_init(&work->entry); 1719 - pwq_dec_nr_in_flight(pwq, *work_data_bits(work)); 1720 1714 1721 1715 /* work->data points to pwq iff queued, point to pool */ 1722 1716 set_work_pool_and_keep_pending(work, pool->id); 1717 + 1718 + /* must be the last step, see the function comment */ 1719 + pwq_dec_nr_in_flight(pwq, *work_data_bits(work)); 1723 1720 1724 1721 raw_spin_unlock(&pool->lock); 1725 1722 rcu_read_unlock(); ··· 2787 2780 worker->current_func = NULL; 2788 2781 worker->current_pwq = NULL; 2789 2782 worker->current_color = INT_MAX; 2783 + 2784 + /* must be the last step, see the function comment */ 2790 2785 pwq_dec_nr_in_flight(pwq, work_data); 2791 2786 } 2792 2787