Skip to content

Commit 456a78e

Browse files
committed
workqueue: Remember whether a work item was on a BH workqueue
Add an off-queue flag, WORK_OFFQ_BH, that indicates whether the last workqueue the work item was on was a BH one. This will be used to test whether a work item is BH in cancel_sync path to implement atomic cancel_sync'ing for BH work items. Signed-off-by: Tejun Heo <[email protected]> Reviewed-by: Lai Jiangshan <[email protected]>
1 parent f09b10b commit 456a78e

File tree

2 files changed

+11
-3
lines changed

2 files changed

+11
-3
lines changed

include/linux/workqueue.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ enum work_bits {
5252
*
5353
* MSB
5454
* [ pool ID ] [ disable depth ] [ OFFQ flags ] [ STRUCT flags ]
55-
* 16 bits 0 bits 4 or 5 bits
55+
* 16 bits 1 bit 4 or 5 bits
5656
*/
5757
WORK_OFFQ_FLAG_SHIFT = WORK_STRUCT_FLAG_BITS,
58+
WORK_OFFQ_BH_BIT = WORK_OFFQ_FLAG_SHIFT,
5859
WORK_OFFQ_FLAG_END,
5960
WORK_OFFQ_FLAG_BITS = WORK_OFFQ_FLAG_END - WORK_OFFQ_FLAG_SHIFT,
6061

@@ -98,6 +99,7 @@ enum wq_misc_consts {
9899
};
99100

100101
/* Convenience constants - of type 'unsigned long', not 'enum'! */
102+
#define WORK_OFFQ_BH (1ul << WORK_OFFQ_BH_BIT)
101103
#define WORK_OFFQ_FLAG_MASK (((1ul << WORK_OFFQ_FLAG_BITS) - 1) << WORK_OFFQ_FLAG_SHIFT)
102104
#define WORK_OFFQ_DISABLE_MASK (((1ul << WORK_OFFQ_DISABLE_BITS) - 1) << WORK_OFFQ_DISABLE_SHIFT)
103105
#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1)

kernel/workqueue.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,11 @@ static int work_next_color(int color)
764764
return (color + 1) % WORK_NR_COLORS;
765765
}
766766

767+
static unsigned long pool_offq_flags(struct worker_pool *pool)
768+
{
769+
return (pool->flags & POOL_BH) ? WORK_OFFQ_BH : 0;
770+
}
771+
767772
/*
768773
* While queued, %WORK_STRUCT_PWQ is set and non flag bits of a work's data
769774
* contain the pointer to the queued pwq. Once execution starts, the flag
@@ -2122,7 +2127,8 @@ static int try_to_grab_pending(struct work_struct *work, u32 cflags,
21222127
* this destroys work->data needed by the next step, stash it.
21232128
*/
21242129
work_data = *work_data_bits(work);
2125-
set_work_pool_and_keep_pending(work, pool->id, 0);
2130+
set_work_pool_and_keep_pending(work, pool->id,
2131+
pool_offq_flags(pool));
21262132

21272133
/* must be the last step, see the function comment */
21282134
pwq_dec_nr_in_flight(pwq, work_data);
@@ -3175,7 +3181,7 @@ __acquires(&pool->lock)
31753181
* PENDING and queued state changes happen together while IRQ is
31763182
* disabled.
31773183
*/
3178-
set_work_pool_and_clear_pending(work, pool->id, 0);
3184+
set_work_pool_and_clear_pending(work, pool->id, pool_offq_flags(pool));
31793185

31803186
pwq->stats[PWQ_STAT_STARTED]++;
31813187
raw_spin_unlock_irq(&pool->lock);

0 commit comments

Comments
 (0)