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: 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 <tj@kernel.org>
Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>

+11 -3
+3 -1
include/linux/workqueue.h
··· 52 52 * 53 53 * MSB 54 54 * [ 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 56 56 */ 57 57 WORK_OFFQ_FLAG_SHIFT = WORK_STRUCT_FLAG_BITS, 58 + WORK_OFFQ_BH_BIT = WORK_OFFQ_FLAG_SHIFT, 58 59 WORK_OFFQ_FLAG_END, 59 60 WORK_OFFQ_FLAG_BITS = WORK_OFFQ_FLAG_END - WORK_OFFQ_FLAG_SHIFT, 60 61 ··· 99 98 }; 100 99 101 100 /* Convenience constants - of type 'unsigned long', not 'enum'! */ 101 + #define WORK_OFFQ_BH (1ul << WORK_OFFQ_BH_BIT) 102 102 #define WORK_OFFQ_FLAG_MASK (((1ul << WORK_OFFQ_FLAG_BITS) - 1) << WORK_OFFQ_FLAG_SHIFT) 103 103 #define WORK_OFFQ_DISABLE_MASK (((1ul << WORK_OFFQ_DISABLE_BITS) - 1) << WORK_OFFQ_DISABLE_SHIFT) 104 104 #define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1)
+8 -2
kernel/workqueue.c
··· 764 764 return (color + 1) % WORK_NR_COLORS; 765 765 } 766 766 767 + static unsigned long pool_offq_flags(struct worker_pool *pool) 768 + { 769 + return (pool->flags & POOL_BH) ? WORK_OFFQ_BH : 0; 770 + } 771 + 767 772 /* 768 773 * While queued, %WORK_STRUCT_PWQ is set and non flag bits of a work's data 769 774 * contain the pointer to the queued pwq. Once execution starts, the flag ··· 2127 2122 * this destroys work->data needed by the next step, stash it. 2128 2123 */ 2129 2124 work_data = *work_data_bits(work); 2130 - set_work_pool_and_keep_pending(work, pool->id, 0); 2125 + set_work_pool_and_keep_pending(work, pool->id, 2126 + pool_offq_flags(pool)); 2131 2127 2132 2128 /* must be the last step, see the function comment */ 2133 2129 pwq_dec_nr_in_flight(pwq, work_data); ··· 3181 3175 * PENDING and queued state changes happen together while IRQ is 3182 3176 * disabled. 3183 3177 */ 3184 - set_work_pool_and_clear_pending(work, pool->id, 0); 3178 + set_work_pool_and_clear_pending(work, pool->id, pool_offq_flags(pool)); 3185 3179 3186 3180 pwq->stats[PWQ_STAT_STARTED]++; 3187 3181 raw_spin_unlock_irq(&pool->lock);