workqueue: Improve locking rule description for worker fields
authorTejun Heo <tj@kernel.org>
Thu, 18 May 2023 03:02:08 +0000 (17:02 -1000)
committerTejun Heo <tj@kernel.org>
Thu, 18 May 2023 03:02:08 +0000 (17:02 -1000)
* Some worker fields are modified only by the worker itself while holding
  pool->lock thus making them safe to read from self, IRQ context if the CPU
  is running the worker or while holding pool->lock. Add 'K' locking rule
  for them.

* worker->sleeping is currently marked "None" which isn't very descriptive.
  It's used only by the worker itself. Add 'S' locking rule for it.

A future patch will depend on the 'K' rule to access worker->current_* from
the scheduler ticks.

Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/workqueue.c
kernel/workqueue_internal.h

index d70bb5b..9424214 100644 (file)
@@ -126,6 +126,12 @@ enum {
  *    cpu or grabbing pool->lock is enough for read access.  If
  *    POOL_DISASSOCIATED is set, it's identical to L.
  *
+ * K: Only modified by worker while holding pool->lock. Can be safely read by
+ *    self, while holding pool->lock or from IRQ context if %current is the
+ *    kworker.
+ *
+ * S: Only modified by worker self.
+ *
  * A: wq_pool_attach_mutex protected.
  *
  * PL: wq_pool_mutex protected.
index 0600f04..c2455be 100644 (file)
@@ -28,14 +28,15 @@ struct worker {
                struct hlist_node       hentry; /* L: while busy */
        };
 
-       struct work_struct      *current_work;  /* L: work being processed */
-       work_func_t             current_func;   /* L: current_work's fn */
-       struct pool_workqueue   *current_pwq;   /* L: current_work's pwq */
-       unsigned int            current_color;  /* L: current_work's color */
-       int                     sleeping;       /* None */
+       struct work_struct      *current_work;  /* K: work being processed and its */
+       work_func_t             current_func;   /* K: function */
+       struct pool_workqueue   *current_pwq;   /* K: pwq */
+       unsigned int            current_color;  /* K: color */
+
+       int                     sleeping;       /* S: is worker sleeping? */
 
        /* used by the scheduler to determine a worker's last known identity */
-       work_func_t             last_func;      /* L: last work's fn */
+       work_func_t             last_func;      /* K: last work's fn */
 
        struct list_head        scheduled;      /* L: scheduled works */
 
@@ -45,7 +46,7 @@ struct worker {
        struct list_head        node;           /* A: anchored at pool->workers */
                                                /* A: runs through worker->node */
 
-       unsigned long           last_active;    /* L: last active timestamp */
+       unsigned long           last_active;    /* K: last active timestamp */
        unsigned int            flags;          /* X: flags */
        int                     id;             /* I: worker id */