workqueue: Factor out clearing of workqueue-only attrs fields
authorTejun Heo <tj@kernel.org>
Tue, 8 Aug 2023 01:57:24 +0000 (15:57 -1000)
committerTejun Heo <tj@kernel.org>
Tue, 8 Aug 2023 01:57:24 +0000 (15:57 -1000)
workqueue_attrs can be used for both workqueues and worker_pools. However,
some fields, currently only ->ordered, only apply to workqueues and should
be cleared to the default / invalid values.

Currently, an unbound workqueue explicitly clears attrs->ordered in
get_unbound_pool() after copying the source workqueue attrs, while per-cpu
workqueues rely on the fact that zeroing on allocation gives us the desired
default value for pool->attrs->ordered.

This is fragile. Let's add wqattrs_clear_for_pool() which clears
attrs->ordered and is called from both init_worker_pool() and
get_unbound_pool(). This will ease adding more workqueue-only attrs fields.

In get_unbound_pool(), pool->node initialization is moved upwards for
readability. This shouldn't cause any behavior changes.

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

index 3f1fffa..37eab7a 100644 (file)
@@ -3678,6 +3678,15 @@ static void copy_workqueue_attrs(struct workqueue_attrs *to,
        to->ordered = from->ordered;
 }
 
+/*
+ * Some attrs fields are workqueue-only. Clear them for worker_pool's. See the
+ * comments in 'struct workqueue_attrs' definition.
+ */
+static void wqattrs_clear_for_pool(struct workqueue_attrs *attrs)
+{
+       attrs->ordered = false;
+}
+
 /* hash value of the content of @attr */
 static u32 wqattrs_hash(const struct workqueue_attrs *attrs)
 {
@@ -3752,6 +3761,9 @@ static int init_worker_pool(struct worker_pool *pool)
        pool->attrs = alloc_workqueue_attrs();
        if (!pool->attrs)
                return -ENOMEM;
+
+       wqattrs_clear_for_pool(pool->attrs);
+
        return 0;
 }
 
@@ -3942,14 +3954,10 @@ static struct worker_pool *get_unbound_pool(const struct workqueue_attrs *attrs)
        if (!pool || init_worker_pool(pool) < 0)
                goto fail;
 
-       copy_workqueue_attrs(pool->attrs, attrs);
        pool->node = target_pod;
 
-       /*
-        * ordered isn't a worker_pool attribute, always clear it.  See
-        * 'struct workqueue_attrs' comments for detail.
-        */
-       pool->attrs->ordered = false;
+       copy_workqueue_attrs(pool->attrs, attrs);
+       wqattrs_clear_for_pool(pool->attrs);
 
        if (worker_pool_assign_id(pool) < 0)
                goto fail;