• Tejun Heo's avatar
    workqueue: Factor out actual cpumask calculation to reduce subtlety in wq_update_pod() · 0f36ee24
    Tejun Heo authored
    For an unbound pool, multiple cpumasks are involved.
    
    U: The user-specified cpumask (may be filtered with cpu_possible_mask).
    
    A: The actual cpumask filtered by wq_unbound_cpumask. If the filtering
       leaves no CPU, wq_unbound_cpumask is used.
    
    P: Per-pod subsets of #A.
    
    wq->attrs stores #U, wq->dfl_pwq->pool->attrs->cpumask #A, and
    wq->cpu_pwq[CPU]->pool->attrs->cpumask #P.
    
    wq_update_pod() is called to update per-pod pwq's during CPU hotplug. To
    calculate the new #P for each workqueue, it needs to call
    wq_calc_pod_cpumask() with @attrs that contains #A. Currently,
    wq_update_pod() achieves this by calling wq_calc_pod_cpumask() with
    wq->dfl_pwq->pool->attrs.
    
    This is rather fragile because we're calling wq_calc_pod_cpumask() with
    @attrs of a worker_pool rather than the workqueue's actual attrs when what
    we want to calculate is the workqueue's cpumask on the pod. While this works
    fine currently, future changes will add fields which are used differently
    between workqueues and worker_pools and this subtlety will bite us.
    
    This patch factors out #U -> #A calculation from apply_wqattrs_prepare()
    into wqattrs_actualize_cpumask and updates wq_update_pod() to copy
    wq->unbound_attrs and use the new helper to obtain #A freshly instead of
    abusing wq->dfl_pwq->pool_attrs.
    
    This shouldn't cause any behavior changes in the current code.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Reported-by: default avatarK Prateek Nayak <kprateek.nayak@amd.com>
    Reference: http://lkml.kernel.org/r/30625cdd-4d61-594b-8db9-6816b017dde3@amd.com
    0f36ee24
workqueue.c 180 KB