workqueue: Clean up enum work_bits and related constants
authorTejun Heo <tj@kernel.org>
Wed, 21 Feb 2024 05:36:14 +0000 (19:36 -1000)
committerTejun Heo <tj@kernel.org>
Wed, 21 Feb 2024 05:36:14 +0000 (19:36 -1000)
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: Tejun Heo <tj@kernel.org>
Reviewed-by: Lai Jiangshan <jiangshanlai@gmail.com>
include/linux/workqueue.h
kernel/workqueue.c

index 1565bab9edc8a83d517cad999c7c388b61b85162..0ad534fe6673cc18caaf6b4b2c4bc2082f4adeea 100644 (file)
 
 enum work_bits {
        WORK_STRUCT_PENDING_BIT = 0,    /* work item is pending execution */
-       WORK_STRUCT_INACTIVE_BIT= 1,    /* work item is inactive */
-       WORK_STRUCT_PWQ_BIT     = 2,    /* data points to pwq */
-       WORK_STRUCT_LINKED_BIT  = 3,    /* next work is linked to this one */
+       WORK_STRUCT_INACTIVE_BIT,       /* work item is inactive */
+       WORK_STRUCT_PWQ_BIT,            /* data points to pwq */
+       WORK_STRUCT_LINKED_BIT,         /* next work is linked to this one */
 #ifdef CONFIG_DEBUG_OBJECTS_WORK
-       WORK_STRUCT_STATIC_BIT  = 4,    /* static initializer (debugobjects) */
-       WORK_STRUCT_COLOR_SHIFT = 5,    /* color for workqueue flushing */
-#else
-       WORK_STRUCT_COLOR_SHIFT = 4,    /* color for workqueue flushing */
+       WORK_STRUCT_STATIC_BIT,         /* static initializer (debugobjects) */
 #endif
+       WORK_STRUCT_FLAG_BITS,
 
+       /* color for workqueue flushing */
+       WORK_STRUCT_COLOR_SHIFT = WORK_STRUCT_FLAG_BITS,
        WORK_STRUCT_COLOR_BITS  = 4,
 
        /*
-        * Reserve 8 bits off of pwq pointer w/ debugobjects turned off.
-        * This makes pwqs aligned to 256 bytes and allows 16 workqueue
-        * flush colors.
+        * When WORK_STRUCT_PWQ is set, reserve 8 bits off of pwq pointer w/
+        * debugobjects turned off. This makes pwqs aligned to 256 bytes (512
+        * 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_COLOR_BITS,
+       WORK_STRUCT_PWQ_SHIFT   = WORK_STRUCT_COLOR_SHIFT + WORK_STRUCT_COLOR_BITS,
 
-       /* data contains off-queue information when !WORK_STRUCT_PWQ */
-       WORK_OFFQ_FLAG_BASE     = WORK_STRUCT_COLOR_SHIFT,
-
-       __WORK_OFFQ_CANCELING   = WORK_OFFQ_FLAG_BASE,
+       /*
+        * data contains off-queue information when !WORK_STRUCT_PWQ.
+        *
+        * 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
-        * pool it was on.  Cap at 31 bits and use the highest number to
-        * indicate that no pool is associated.
+        * When a work item is off queue, the high bits encode off-queue flags
+        * 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_FLAG_BITS     = 1,
-       WORK_OFFQ_POOL_SHIFT    = WORK_OFFQ_FLAG_BASE + WORK_OFFQ_FLAG_BITS,
+       WORK_OFFQ_POOL_SHIFT    = WORK_OFFQ_FLAG_SHIFT + WORK_OFFQ_FLAG_BITS,
        WORK_OFFQ_LEFT          = BITS_PER_LONG - WORK_OFFQ_POOL_SHIFT,
        WORK_OFFQ_POOL_BITS     = WORK_OFFQ_LEFT <= 31 ? WORK_OFFQ_LEFT : 31,
-
 };
 
 enum work_flags {
@@ -88,12 +96,10 @@ enum wq_misc_consts {
 };
 
 /* 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_STRUCT_NO_POOL    (WORK_OFFQ_POOL_NONE << WORK_OFFQ_POOL_SHIFT)
-
-#define WORK_STRUCT_FLAG_MASK    ((1ul << WORK_STRUCT_FLAG_BITS) - 1)
-#define WORK_STRUCT_WQ_DATA_MASK (~WORK_STRUCT_FLAG_MASK)
+#define WORK_STRUCT_PWQ_MASK   (~((1ul << WORK_STRUCT_PWQ_SHIFT) - 1))
 
 #define WORK_DATA_INIT()       ATOMIC_LONG_INIT((unsigned long)WORK_STRUCT_NO_POOL)
 #define WORK_DATA_STATIC_INIT()        \
index 317c85f051b0f6fd6d474b263f967bd248fb9169..7c6915e23c5cf7a9b2569785b0f9fe07d3344a15 100644 (file)
@@ -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
  * point to the pwq; thus, pwqs need to be aligned at two's power of the
  * number of flag bits.
@@ -294,7 +294,7 @@ struct pool_workqueue {
         */
        struct kthread_work     release_work;
        struct rcu_head         rcu;
-} __aligned(1 << WORK_STRUCT_FLAG_BITS);
+} __aligned(1 << WORK_STRUCT_PWQ_SHIFT);
 
 /*
  * Structure used to wait for workqueue flush.
@@ -843,7 +843,7 @@ static void clear_work_data(struct work_struct *work)
 
 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)
@@ -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,
                     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));