Commit e9a8e01f authored by Tejun Heo's avatar Tejun Heo

workqueue: Clean up enum work_bits and related constants

The bits of work->data are used for a few different purposes. How the bits
are used is determined by enum work_bits. The planned disable/enable support
will add another use, so let's clean it up a bit in preparation.

- Let WORK_STRUCT_*_BIT's values be determined by enum definition order.

- Deliminate different bit sections the same way using SHIFT and BITS
  values.

- Rename __WORK_OFFQ_CANCELING to WORK_OFFQ_CANCELING_BIT for consistency.

- Introduce WORK_STRUCT_PWQ_SHIFT and replace WORK_STRUCT_FLAG_MASK and
  WORK_STRUCT_WQ_DATA_MASK with WQ_STRUCT_PWQ_MASK for clarity.

- Improve documentation.

No functional changes.
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
Reviewed-by: default avatarLai Jiangshan <jiangshanlai@gmail.com>
parent c5f5b942
...@@ -24,41 +24,49 @@ ...@@ -24,41 +24,49 @@
enum work_bits { enum work_bits {
WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */ WORK_STRUCT_PENDING_BIT = 0, /* work item is pending execution */
WORK_STRUCT_INACTIVE_BIT= 1, /* work item is inactive */ WORK_STRUCT_INACTIVE_BIT, /* work item is inactive */
WORK_STRUCT_PWQ_BIT = 2, /* data points to pwq */ WORK_STRUCT_PWQ_BIT, /* data points to pwq */
WORK_STRUCT_LINKED_BIT = 3, /* next work is linked to this one */ WORK_STRUCT_LINKED_BIT, /* next work is linked to this one */
#ifdef CONFIG_DEBUG_OBJECTS_WORK #ifdef CONFIG_DEBUG_OBJECTS_WORK
WORK_STRUCT_STATIC_BIT = 4, /* static initializer (debugobjects) */ WORK_STRUCT_STATIC_BIT, /* static initializer (debugobjects) */
WORK_STRUCT_COLOR_SHIFT = 5, /* color for workqueue flushing */
#else
WORK_STRUCT_COLOR_SHIFT = 4, /* color for workqueue flushing */
#endif #endif
WORK_STRUCT_FLAG_BITS,
/* color for workqueue flushing */
WORK_STRUCT_COLOR_SHIFT = WORK_STRUCT_FLAG_BITS,
WORK_STRUCT_COLOR_BITS = 4, WORK_STRUCT_COLOR_BITS = 4,
/* /*
* Reserve 8 bits off of pwq pointer w/ debugobjects turned off. * When WORK_STRUCT_PWQ is set, reserve 8 bits off of pwq pointer w/
* This makes pwqs aligned to 256 bytes and allows 16 workqueue * debugobjects turned off. This makes pwqs aligned to 256 bytes (512
* flush colors. * bytes w/ DEBUG_OBJECTS_WORK) and allows 16 workqueue flush colors.
*
* MSB
* [ pwq pointer ] [ flush color ] [ STRUCT flags ]
* 4 bits 4 or 5 bits
*/ */
WORK_STRUCT_FLAG_BITS = WORK_STRUCT_COLOR_SHIFT + WORK_STRUCT_PWQ_SHIFT = WORK_STRUCT_COLOR_SHIFT + WORK_STRUCT_COLOR_BITS,
WORK_STRUCT_COLOR_BITS,
/* data contains off-queue information when !WORK_STRUCT_PWQ */ /*
WORK_OFFQ_FLAG_BASE = WORK_STRUCT_COLOR_SHIFT, * data contains off-queue information when !WORK_STRUCT_PWQ.
*
__WORK_OFFQ_CANCELING = WORK_OFFQ_FLAG_BASE, * MSB
* [ pool ID ] [ OFFQ flags ] [ STRUCT flags ]
* 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,
/* /*
* When a work item is off queue, its high bits point to the last * When a work item is off queue, the high bits encode off-queue flags
* pool it was on. Cap at 31 bits and use the highest number to * and the last pool it was on. Cap pool ID to 31 bits and use the
* indicate that no pool is associated. * highest number to indicate that no pool is associated.
*/ */
WORK_OFFQ_FLAG_BITS = 1, WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_SHIFT + WORK_OFFQ_FLAG_BITS,
WORK_OFFQ_POOL_SHIFT = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT, WORK_OFFQ_LEFT = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31, WORK_OFFQ_POOL_BITS = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
}; };
enum work_flags { enum work_flags {
...@@ -88,12 +96,10 @@ enum wq_misc_consts { ...@@ -88,12 +96,10 @@ enum wq_misc_consts {
}; };
/* Convenience constants - of type 'unsigned long', not 'enum'! */ /* Convenience constants - of type 'unsigned long', not 'enum'! */
#define WORK_OFFQ_CANCELING (1ul << __WORK_OFFQ_CANCELING) #define WORK_OFFQ_CANCELING (1ul << WORK_OFFQ_CANCELING_BIT)
#define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1) #define WORK_OFFQ_POOL_NONE ((1ul << WORK_OFFQ_POOL_BITS) - 1)
#define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT) #define WORK_STRUCT_NO_POOL (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
#define WORK_STRUCT_PWQ_MASK (~((1ul << WORK_STRUCT_PWQ_SHIFT) - 1))
#define WORK_STRUCT_FLAG_MASK ((1ul << WORK_STRUCT_FLAG_BITS) - 1)
#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
#define WORK_DATA_INIT() ATOMIC_LONG_INIT((unsigned long)WORK_STRUCT_NO_POOL) #define WORK_DATA_INIT() ATOMIC_LONG_INIT((unsigned long)WORK_STRUCT_NO_POOL)
#define WORK_DATA_STATIC_INIT() \ #define WORK_DATA_STATIC_INIT() \
......
...@@ -247,7 +247,7 @@ enum pool_workqueue_stats { ...@@ -247,7 +247,7 @@ enum pool_workqueue_stats {
}; };
/* /*
* The per-pool workqueue. While queued, the lower WORK_STRUCT_FLAG_BITS * The per-pool workqueue. While queued, bits below WORK_PWQ_SHIFT
* of work_struct->data are used for flags and the remaining high bits * of work_struct->data are used for flags and the remaining high bits
* point to the pwq; thus, pwqs need to be aligned at two's power of the * point to the pwq; thus, pwqs need to be aligned at two's power of the
* number of flag bits. * number of flag bits.
...@@ -294,7 +294,7 @@ struct pool_workqueue { ...@@ -294,7 +294,7 @@ struct pool_workqueue {
*/ */
struct kthread_work release_work; struct kthread_work release_work;
struct rcu_head rcu; struct rcu_head rcu;
} __aligned(1 << WORK_STRUCT_FLAG_BITS); } __aligned(1 << WORK_STRUCT_PWQ_SHIFT);
/* /*
* Structure used to wait for workqueue flush. * Structure used to wait for workqueue flush.
...@@ -843,7 +843,7 @@ static void clear_work_data(struct work_struct *work) ...@@ -843,7 +843,7 @@ static void clear_work_data(struct work_struct *work)
static inline struct pool_workqueue *work_struct_pwq(unsigned long data) static inline struct pool_workqueue *work_struct_pwq(unsigned long data)
{ {
return (struct pool_workqueue *)(data & WORK_STRUCT_WQ_DATA_MASK); return (struct pool_workqueue *)(data & WORK_STRUCT_PWQ_MASK);
} }
static struct pool_workqueue *get_work_pwq(struct work_struct *work) static struct pool_workqueue *get_work_pwq(struct work_struct *work)
...@@ -4851,7 +4851,7 @@ static void pwq_release_workfn(struct kthread_work *work) ...@@ -4851,7 +4851,7 @@ static void pwq_release_workfn(struct kthread_work *work)
static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq, static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq,
struct worker_pool *pool) struct worker_pool *pool)
{ {
BUG_ON((unsigned long)pwq & WORK_STRUCT_FLAG_MASK); BUG_ON((unsigned long)pwq & ~WORK_STRUCT_PWQ_MASK);
memset(pwq, 0, sizeof(*pwq)); memset(pwq, 0, sizeof(*pwq));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment