Break init_and_link_pwq() into init_pwq() and link_pwq() and move unbound-workqueue specific handling into apply_workqueue_attrs(). Also, factor out unbound pool and pool_workqueue allocation into alloc_unbound_pwq(). This reorganization is to prepare for NUMA affinity and doesn't introduce any functional changes.
Showing the changes to kernel/workqueue.c (1 of 1 file). Show all
Unified · Split
| @@ -3626,13 +3626,10 @@ static void pwq_adjust_max_active(struct pool_workqueue *pwq) · 3625 unmodified lines | ||
| 3626 | 3626 | spin_unlock_irq(&pwq->pool->lock); |
| 3627 | 3627 | } |
| 3628 | 3628 | |
| 3629 | −static void init_and_link_pwq(struct pool_workqueue *pwq, | |
| 3630 | − struct workqueue_struct *wq, | |
| 3631 | − struct worker_pool *pool, | |
| 3632 | − struct pool_workqueue **p_last_pwq) | |
| 3629 | +/* initialize newly zalloced @pwq which is associated with @wq and @pool */ | |
| 3630 | +static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq, | |
| 3631 | + struct worker_pool *pool) | |
| 3633 | 3632 | { |
| 3634 | − int node; | |
| 3635 | − | |
| 3636 | 3633 | BUG_ON((unsigned long)pwq & WORK_STRUCT_FLAG_MASK); |
| 3637 | 3634 | |
| 3638 | 3635 | pwq->pool = pool; |
| @@ -3642,8 +3639,15 @@ static void init_and_link_pwq(struct pool_workqueue *pwq, · 3 unmodified lines | ||
| 3642 | 3639 | INIT_LIST_HEAD(&pwq->delayed_works); |
| 3643 | 3640 | INIT_LIST_HEAD(&pwq->mayday_node); |
| 3644 | 3641 | INIT_WORK(&pwq->unbound_release_work, pwq_unbound_release_workfn); |
| 3642 | +} | |
| 3645 | 3643 | |
| 3646 | − mutex_lock(&wq->mutex); | |
| 3644 | +/* sync @pwq with the current state of its associated wq and link it */ | |
| 3645 | +static void link_pwq(struct pool_workqueue *pwq, | |
| 3646 | + struct pool_workqueue **p_last_pwq) | |
| 3647 | +{ | |
| 3648 | + struct workqueue_struct *wq = pwq->wq; | |
| 3649 | + | |
| 3650 | + lockdep_assert_held(&wq->mutex); | |
| 3647 | 3651 | |
| 3648 | 3652 | /* |
| 3649 | 3653 | * Set the matching work_color. This is synchronized with |
| @@ -3658,14 +3662,29 @@ static void init_and_link_pwq(struct pool_workqueue *pwq, · 8 unmodified lines | ||
| 3658 | 3662 | |
| 3659 | 3663 | /* link in @pwq */ |
| 3660 | 3664 | list_add_rcu(&pwq->pwqs_node, &wq->pwqs); |
| 3665 | +} | |
| 3661 | 3666 | |
| 3662 | − if (wq->flags & WQ_UNBOUND) { | |
| 3663 | − copy_workqueue_attrs(wq->unbound_attrs, pool->attrs); | |
| 3664 | − for_each_node(node) | |
| 3665 | − rcu_assign_pointer(wq->numa_pwq_tbl[node], pwq); | |
| 3667 | +/* obtain a pool matching @attr and create a pwq associating the pool and @wq */ | |
| 3668 | +static struct pool_workqueue *alloc_unbound_pwq(struct workqueue_struct *wq, | |
| 3669 | + const struct workqueue_attrs *attrs) | |
| 3670 | +{ | |
| 3671 | + struct worker_pool *pool; | |
| 3672 | + struct pool_workqueue *pwq; | |
| 3673 | + | |
| 3674 | + lockdep_assert_held(&wq_pool_mutex); | |
| 3675 | + | |
| 3676 | + pool = get_unbound_pool(attrs); | |
| 3677 | + if (!pool) | |
| 3678 | + return NULL; | |
| 3679 | + | |
| 3680 | + pwq = kmem_cache_zalloc(pwq_cache, GFP_KERNEL); | |
| 3681 | + if (!pwq) { | |
| 3682 | + put_unbound_pool(pool); | |
| 3683 | + return NULL; | |
| 3666 | 3684 | } |
| 3667 | 3685 | |
| 3668 | − mutex_unlock(&wq->mutex); | |
| 3686 | + init_pwq(pwq, wq, pool); | |
| 3687 | + return pwq; | |
| 3669 | 3688 | } |
| 3670 | 3689 | |
| 3671 | 3690 | /** |
| @@ -3686,9 +3705,8 @@ int apply_workqueue_attrs(struct workqueue_struct *wq, · 14 unmodified lines | ||
| 3686 | 3705 | const struct workqueue_attrs *attrs) |
| 3687 | 3706 | { |
| 3688 | 3707 | struct workqueue_attrs *new_attrs; |
| 3689 | − struct pool_workqueue *pwq = NULL, *last_pwq; | |
| 3690 | − struct worker_pool *pool; | |
| 3691 | − int ret; | |
| 3708 | + struct pool_workqueue *pwq, *last_pwq; | |
| 3709 | + int node, ret; | |
| 3692 | 3710 | |
| 3693 | 3711 | /* only unbound workqueues can change attributes */ |
| 3694 | 3712 | if (WARN_ON(!(wq->flags & WQ_UNBOUND))) |
| @@ -3707,22 +3725,21 @@ int apply_workqueue_attrs(struct workqueue_struct *wq, · 12 unmodified lines | ||
| 3707 | 3725 | cpumask_and(new_attrs->cpumask, new_attrs->cpumask, cpu_possible_mask); |
| 3708 | 3726 | |
| 3709 | 3727 | mutex_lock(&wq_pool_mutex); |
| 3710 | − | |
| 3711 | − pwq = kmem_cache_zalloc(pwq_cache, GFP_KERNEL); | |
| 3712 | − if (!pwq) { | |
| 3713 | − mutex_unlock(&wq_pool_mutex); | |
| 3728 | + pwq = alloc_unbound_pwq(wq, new_attrs); | |
| 3729 | + mutex_unlock(&wq_pool_mutex); | |
| 3730 | + if (!pwq) | |
| 3714 | 3731 | goto enomem; |
| 3715 | − } | |
| 3716 | 3732 | |
| 3717 | − pool = get_unbound_pool(new_attrs); | |
| 3718 | − if (!pool) { | |
| 3719 | − mutex_unlock(&wq_pool_mutex); | |
| 3720 | − goto enomem; | |
| 3721 | − } | |
| 3733 | + mutex_lock(&wq->mutex); | |
| 3722 | 3734 | |
| 3723 | − mutex_unlock(&wq_pool_mutex); | |
| 3735 | + link_pwq(pwq, &last_pwq); | |
| 3736 | + | |
| 3737 | + copy_workqueue_attrs(wq->unbound_attrs, new_attrs); | |
| 3738 | + for_each_node(node) | |
| 3739 | + rcu_assign_pointer(wq->numa_pwq_tbl[node], pwq); | |
| 3740 | + | |
| 3741 | + mutex_unlock(&wq->mutex); | |
| 3724 | 3742 | |
| 3725 | − init_and_link_pwq(pwq, wq, pool, &last_pwq); | |
| 3726 | 3743 | if (last_pwq) { |
| 3727 | 3744 | spin_lock_irq(&last_pwq->pool->lock); |
| 3728 | 3745 | put_pwq(last_pwq); |
| @@ -3736,7 +3753,6 @@ out_free: · 7 unmodified lines | ||
| 3736 | 3753 | return ret; |
| 3737 | 3754 | |
| 3738 | 3755 | enomem: |
| 3739 | − kmem_cache_free(pwq_cache, pwq); | |
| 3740 | 3756 | ret = -ENOMEM; |
| 3741 | 3757 | goto out_free; |
| 3742 | 3758 | } |
| @@ -3757,7 +3773,11 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq) · 14 unmodified lines | ||
| 3757 | 3773 | struct worker_pool *cpu_pools = |
| 3758 | 3774 | per_cpu(cpu_worker_pools, cpu); |
| 3759 | 3775 | |
| 3760 | − init_and_link_pwq(pwq, wq, &cpu_pools[highpri], NULL); | |
| 3776 | + init_pwq(pwq, wq, &cpu_pools[highpri]); | |
| 3777 | + | |
| 3778 | + mutex_lock(&wq->mutex); | |
| 3779 | + link_pwq(pwq, NULL); | |
| 3780 | + mutex_unlock(&wq->mutex); | |
| 3761 | 3781 | } |
| 3762 | 3782 | return 0; |
| 3763 | 3783 | } else { |