diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h index 35eee10263c27de32953b1fb9b4288408df834b1..f96e83ffb5f622b4d75a075844455055e359ae5b 100644 --- a/include/linux/workqueue.h +++ b/include/linux/workqueue.h @@ -72,15 +72,14 @@ enum { * data contains off-queue information when !WORK_STRUCT_PWQ. * * MSB - * [ pool ID ] [ disable depth ] [ OFFQ flags ] [ STRUCT flags ] - * 16 bits 1 bit 4 or 5 bits + * [ disable depth ] [ pool ID ] [ OFFQ flags ] [ STRUCT flags ] + * 16 bits 1 bit 4 or 5 bits */ WORK_OFFQ_FLAG_SHIFT = WORK_STRUCT_FLAG_BITS, WORK_OFFQ_CANCELING_BIT = WORK_OFFQ_FLAG_SHIFT, WORK_OFFQ_FLAG_END, WORK_OFFQ_FLAG_BITS = WORK_OFFQ_FLAG_END - WORK_OFFQ_FLAG_SHIFT, - WORK_OFFQ_DISABLE_SHIFT = WORK_OFFQ_FLAG_SHIFT + WORK_OFFQ_FLAG_BITS, WORK_OFFQ_DISABLE_BITS = 16, /* @@ -88,10 +87,12 @@ enum { * and the last pool it was on. Cap pool ID to 31 bits and use the * highest number to indicate that no pool is associated. */ - WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_DISABLE_SHIFT + WORK_OFFQ_DISABLE_BITS, - WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, + WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_SHIFT + WORK_OFFQ_FLAG_BITS, + WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT - WORK_OFFQ_DISABLE_BITS, WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, + WORK_OFFQ_DISABLE_SHIFT = WORK_OFFQ_POOL_SHIFT + WORK_OFFQ_POOL_BITS, + /* bit mask for work_busy() return values */ WORK_BUSY_PENDING = 1 << 0, WORK_BUSY_RUNNING = 1 << 1, diff --git a/kernel/workqueue.c b/kernel/workqueue.c index dc9cd3b1bb5fd1ce22667873ddae73587b23ebed..b9676a628c8eb9ae65b0692836250f91144a794d 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c @@ -756,6 +756,11 @@ static struct pool_workqueue *get_work_pwq(struct work_struct *work) return NULL; } +static unsigned long shift_and_mask(unsigned long v, u32 shift, u32 bits) +{ + return (v >> shift) & ((1U << bits) - 1); +} + /** * get_work_pool - return the worker_pool a given work was associated with * @work: the work item of interest @@ -781,18 +786,13 @@ static struct worker_pool *get_work_pool(struct work_struct *work) if (data & WORK_STRUCT_PWQ) return work_struct_pwq(data)->pool; - pool_id = data >> WORK_OFFQ_POOL_SHIFT; + pool_id = shift_and_mask(data, WORK_OFFQ_POOL_SHIFT, WORK_OFFQ_POOL_BITS); if (pool_id == WORK_OFFQ_POOL_NONE) return NULL; return idr_find(&worker_pool_idr, pool_id); } -static unsigned long shift_and_mask(unsigned long v, u32 shift, u32 bits) -{ - return (v >> shift) & ((1U << bits) - 1); -} - static void work_offqd_unpack(struct work_offq_data *offqd, unsigned long data) { WARN_ON_ONCE(data & WORK_STRUCT_PWQ);