diff options
author | Tejun Heo <tj@kernel.org> | 2024-03-25 18:21:03 +0100 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2024-03-25 18:21:03 +0100 |
commit | 134874e2eee9380c2700411d4844cbc29297bc01 (patch) | |
tree | ee79520ba6213eebefac269a1762f49bda1045ca /drivers/soc | |
parent | workqueue: Remember whether a work item was on a BH workqueue (diff) | |
download | linux-134874e2eee9380c2700411d4844cbc29297bc01.tar.xz linux-134874e2eee9380c2700411d4844cbc29297bc01.zip |
workqueue: Allow cancel_work_sync() and disable_work() from atomic contexts on BH work items
Now that work_grab_pending() can always grab the PENDING bit without
sleeping, the only thing that prevents allowing cancel_work_sync() of a BH
work item from an atomic context is the flushing of the in-flight instance.
When we're flushing a BH work item for cancel_work_sync(), we know that the
work item is not queued and must be executing in a BH context, which means
that it's safe to busy-wait for its completion from a non-hardirq atomic
context.
This patch updates __flush_work() so that it busy-waits when flushing a BH
work item for cancel_work_sync(). might_sleep() is pushed from
start_flush_work() to its callers - when operating on a BH work item,
__cancel_work_sync() now enforces !in_hardirq() instead of might_sleep().
This allows cancel_work_sync() and disable_work() to be called from
non-hardirq atomic contexts on BH work items.
v3: In __flush_work(), test WORK_OFFQ_BH to tell whether a work item being
canceled can be busy waited instead of making start_flush_work() return
the pool. (Lai)
v2: Lai pointed out that __flush_work() was accessing pool->flags outside
the RCU critical section protecting the pool pointer. Fix it by testing
and remembering the result inside the RCU critical section.
Signed-off-by: Tejun Heo <tj@kernel.org>
Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>
Diffstat (limited to 'drivers/soc')
0 files changed, 0 insertions, 0 deletions