xref: /linux-6.15/kernel/padata.c (revision bbefa1dd)
108b21fbfSCheah Kok Cheong // SPDX-License-Identifier: GPL-2.0
216295becSSteffen Klassert /*
316295becSSteffen Klassert  * padata.c - generic interface to process data streams in parallel
416295becSSteffen Klassert  *
5107f8bdaSSteffen Klassert  * See Documentation/padata.txt for an api documentation.
6107f8bdaSSteffen Klassert  *
716295becSSteffen Klassert  * Copyright (C) 2008, 2009 secunet Security Networks AG
816295becSSteffen Klassert  * Copyright (C) 2008, 2009 Steffen Klassert <[email protected]>
916295becSSteffen Klassert  *
1016295becSSteffen Klassert  * This program is free software; you can redistribute it and/or modify it
1116295becSSteffen Klassert  * under the terms and conditions of the GNU General Public License,
1216295becSSteffen Klassert  * version 2, as published by the Free Software Foundation.
1316295becSSteffen Klassert  *
1416295becSSteffen Klassert  * This program is distributed in the hope it will be useful, but WITHOUT
1516295becSSteffen Klassert  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1616295becSSteffen Klassert  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1716295becSSteffen Klassert  * more details.
1816295becSSteffen Klassert  *
1916295becSSteffen Klassert  * You should have received a copy of the GNU General Public License along with
2016295becSSteffen Klassert  * this program; if not, write to the Free Software Foundation, Inc.,
2116295becSSteffen Klassert  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
2216295becSSteffen Klassert  */
2316295becSSteffen Klassert 
249984de1aSPaul Gortmaker #include <linux/export.h>
2516295becSSteffen Klassert #include <linux/cpumask.h>
2616295becSSteffen Klassert #include <linux/err.h>
2716295becSSteffen Klassert #include <linux/cpu.h>
2816295becSSteffen Klassert #include <linux/padata.h>
2916295becSSteffen Klassert #include <linux/mutex.h>
3016295becSSteffen Klassert #include <linux/sched.h>
315a0e3ad6STejun Heo #include <linux/slab.h>
325e017dc3SDan Kruchinin #include <linux/sysfs.h>
3316295becSSteffen Klassert #include <linux/rcupdate.h>
3430e92153SSebastian Andrzej Siewior #include <linux/module.h>
3516295becSSteffen Klassert 
3697e3d94aSSteffen Klassert #define MAX_OBJ_NUM 1000
3716295becSSteffen Klassert 
3807928d9bSHerbert Xu static void padata_free_pd(struct parallel_data *pd);
3907928d9bSHerbert Xu 
4016295becSSteffen Klassert static int padata_index_to_cpu(struct parallel_data *pd, int cpu_index)
4116295becSSteffen Klassert {
4216295becSSteffen Klassert 	int cpu, target_cpu;
4316295becSSteffen Klassert 
44e15bacbeSDan Kruchinin 	target_cpu = cpumask_first(pd->cpumask.pcpu);
4516295becSSteffen Klassert 	for (cpu = 0; cpu < cpu_index; cpu++)
46e15bacbeSDan Kruchinin 		target_cpu = cpumask_next(target_cpu, pd->cpumask.pcpu);
4716295becSSteffen Klassert 
4816295becSSteffen Klassert 	return target_cpu;
4916295becSSteffen Klassert }
5016295becSSteffen Klassert 
51bfde23ceSDaniel Jordan static int padata_cpu_hash(struct parallel_data *pd, unsigned int seq_nr)
5216295becSSteffen Klassert {
5316295becSSteffen Klassert 	/*
5416295becSSteffen Klassert 	 * Hash the sequence numbers to the cpus by taking
5516295becSSteffen Klassert 	 * seq_nr mod. number of cpus in use.
5616295becSSteffen Klassert 	 */
57bfde23ceSDaniel Jordan 	int cpu_index = seq_nr % cpumask_weight(pd->cpumask.pcpu);
5816295becSSteffen Klassert 
5916295becSSteffen Klassert 	return padata_index_to_cpu(pd, cpu_index);
6016295becSSteffen Klassert }
6116295becSSteffen Klassert 
62e15bacbeSDan Kruchinin static void padata_parallel_worker(struct work_struct *parallel_work)
6316295becSSteffen Klassert {
64e15bacbeSDan Kruchinin 	struct padata_parallel_queue *pqueue;
6516295becSSteffen Klassert 	LIST_HEAD(local_list);
6616295becSSteffen Klassert 
6716295becSSteffen Klassert 	local_bh_disable();
68e15bacbeSDan Kruchinin 	pqueue = container_of(parallel_work,
69e15bacbeSDan Kruchinin 			      struct padata_parallel_queue, work);
7016295becSSteffen Klassert 
71e15bacbeSDan Kruchinin 	spin_lock(&pqueue->parallel.lock);
72e15bacbeSDan Kruchinin 	list_replace_init(&pqueue->parallel.list, &local_list);
73e15bacbeSDan Kruchinin 	spin_unlock(&pqueue->parallel.lock);
7416295becSSteffen Klassert 
7516295becSSteffen Klassert 	while (!list_empty(&local_list)) {
7616295becSSteffen Klassert 		struct padata_priv *padata;
7716295becSSteffen Klassert 
7816295becSSteffen Klassert 		padata = list_entry(local_list.next,
7916295becSSteffen Klassert 				    struct padata_priv, list);
8016295becSSteffen Klassert 
8116295becSSteffen Klassert 		list_del_init(&padata->list);
8216295becSSteffen Klassert 
8316295becSSteffen Klassert 		padata->parallel(padata);
8416295becSSteffen Klassert 	}
8516295becSSteffen Klassert 
8616295becSSteffen Klassert 	local_bh_enable();
8716295becSSteffen Klassert }
8816295becSSteffen Klassert 
890198ffd1SSteffen Klassert /**
9016295becSSteffen Klassert  * padata_do_parallel - padata parallelization function
9116295becSSteffen Klassert  *
92*bbefa1ddSHerbert Xu  * @ps: padatashell
9316295becSSteffen Klassert  * @padata: object to be parallelized
94e6ce0e08SDaniel Jordan  * @cb_cpu: pointer to the CPU that the serialization callback function should
95e6ce0e08SDaniel Jordan  *          run on.  If it's not in the serial cpumask of @pinst
96e6ce0e08SDaniel Jordan  *          (i.e. cpumask.cbcpu), this function selects a fallback CPU and if
97e6ce0e08SDaniel Jordan  *          none found, returns -EINVAL.
9816295becSSteffen Klassert  *
9916295becSSteffen Klassert  * The parallelization callback function will run with BHs off.
10016295becSSteffen Klassert  * Note: Every object which is parallelized by padata_do_parallel
10116295becSSteffen Klassert  * must be seen by padata_do_serial.
10216295becSSteffen Klassert  */
103*bbefa1ddSHerbert Xu int padata_do_parallel(struct padata_shell *ps,
104e6ce0e08SDaniel Jordan 		       struct padata_priv *padata, int *cb_cpu)
10516295becSSteffen Klassert {
106*bbefa1ddSHerbert Xu 	struct padata_instance *pinst = ps->pinst;
107e6ce0e08SDaniel Jordan 	int i, cpu, cpu_index, target_cpu, err;
108e15bacbeSDan Kruchinin 	struct padata_parallel_queue *queue;
10916295becSSteffen Klassert 	struct parallel_data *pd;
11016295becSSteffen Klassert 
11116295becSSteffen Klassert 	rcu_read_lock_bh();
11216295becSSteffen Klassert 
113*bbefa1ddSHerbert Xu 	pd = rcu_dereference_bh(ps->pd);
11416295becSSteffen Klassert 
11583f619f3SSteffen Klassert 	err = -EINVAL;
1167424713bSSteffen Klassert 	if (!(pinst->flags & PADATA_INIT) || pinst->flags & PADATA_INVALID)
11716295becSSteffen Klassert 		goto out;
11816295becSSteffen Klassert 
119e6ce0e08SDaniel Jordan 	if (!cpumask_test_cpu(*cb_cpu, pd->cpumask.cbcpu)) {
120e6ce0e08SDaniel Jordan 		if (!cpumask_weight(pd->cpumask.cbcpu))
12116295becSSteffen Klassert 			goto out;
12216295becSSteffen Klassert 
123e6ce0e08SDaniel Jordan 		/* Select an alternate fallback CPU and notify the caller. */
124e6ce0e08SDaniel Jordan 		cpu_index = *cb_cpu % cpumask_weight(pd->cpumask.cbcpu);
125e6ce0e08SDaniel Jordan 
126e6ce0e08SDaniel Jordan 		cpu = cpumask_first(pd->cpumask.cbcpu);
127e6ce0e08SDaniel Jordan 		for (i = 0; i < cpu_index; i++)
128e6ce0e08SDaniel Jordan 			cpu = cpumask_next(cpu, pd->cpumask.cbcpu);
129e6ce0e08SDaniel Jordan 
130e6ce0e08SDaniel Jordan 		*cb_cpu = cpu;
131e6ce0e08SDaniel Jordan 	}
132e6ce0e08SDaniel Jordan 
13316295becSSteffen Klassert 	err =  -EBUSY;
13416295becSSteffen Klassert 	if ((pinst->flags & PADATA_RESET))
13516295becSSteffen Klassert 		goto out;
13616295becSSteffen Klassert 
13716295becSSteffen Klassert 	if (atomic_read(&pd->refcnt) >= MAX_OBJ_NUM)
13816295becSSteffen Klassert 		goto out;
13916295becSSteffen Klassert 
14083f619f3SSteffen Klassert 	err = 0;
14116295becSSteffen Klassert 	atomic_inc(&pd->refcnt);
14216295becSSteffen Klassert 	padata->pd = pd;
143e6ce0e08SDaniel Jordan 	padata->cb_cpu = *cb_cpu;
14416295becSSteffen Klassert 
145bfde23ceSDaniel Jordan 	padata->seq_nr = atomic_inc_return(&pd->seq_nr);
146bfde23ceSDaniel Jordan 	target_cpu = padata_cpu_hash(pd, padata->seq_nr);
147350ef88eSMathias Krause 	padata->cpu = target_cpu;
148e15bacbeSDan Kruchinin 	queue = per_cpu_ptr(pd->pqueue, target_cpu);
14916295becSSteffen Klassert 
15016295becSSteffen Klassert 	spin_lock(&queue->parallel.lock);
15116295becSSteffen Klassert 	list_add_tail(&padata->list, &queue->parallel.list);
15216295becSSteffen Klassert 	spin_unlock(&queue->parallel.lock);
15316295becSSteffen Klassert 
154bfde23ceSDaniel Jordan 	queue_work(pinst->parallel_wq, &queue->work);
15516295becSSteffen Klassert 
15616295becSSteffen Klassert out:
15716295becSSteffen Klassert 	rcu_read_unlock_bh();
15816295becSSteffen Klassert 
15916295becSSteffen Klassert 	return err;
16016295becSSteffen Klassert }
16116295becSSteffen Klassert EXPORT_SYMBOL(padata_do_parallel);
16216295becSSteffen Klassert 
1630198ffd1SSteffen Klassert /*
164bfde23ceSDaniel Jordan  * padata_find_next - Find the next object that needs serialization.
1650198ffd1SSteffen Klassert  *
1660198ffd1SSteffen Klassert  * Return values are:
1670198ffd1SSteffen Klassert  *
1680198ffd1SSteffen Klassert  * A pointer to the control struct of the next object that needs
1690198ffd1SSteffen Klassert  * serialization, if present in one of the percpu reorder queues.
1700198ffd1SSteffen Klassert  *
171bfde23ceSDaniel Jordan  * NULL, if the next object that needs serialization will
1720198ffd1SSteffen Klassert  *  be parallel processed by another cpu and is not yet present in
1730198ffd1SSteffen Klassert  *  the cpu's reorder queue.
1740198ffd1SSteffen Klassert  */
175bfde23ceSDaniel Jordan static struct padata_priv *padata_find_next(struct parallel_data *pd,
176bfde23ceSDaniel Jordan 					    bool remove_object)
17716295becSSteffen Klassert {
178f0fcf200SShan Wei 	struct padata_parallel_queue *next_queue;
17916295becSSteffen Klassert 	struct padata_priv *padata;
18016295becSSteffen Klassert 	struct padata_list *reorder;
1816fc4dbcfSHerbert Xu 	int cpu = pd->cpu;
18216295becSSteffen Klassert 
183e15bacbeSDan Kruchinin 	next_queue = per_cpu_ptr(pd->pqueue, cpu);
18416295becSSteffen Klassert 	reorder = &next_queue->reorder;
18516295becSSteffen Klassert 
186de5540d0SJason A. Donenfeld 	spin_lock(&reorder->lock);
187bfde23ceSDaniel Jordan 	if (list_empty(&reorder->list)) {
188bfde23ceSDaniel Jordan 		spin_unlock(&reorder->lock);
189bfde23ceSDaniel Jordan 		return NULL;
190bfde23ceSDaniel Jordan 	}
19116295becSSteffen Klassert 
192bfde23ceSDaniel Jordan 	padata = list_entry(reorder->list.next, struct padata_priv, list);
193bfde23ceSDaniel Jordan 
194bfde23ceSDaniel Jordan 	/*
195bfde23ceSDaniel Jordan 	 * Checks the rare case where two or more parallel jobs have hashed to
196bfde23ceSDaniel Jordan 	 * the same CPU and one of the later ones finishes first.
197bfde23ceSDaniel Jordan 	 */
198bfde23ceSDaniel Jordan 	if (padata->seq_nr != pd->processed) {
199bfde23ceSDaniel Jordan 		spin_unlock(&reorder->lock);
200bfde23ceSDaniel Jordan 		return NULL;
201bfde23ceSDaniel Jordan 	}
202bfde23ceSDaniel Jordan 
203bfde23ceSDaniel Jordan 	if (remove_object) {
20416295becSSteffen Klassert 		list_del_init(&padata->list);
20516295becSSteffen Klassert 		atomic_dec(&pd->reorder_objects);
206bfde23ceSDaniel Jordan 		++pd->processed;
207bfde23ceSDaniel Jordan 		pd->cpu = cpumask_next_wrap(cpu, pd->cpumask.pcpu, -1, false);
20816295becSSteffen Klassert 	}
20916295becSSteffen Klassert 
210bfde23ceSDaniel Jordan 	spin_unlock(&reorder->lock);
21116295becSSteffen Klassert 	return padata;
21216295becSSteffen Klassert }
21316295becSSteffen Klassert 
21416295becSSteffen Klassert static void padata_reorder(struct parallel_data *pd)
21516295becSSteffen Klassert {
216*bbefa1ddSHerbert Xu 	struct padata_instance *pinst = pd->ps->pinst;
2173047817bSSteffen Klassert 	int cb_cpu;
21816295becSSteffen Klassert 	struct padata_priv *padata;
219e15bacbeSDan Kruchinin 	struct padata_serial_queue *squeue;
2206fc4dbcfSHerbert Xu 	struct padata_parallel_queue *next_queue;
22116295becSSteffen Klassert 
2220198ffd1SSteffen Klassert 	/*
2230198ffd1SSteffen Klassert 	 * We need to ensure that only one cpu can work on dequeueing of
2240198ffd1SSteffen Klassert 	 * the reorder queue the time. Calculating in which percpu reorder
2250198ffd1SSteffen Klassert 	 * queue the next object will arrive takes some time. A spinlock
2260198ffd1SSteffen Klassert 	 * would be highly contended. Also it is not clear in which order
2270198ffd1SSteffen Klassert 	 * the objects arrive to the reorder queues. So a cpu could wait to
2280198ffd1SSteffen Klassert 	 * get the lock just to notice that there is nothing to do at the
2290198ffd1SSteffen Klassert 	 * moment. Therefore we use a trylock and let the holder of the lock
2300198ffd1SSteffen Klassert 	 * care for all the objects enqueued during the holdtime of the lock.
2310198ffd1SSteffen Klassert 	 */
23216295becSSteffen Klassert 	if (!spin_trylock_bh(&pd->lock))
233d46a5ac7SSteffen Klassert 		return;
23416295becSSteffen Klassert 
23516295becSSteffen Klassert 	while (1) {
236bfde23ceSDaniel Jordan 		padata = padata_find_next(pd, true);
23716295becSSteffen Klassert 
2380198ffd1SSteffen Klassert 		/*
23969b34844SJason A. Donenfeld 		 * If the next object that needs serialization is parallel
24069b34844SJason A. Donenfeld 		 * processed by another cpu and is still on it's way to the
24169b34844SJason A. Donenfeld 		 * cpu's reorder queue, nothing to do for now.
2420198ffd1SSteffen Klassert 		 */
243bfde23ceSDaniel Jordan 		if (!padata)
24416295becSSteffen Klassert 			break;
24516295becSSteffen Klassert 
2463047817bSSteffen Klassert 		cb_cpu = padata->cb_cpu;
2473047817bSSteffen Klassert 		squeue = per_cpu_ptr(pd->squeue, cb_cpu);
24816295becSSteffen Klassert 
249e15bacbeSDan Kruchinin 		spin_lock(&squeue->serial.lock);
250e15bacbeSDan Kruchinin 		list_add_tail(&padata->list, &squeue->serial.list);
251e15bacbeSDan Kruchinin 		spin_unlock(&squeue->serial.lock);
25216295becSSteffen Klassert 
25345d153c0SDaniel Jordan 		queue_work_on(cb_cpu, pinst->serial_wq, &squeue->work);
25416295becSSteffen Klassert 	}
25516295becSSteffen Klassert 
25616295becSSteffen Klassert 	spin_unlock_bh(&pd->lock);
25716295becSSteffen Klassert 
2580198ffd1SSteffen Klassert 	/*
2590198ffd1SSteffen Klassert 	 * The next object that needs serialization might have arrived to
2606fc4dbcfSHerbert Xu 	 * the reorder queues in the meantime.
261cf144f81SDaniel Jordan 	 *
2626fc4dbcfSHerbert Xu 	 * Ensure reorder queue is read after pd->lock is dropped so we see
2636fc4dbcfSHerbert Xu 	 * new objects from another task in padata_do_serial.  Pairs with
264cf144f81SDaniel Jordan 	 * smp_mb__after_atomic in padata_do_serial.
2650198ffd1SSteffen Klassert 	 */
266cf144f81SDaniel Jordan 	smp_mb();
26716295becSSteffen Klassert 
2686fc4dbcfSHerbert Xu 	next_queue = per_cpu_ptr(pd->pqueue, pd->cpu);
269bfde23ceSDaniel Jordan 	if (!list_empty(&next_queue->reorder.list) &&
270bfde23ceSDaniel Jordan 	    padata_find_next(pd, false))
27145d153c0SDaniel Jordan 		queue_work(pinst->serial_wq, &pd->reorder_work);
27216295becSSteffen Klassert }
27316295becSSteffen Klassert 
274cf5868c8SMathias Krause static void invoke_padata_reorder(struct work_struct *work)
275cf5868c8SMathias Krause {
276cf5868c8SMathias Krause 	struct parallel_data *pd;
277cf5868c8SMathias Krause 
278cf5868c8SMathias Krause 	local_bh_disable();
2796fc4dbcfSHerbert Xu 	pd = container_of(work, struct parallel_data, reorder_work);
280cf5868c8SMathias Krause 	padata_reorder(pd);
281cf5868c8SMathias Krause 	local_bh_enable();
282cf5868c8SMathias Krause }
283cf5868c8SMathias Krause 
284e15bacbeSDan Kruchinin static void padata_serial_worker(struct work_struct *serial_work)
28516295becSSteffen Klassert {
286e15bacbeSDan Kruchinin 	struct padata_serial_queue *squeue;
28716295becSSteffen Klassert 	struct parallel_data *pd;
28816295becSSteffen Klassert 	LIST_HEAD(local_list);
28907928d9bSHerbert Xu 	int cnt;
29016295becSSteffen Klassert 
29116295becSSteffen Klassert 	local_bh_disable();
292e15bacbeSDan Kruchinin 	squeue = container_of(serial_work, struct padata_serial_queue, work);
293e15bacbeSDan Kruchinin 	pd = squeue->pd;
29416295becSSteffen Klassert 
295e15bacbeSDan Kruchinin 	spin_lock(&squeue->serial.lock);
296e15bacbeSDan Kruchinin 	list_replace_init(&squeue->serial.list, &local_list);
297e15bacbeSDan Kruchinin 	spin_unlock(&squeue->serial.lock);
29816295becSSteffen Klassert 
29907928d9bSHerbert Xu 	cnt = 0;
30007928d9bSHerbert Xu 
30116295becSSteffen Klassert 	while (!list_empty(&local_list)) {
30216295becSSteffen Klassert 		struct padata_priv *padata;
30316295becSSteffen Klassert 
30416295becSSteffen Klassert 		padata = list_entry(local_list.next,
30516295becSSteffen Klassert 				    struct padata_priv, list);
30616295becSSteffen Klassert 
30716295becSSteffen Klassert 		list_del_init(&padata->list);
30816295becSSteffen Klassert 
30916295becSSteffen Klassert 		padata->serial(padata);
31007928d9bSHerbert Xu 		cnt++;
31116295becSSteffen Klassert 	}
31216295becSSteffen Klassert 	local_bh_enable();
31307928d9bSHerbert Xu 
31407928d9bSHerbert Xu 	if (atomic_sub_and_test(cnt, &pd->refcnt))
31507928d9bSHerbert Xu 		padata_free_pd(pd);
31616295becSSteffen Klassert }
31716295becSSteffen Klassert 
3180198ffd1SSteffen Klassert /**
31916295becSSteffen Klassert  * padata_do_serial - padata serialization function
32016295becSSteffen Klassert  *
32116295becSSteffen Klassert  * @padata: object to be serialized.
32216295becSSteffen Klassert  *
32316295becSSteffen Klassert  * padata_do_serial must be called for every parallelized object.
32416295becSSteffen Klassert  * The serialization callback function will run with BHs off.
32516295becSSteffen Klassert  */
32616295becSSteffen Klassert void padata_do_serial(struct padata_priv *padata)
32716295becSSteffen Klassert {
328065cf577SDaniel Jordan 	struct parallel_data *pd = padata->pd;
329065cf577SDaniel Jordan 	struct padata_parallel_queue *pqueue = per_cpu_ptr(pd->pqueue,
330065cf577SDaniel Jordan 							   padata->cpu);
331bfde23ceSDaniel Jordan 	struct padata_priv *cur;
33216295becSSteffen Klassert 
333e15bacbeSDan Kruchinin 	spin_lock(&pqueue->reorder.lock);
334bfde23ceSDaniel Jordan 	/* Sort in ascending order of sequence number. */
335bfde23ceSDaniel Jordan 	list_for_each_entry_reverse(cur, &pqueue->reorder.list, list)
336bfde23ceSDaniel Jordan 		if (cur->seq_nr < padata->seq_nr)
337bfde23ceSDaniel Jordan 			break;
338bfde23ceSDaniel Jordan 	list_add(&padata->list, &cur->list);
3396fc4dbcfSHerbert Xu 	atomic_inc(&pd->reorder_objects);
340e15bacbeSDan Kruchinin 	spin_unlock(&pqueue->reorder.lock);
34116295becSSteffen Klassert 
342cf144f81SDaniel Jordan 	/*
3436fc4dbcfSHerbert Xu 	 * Ensure the addition to the reorder list is ordered correctly
344cf144f81SDaniel Jordan 	 * with the trylock of pd->lock in padata_reorder.  Pairs with smp_mb
345cf144f81SDaniel Jordan 	 * in padata_reorder.
346cf144f81SDaniel Jordan 	 */
347cf144f81SDaniel Jordan 	smp_mb__after_atomic();
348cf144f81SDaniel Jordan 
34916295becSSteffen Klassert 	padata_reorder(pd);
35016295becSSteffen Klassert }
35116295becSSteffen Klassert EXPORT_SYMBOL(padata_do_serial);
35216295becSSteffen Klassert 
353*bbefa1ddSHerbert Xu static int padata_setup_cpumasks(struct padata_instance *pinst)
354*bbefa1ddSHerbert Xu {
355*bbefa1ddSHerbert Xu 	struct workqueue_attrs *attrs;
356*bbefa1ddSHerbert Xu 	int err;
357*bbefa1ddSHerbert Xu 
358*bbefa1ddSHerbert Xu 	attrs = alloc_workqueue_attrs();
359*bbefa1ddSHerbert Xu 	if (!attrs)
360*bbefa1ddSHerbert Xu 		return -ENOMEM;
361*bbefa1ddSHerbert Xu 
362*bbefa1ddSHerbert Xu 	/* Restrict parallel_wq workers to pd->cpumask.pcpu. */
363*bbefa1ddSHerbert Xu 	cpumask_copy(attrs->cpumask, pinst->cpumask.pcpu);
364*bbefa1ddSHerbert Xu 	err = apply_workqueue_attrs(pinst->parallel_wq, attrs);
365*bbefa1ddSHerbert Xu 	free_workqueue_attrs(attrs);
366*bbefa1ddSHerbert Xu 
367*bbefa1ddSHerbert Xu 	return err;
368*bbefa1ddSHerbert Xu }
369*bbefa1ddSHerbert Xu 
370*bbefa1ddSHerbert Xu static int pd_setup_cpumasks(struct parallel_data *pd,
371e15bacbeSDan Kruchinin 			     const struct cpumask *pcpumask,
372e15bacbeSDan Kruchinin 			     const struct cpumask *cbcpumask)
37316295becSSteffen Klassert {
374bfde23ceSDaniel Jordan 	int err = -ENOMEM;
375bfde23ceSDaniel Jordan 
376e15bacbeSDan Kruchinin 	if (!alloc_cpumask_var(&pd->cpumask.pcpu, GFP_KERNEL))
377bfde23ceSDaniel Jordan 		goto out;
378bfde23ceSDaniel Jordan 	if (!alloc_cpumask_var(&pd->cpumask.cbcpu, GFP_KERNEL))
379bfde23ceSDaniel Jordan 		goto free_pcpu_mask;
380bfde23ceSDaniel Jordan 
381*bbefa1ddSHerbert Xu 	cpumask_copy(pd->cpumask.pcpu, pcpumask);
382*bbefa1ddSHerbert Xu 	cpumask_copy(pd->cpumask.cbcpu, cbcpumask);
383bfde23ceSDaniel Jordan 
384e15bacbeSDan Kruchinin 	return 0;
385bfde23ceSDaniel Jordan 
386bfde23ceSDaniel Jordan free_pcpu_mask:
387bfde23ceSDaniel Jordan 	free_cpumask_var(pd->cpumask.pcpu);
388bfde23ceSDaniel Jordan out:
389bfde23ceSDaniel Jordan 	return err;
390e15bacbeSDan Kruchinin }
391e15bacbeSDan Kruchinin 
392e15bacbeSDan Kruchinin static void __padata_list_init(struct padata_list *pd_list)
393e15bacbeSDan Kruchinin {
394e15bacbeSDan Kruchinin 	INIT_LIST_HEAD(&pd_list->list);
395e15bacbeSDan Kruchinin 	spin_lock_init(&pd_list->lock);
396e15bacbeSDan Kruchinin }
397e15bacbeSDan Kruchinin 
398e15bacbeSDan Kruchinin /* Initialize all percpu queues used by serial workers */
399e15bacbeSDan Kruchinin static void padata_init_squeues(struct parallel_data *pd)
400e15bacbeSDan Kruchinin {
401e15bacbeSDan Kruchinin 	int cpu;
402e15bacbeSDan Kruchinin 	struct padata_serial_queue *squeue;
403e15bacbeSDan Kruchinin 
404e15bacbeSDan Kruchinin 	for_each_cpu(cpu, pd->cpumask.cbcpu) {
405e15bacbeSDan Kruchinin 		squeue = per_cpu_ptr(pd->squeue, cpu);
406e15bacbeSDan Kruchinin 		squeue->pd = pd;
407e15bacbeSDan Kruchinin 		__padata_list_init(&squeue->serial);
408e15bacbeSDan Kruchinin 		INIT_WORK(&squeue->work, padata_serial_worker);
409e15bacbeSDan Kruchinin 	}
410e15bacbeSDan Kruchinin }
411e15bacbeSDan Kruchinin 
412e15bacbeSDan Kruchinin /* Initialize all percpu queues used by parallel workers */
413e15bacbeSDan Kruchinin static void padata_init_pqueues(struct parallel_data *pd)
414e15bacbeSDan Kruchinin {
415c51636a3SDaniel Jordan 	int cpu;
416e15bacbeSDan Kruchinin 	struct padata_parallel_queue *pqueue;
41716295becSSteffen Klassert 
418c51636a3SDaniel Jordan 	for_each_cpu(cpu, pd->cpumask.pcpu) {
419e15bacbeSDan Kruchinin 		pqueue = per_cpu_ptr(pd->pqueue, cpu);
4201bd845bcSMathias Krause 
421e15bacbeSDan Kruchinin 		__padata_list_init(&pqueue->reorder);
422e15bacbeSDan Kruchinin 		__padata_list_init(&pqueue->parallel);
423e15bacbeSDan Kruchinin 		INIT_WORK(&pqueue->work, padata_parallel_worker);
424e15bacbeSDan Kruchinin 		atomic_set(&pqueue->num_obj, 0);
425e15bacbeSDan Kruchinin 	}
426e15bacbeSDan Kruchinin }
427e15bacbeSDan Kruchinin 
428e15bacbeSDan Kruchinin /* Allocate and initialize the internal cpumask dependend resources. */
429*bbefa1ddSHerbert Xu static struct parallel_data *padata_alloc_pd(struct padata_shell *ps)
430e15bacbeSDan Kruchinin {
431*bbefa1ddSHerbert Xu 	struct padata_instance *pinst = ps->pinst;
432*bbefa1ddSHerbert Xu 	const struct cpumask *cbcpumask;
433*bbefa1ddSHerbert Xu 	const struct cpumask *pcpumask;
434e15bacbeSDan Kruchinin 	struct parallel_data *pd;
43516295becSSteffen Klassert 
436*bbefa1ddSHerbert Xu 	cbcpumask = pinst->rcpumask.cbcpu;
437*bbefa1ddSHerbert Xu 	pcpumask = pinst->rcpumask.pcpu;
438*bbefa1ddSHerbert Xu 
43916295becSSteffen Klassert 	pd = kzalloc(sizeof(struct parallel_data), GFP_KERNEL);
44016295becSSteffen Klassert 	if (!pd)
44116295becSSteffen Klassert 		goto err;
44216295becSSteffen Klassert 
443e15bacbeSDan Kruchinin 	pd->pqueue = alloc_percpu(struct padata_parallel_queue);
444e15bacbeSDan Kruchinin 	if (!pd->pqueue)
44516295becSSteffen Klassert 		goto err_free_pd;
44616295becSSteffen Klassert 
447e15bacbeSDan Kruchinin 	pd->squeue = alloc_percpu(struct padata_serial_queue);
448e15bacbeSDan Kruchinin 	if (!pd->squeue)
449e15bacbeSDan Kruchinin 		goto err_free_pqueue;
450bfde23ceSDaniel Jordan 
451*bbefa1ddSHerbert Xu 	pd->ps = ps;
452*bbefa1ddSHerbert Xu 	if (pd_setup_cpumasks(pd, pcpumask, cbcpumask))
453e15bacbeSDan Kruchinin 		goto err_free_squeue;
45416295becSSteffen Klassert 
455e15bacbeSDan Kruchinin 	padata_init_pqueues(pd);
456e15bacbeSDan Kruchinin 	padata_init_squeues(pd);
4570b6b098eSMathias Krause 	atomic_set(&pd->seq_nr, -1);
45816295becSSteffen Klassert 	atomic_set(&pd->reorder_objects, 0);
45907928d9bSHerbert Xu 	atomic_set(&pd->refcnt, 1);
46016295becSSteffen Klassert 	spin_lock_init(&pd->lock);
461ec9c7d19SDaniel Jordan 	pd->cpu = cpumask_first(pd->cpumask.pcpu);
4626fc4dbcfSHerbert Xu 	INIT_WORK(&pd->reorder_work, invoke_padata_reorder);
46316295becSSteffen Klassert 
46416295becSSteffen Klassert 	return pd;
46516295becSSteffen Klassert 
466e15bacbeSDan Kruchinin err_free_squeue:
467e15bacbeSDan Kruchinin 	free_percpu(pd->squeue);
468e15bacbeSDan Kruchinin err_free_pqueue:
469e15bacbeSDan Kruchinin 	free_percpu(pd->pqueue);
47016295becSSteffen Klassert err_free_pd:
47116295becSSteffen Klassert 	kfree(pd);
47216295becSSteffen Klassert err:
47316295becSSteffen Klassert 	return NULL;
47416295becSSteffen Klassert }
47516295becSSteffen Klassert 
47616295becSSteffen Klassert static void padata_free_pd(struct parallel_data *pd)
47716295becSSteffen Klassert {
478e15bacbeSDan Kruchinin 	free_cpumask_var(pd->cpumask.pcpu);
479e15bacbeSDan Kruchinin 	free_cpumask_var(pd->cpumask.cbcpu);
480e15bacbeSDan Kruchinin 	free_percpu(pd->pqueue);
481e15bacbeSDan Kruchinin 	free_percpu(pd->squeue);
48216295becSSteffen Klassert 	kfree(pd);
48316295becSSteffen Klassert }
48416295becSSteffen Klassert 
4854c879170SSteffen Klassert static void __padata_start(struct padata_instance *pinst)
4864c879170SSteffen Klassert {
4874c879170SSteffen Klassert 	pinst->flags |= PADATA_INIT;
4884c879170SSteffen Klassert }
4894c879170SSteffen Klassert 
490ee836555SSteffen Klassert static void __padata_stop(struct padata_instance *pinst)
491ee836555SSteffen Klassert {
492ee836555SSteffen Klassert 	if (!(pinst->flags & PADATA_INIT))
493ee836555SSteffen Klassert 		return;
494ee836555SSteffen Klassert 
495ee836555SSteffen Klassert 	pinst->flags &= ~PADATA_INIT;
496ee836555SSteffen Klassert 
497ee836555SSteffen Klassert 	synchronize_rcu();
498ee836555SSteffen Klassert }
499ee836555SSteffen Klassert 
50025985edcSLucas De Marchi /* Replace the internal control structure with a new one. */
501*bbefa1ddSHerbert Xu static int padata_replace_one(struct padata_shell *ps)
50216295becSSteffen Klassert {
503*bbefa1ddSHerbert Xu 	struct parallel_data *pd_new;
504*bbefa1ddSHerbert Xu 
505*bbefa1ddSHerbert Xu 	pd_new = padata_alloc_pd(ps);
506*bbefa1ddSHerbert Xu 	if (!pd_new)
507*bbefa1ddSHerbert Xu 		return -ENOMEM;
508*bbefa1ddSHerbert Xu 
509*bbefa1ddSHerbert Xu 	ps->opd = rcu_dereference_protected(ps->pd, 1);
510*bbefa1ddSHerbert Xu 	rcu_assign_pointer(ps->pd, pd_new);
511*bbefa1ddSHerbert Xu 
512*bbefa1ddSHerbert Xu 	return 0;
513*bbefa1ddSHerbert Xu }
514*bbefa1ddSHerbert Xu 
515*bbefa1ddSHerbert Xu static int padata_replace(struct padata_instance *pinst, int cpu)
516*bbefa1ddSHerbert Xu {
517e15bacbeSDan Kruchinin 	int notification_mask = 0;
518*bbefa1ddSHerbert Xu 	struct padata_shell *ps;
519*bbefa1ddSHerbert Xu 	int err;
52016295becSSteffen Klassert 
52116295becSSteffen Klassert 	pinst->flags |= PADATA_RESET;
52216295becSSteffen Klassert 
523*bbefa1ddSHerbert Xu 	cpumask_copy(pinst->omask, pinst->rcpumask.pcpu);
524*bbefa1ddSHerbert Xu 	cpumask_and(pinst->rcpumask.pcpu, pinst->cpumask.pcpu,
525*bbefa1ddSHerbert Xu 		    cpu_online_mask);
526*bbefa1ddSHerbert Xu 	if (cpu >= 0)
527*bbefa1ddSHerbert Xu 		cpumask_clear_cpu(cpu, pinst->rcpumask.pcpu);
528*bbefa1ddSHerbert Xu 	if (!cpumask_equal(pinst->omask, pinst->rcpumask.pcpu))
529*bbefa1ddSHerbert Xu 		notification_mask |= PADATA_CPU_PARALLEL;
530*bbefa1ddSHerbert Xu 
531*bbefa1ddSHerbert Xu 	cpumask_copy(pinst->omask, pinst->rcpumask.cbcpu);
532*bbefa1ddSHerbert Xu 	cpumask_and(pinst->rcpumask.cbcpu, pinst->cpumask.cbcpu,
533*bbefa1ddSHerbert Xu 		    cpu_online_mask);
534*bbefa1ddSHerbert Xu 	if (cpu >= 0)
535*bbefa1ddSHerbert Xu 		cpumask_clear_cpu(cpu, pinst->rcpumask.cbcpu);
536*bbefa1ddSHerbert Xu 	if (!cpumask_equal(pinst->omask, pinst->rcpumask.cbcpu))
537*bbefa1ddSHerbert Xu 		notification_mask |= PADATA_CPU_SERIAL;
538*bbefa1ddSHerbert Xu 
539*bbefa1ddSHerbert Xu 	list_for_each_entry(ps, &pinst->pslist, list) {
540*bbefa1ddSHerbert Xu 		err = padata_replace_one(ps);
541*bbefa1ddSHerbert Xu 		if (err)
542*bbefa1ddSHerbert Xu 			break;
543*bbefa1ddSHerbert Xu 	}
54416295becSSteffen Klassert 
54516295becSSteffen Klassert 	synchronize_rcu();
54616295becSSteffen Klassert 
547*bbefa1ddSHerbert Xu 	list_for_each_entry_continue_reverse(ps, &pinst->pslist, list)
548*bbefa1ddSHerbert Xu 		if (atomic_dec_and_test(&ps->opd->refcnt))
549*bbefa1ddSHerbert Xu 			padata_free_pd(ps->opd);
55016295becSSteffen Klassert 
551e15bacbeSDan Kruchinin 	if (notification_mask)
552e15bacbeSDan Kruchinin 		blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
553c635696cSSteffen Klassert 					     notification_mask,
554*bbefa1ddSHerbert Xu 					     &pinst->cpumask);
555e15bacbeSDan Kruchinin 
55616295becSSteffen Klassert 	pinst->flags &= ~PADATA_RESET;
557*bbefa1ddSHerbert Xu 
558*bbefa1ddSHerbert Xu 	return err;
55916295becSSteffen Klassert }
56016295becSSteffen Klassert 
5610198ffd1SSteffen Klassert /**
562e15bacbeSDan Kruchinin  * padata_register_cpumask_notifier - Registers a notifier that will be called
563e15bacbeSDan Kruchinin  *                             if either pcpu or cbcpu or both cpumasks change.
56416295becSSteffen Klassert  *
565e15bacbeSDan Kruchinin  * @pinst: A poineter to padata instance
566e15bacbeSDan Kruchinin  * @nblock: A pointer to notifier block.
56716295becSSteffen Klassert  */
568e15bacbeSDan Kruchinin int padata_register_cpumask_notifier(struct padata_instance *pinst,
569e15bacbeSDan Kruchinin 				     struct notifier_block *nblock)
57016295becSSteffen Klassert {
571e15bacbeSDan Kruchinin 	return blocking_notifier_chain_register(&pinst->cpumask_change_notifier,
572e15bacbeSDan Kruchinin 						nblock);
573e15bacbeSDan Kruchinin }
574e15bacbeSDan Kruchinin EXPORT_SYMBOL(padata_register_cpumask_notifier);
57516295becSSteffen Klassert 
576e15bacbeSDan Kruchinin /**
577e15bacbeSDan Kruchinin  * padata_unregister_cpumask_notifier - Unregisters cpumask notifier
578e15bacbeSDan Kruchinin  *        registered earlier  using padata_register_cpumask_notifier
579e15bacbeSDan Kruchinin  *
580e15bacbeSDan Kruchinin  * @pinst: A pointer to data instance.
581e15bacbeSDan Kruchinin  * @nlock: A pointer to notifier block.
582e15bacbeSDan Kruchinin  */
583e15bacbeSDan Kruchinin int padata_unregister_cpumask_notifier(struct padata_instance *pinst,
584e15bacbeSDan Kruchinin 				       struct notifier_block *nblock)
585e15bacbeSDan Kruchinin {
586e15bacbeSDan Kruchinin 	return blocking_notifier_chain_unregister(
587e15bacbeSDan Kruchinin 		&pinst->cpumask_change_notifier,
588e15bacbeSDan Kruchinin 		nblock);
589e15bacbeSDan Kruchinin }
590e15bacbeSDan Kruchinin EXPORT_SYMBOL(padata_unregister_cpumask_notifier);
59116295becSSteffen Klassert 
5926751fb3cSSteffen Klassert 
59333e54450SSteffen Klassert /* If cpumask contains no active cpu, we mark the instance as invalid. */
59433e54450SSteffen Klassert static bool padata_validate_cpumask(struct padata_instance *pinst,
59533e54450SSteffen Klassert 				    const struct cpumask *cpumask)
59633e54450SSteffen Klassert {
59713614e0fSSteffen Klassert 	if (!cpumask_intersects(cpumask, cpu_online_mask)) {
59833e54450SSteffen Klassert 		pinst->flags |= PADATA_INVALID;
59933e54450SSteffen Klassert 		return false;
60016295becSSteffen Klassert 	}
60116295becSSteffen Klassert 
60233e54450SSteffen Klassert 	pinst->flags &= ~PADATA_INVALID;
60333e54450SSteffen Klassert 	return true;
60433e54450SSteffen Klassert }
60533e54450SSteffen Klassert 
60665ff577eSSteffen Klassert static int __padata_set_cpumasks(struct padata_instance *pinst,
60765ff577eSSteffen Klassert 				 cpumask_var_t pcpumask,
60865ff577eSSteffen Klassert 				 cpumask_var_t cbcpumask)
609e15bacbeSDan Kruchinin {
61033e54450SSteffen Klassert 	int valid;
611*bbefa1ddSHerbert Xu 	int err;
61216295becSSteffen Klassert 
613e15bacbeSDan Kruchinin 	valid = padata_validate_cpumask(pinst, pcpumask);
614e15bacbeSDan Kruchinin 	if (!valid) {
615e15bacbeSDan Kruchinin 		__padata_stop(pinst);
616e15bacbeSDan Kruchinin 		goto out_replace;
617e15bacbeSDan Kruchinin 	}
618e15bacbeSDan Kruchinin 
619e15bacbeSDan Kruchinin 	valid = padata_validate_cpumask(pinst, cbcpumask);
620b89661dfSSteffen Klassert 	if (!valid)
62133e54450SSteffen Klassert 		__padata_stop(pinst);
62233e54450SSteffen Klassert 
623b89661dfSSteffen Klassert out_replace:
624e15bacbeSDan Kruchinin 	cpumask_copy(pinst->cpumask.pcpu, pcpumask);
625e15bacbeSDan Kruchinin 	cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
62616295becSSteffen Klassert 
627*bbefa1ddSHerbert Xu 	err = padata_setup_cpumasks(pinst) ?: padata_replace(pinst, -1);
62816295becSSteffen Klassert 
62933e54450SSteffen Klassert 	if (valid)
63033e54450SSteffen Klassert 		__padata_start(pinst);
63133e54450SSteffen Klassert 
632*bbefa1ddSHerbert Xu 	return err;
63365ff577eSSteffen Klassert }
63465ff577eSSteffen Klassert 
63565ff577eSSteffen Klassert /**
63665ff577eSSteffen Klassert  * padata_set_cpumask: Sets specified by @cpumask_type cpumask to the value
63765ff577eSSteffen Klassert  *                     equivalent to @cpumask.
63865ff577eSSteffen Klassert  *
63965ff577eSSteffen Klassert  * @pinst: padata instance
64065ff577eSSteffen Klassert  * @cpumask_type: PADATA_CPU_SERIAL or PADATA_CPU_PARALLEL corresponding
64165ff577eSSteffen Klassert  *                to parallel and serial cpumasks respectively.
64265ff577eSSteffen Klassert  * @cpumask: the cpumask to use
64365ff577eSSteffen Klassert  */
64465ff577eSSteffen Klassert int padata_set_cpumask(struct padata_instance *pinst, int cpumask_type,
64565ff577eSSteffen Klassert 		       cpumask_var_t cpumask)
64665ff577eSSteffen Klassert {
64765ff577eSSteffen Klassert 	struct cpumask *serial_mask, *parallel_mask;
64865ff577eSSteffen Klassert 	int err = -EINVAL;
64965ff577eSSteffen Klassert 
65065ff577eSSteffen Klassert 	mutex_lock(&pinst->lock);
65165ff577eSSteffen Klassert 	get_online_cpus();
65265ff577eSSteffen Klassert 
65365ff577eSSteffen Klassert 	switch (cpumask_type) {
65465ff577eSSteffen Klassert 	case PADATA_CPU_PARALLEL:
65565ff577eSSteffen Klassert 		serial_mask = pinst->cpumask.cbcpu;
65665ff577eSSteffen Klassert 		parallel_mask = cpumask;
65765ff577eSSteffen Klassert 		break;
65865ff577eSSteffen Klassert 	case PADATA_CPU_SERIAL:
65965ff577eSSteffen Klassert 		parallel_mask = pinst->cpumask.pcpu;
66065ff577eSSteffen Klassert 		serial_mask = cpumask;
66165ff577eSSteffen Klassert 		break;
66265ff577eSSteffen Klassert 	default:
66365ff577eSSteffen Klassert 		 goto out;
66465ff577eSSteffen Klassert 	}
66565ff577eSSteffen Klassert 
66665ff577eSSteffen Klassert 	err =  __padata_set_cpumasks(pinst, parallel_mask, serial_mask);
66765ff577eSSteffen Klassert 
66816295becSSteffen Klassert out:
6696751fb3cSSteffen Klassert 	put_online_cpus();
67016295becSSteffen Klassert 	mutex_unlock(&pinst->lock);
67116295becSSteffen Klassert 
67216295becSSteffen Klassert 	return err;
67316295becSSteffen Klassert }
67416295becSSteffen Klassert EXPORT_SYMBOL(padata_set_cpumask);
67516295becSSteffen Klassert 
67619d795b6SArnd Bergmann /**
67719d795b6SArnd Bergmann  * padata_start - start the parallel processing
67819d795b6SArnd Bergmann  *
67919d795b6SArnd Bergmann  * @pinst: padata instance to start
68019d795b6SArnd Bergmann  */
68119d795b6SArnd Bergmann int padata_start(struct padata_instance *pinst)
68219d795b6SArnd Bergmann {
68319d795b6SArnd Bergmann 	int err = 0;
68419d795b6SArnd Bergmann 
68519d795b6SArnd Bergmann 	mutex_lock(&pinst->lock);
68619d795b6SArnd Bergmann 
68719d795b6SArnd Bergmann 	if (pinst->flags & PADATA_INVALID)
68819d795b6SArnd Bergmann 		err = -EINVAL;
68919d795b6SArnd Bergmann 
69019d795b6SArnd Bergmann 	__padata_start(pinst);
69119d795b6SArnd Bergmann 
69219d795b6SArnd Bergmann 	mutex_unlock(&pinst->lock);
69319d795b6SArnd Bergmann 
69419d795b6SArnd Bergmann 	return err;
69519d795b6SArnd Bergmann }
69619d795b6SArnd Bergmann EXPORT_SYMBOL(padata_start);
69719d795b6SArnd Bergmann 
69819d795b6SArnd Bergmann /**
69919d795b6SArnd Bergmann  * padata_stop - stop the parallel processing
70019d795b6SArnd Bergmann  *
70119d795b6SArnd Bergmann  * @pinst: padata instance to stop
70219d795b6SArnd Bergmann  */
70319d795b6SArnd Bergmann void padata_stop(struct padata_instance *pinst)
70419d795b6SArnd Bergmann {
70519d795b6SArnd Bergmann 	mutex_lock(&pinst->lock);
70619d795b6SArnd Bergmann 	__padata_stop(pinst);
70719d795b6SArnd Bergmann 	mutex_unlock(&pinst->lock);
70819d795b6SArnd Bergmann }
70919d795b6SArnd Bergmann EXPORT_SYMBOL(padata_stop);
71019d795b6SArnd Bergmann 
71119d795b6SArnd Bergmann #ifdef CONFIG_HOTPLUG_CPU
71219d795b6SArnd Bergmann 
71316295becSSteffen Klassert static int __padata_add_cpu(struct padata_instance *pinst, int cpu)
71416295becSSteffen Klassert {
715*bbefa1ddSHerbert Xu 	int err = 0;
71616295becSSteffen Klassert 
71713614e0fSSteffen Klassert 	if (cpumask_test_cpu(cpu, cpu_online_mask)) {
718*bbefa1ddSHerbert Xu 		err = padata_replace(pinst, -1);
71933e54450SSteffen Klassert 
720e15bacbeSDan Kruchinin 		if (padata_validate_cpumask(pinst, pinst->cpumask.pcpu) &&
721e15bacbeSDan Kruchinin 		    padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
72233e54450SSteffen Klassert 			__padata_start(pinst);
72316295becSSteffen Klassert 	}
72416295becSSteffen Klassert 
725*bbefa1ddSHerbert Xu 	return err;
72616295becSSteffen Klassert }
72716295becSSteffen Klassert 
72816295becSSteffen Klassert static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
72916295becSSteffen Klassert {
730*bbefa1ddSHerbert Xu 	int err = 0;
73116295becSSteffen Klassert 
73216295becSSteffen Klassert 	if (cpumask_test_cpu(cpu, cpu_online_mask)) {
733e15bacbeSDan Kruchinin 		if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) ||
734b89661dfSSteffen Klassert 		    !padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
73533e54450SSteffen Klassert 			__padata_stop(pinst);
73633e54450SSteffen Klassert 
737*bbefa1ddSHerbert Xu 		err = padata_replace(pinst, cpu);
73816295becSSteffen Klassert 	}
73916295becSSteffen Klassert 
740*bbefa1ddSHerbert Xu 	return err;
74116295becSSteffen Klassert }
74216295becSSteffen Klassert 
743e15bacbeSDan Kruchinin static inline int pinst_has_cpu(struct padata_instance *pinst, int cpu)
744e15bacbeSDan Kruchinin {
745e15bacbeSDan Kruchinin 	return cpumask_test_cpu(cpu, pinst->cpumask.pcpu) ||
746e15bacbeSDan Kruchinin 		cpumask_test_cpu(cpu, pinst->cpumask.cbcpu);
747e15bacbeSDan Kruchinin }
748e15bacbeSDan Kruchinin 
74930e92153SSebastian Andrzej Siewior static int padata_cpu_online(unsigned int cpu, struct hlist_node *node)
75016295becSSteffen Klassert {
75116295becSSteffen Klassert 	struct padata_instance *pinst;
75230e92153SSebastian Andrzej Siewior 	int ret;
75316295becSSteffen Klassert 
75430e92153SSebastian Andrzej Siewior 	pinst = hlist_entry_safe(node, struct padata_instance, node);
755e15bacbeSDan Kruchinin 	if (!pinst_has_cpu(pinst, cpu))
75630e92153SSebastian Andrzej Siewior 		return 0;
75716295becSSteffen Klassert 
75816295becSSteffen Klassert 	mutex_lock(&pinst->lock);
75930e92153SSebastian Andrzej Siewior 	ret = __padata_add_cpu(pinst, cpu);
76016295becSSteffen Klassert 	mutex_unlock(&pinst->lock);
76130e92153SSebastian Andrzej Siewior 	return ret;
76216295becSSteffen Klassert }
76316295becSSteffen Klassert 
76430e92153SSebastian Andrzej Siewior static int padata_cpu_prep_down(unsigned int cpu, struct hlist_node *node)
76530e92153SSebastian Andrzej Siewior {
76630e92153SSebastian Andrzej Siewior 	struct padata_instance *pinst;
76730e92153SSebastian Andrzej Siewior 	int ret;
76830e92153SSebastian Andrzej Siewior 
76930e92153SSebastian Andrzej Siewior 	pinst = hlist_entry_safe(node, struct padata_instance, node);
77030e92153SSebastian Andrzej Siewior 	if (!pinst_has_cpu(pinst, cpu))
77130e92153SSebastian Andrzej Siewior 		return 0;
77230e92153SSebastian Andrzej Siewior 
77330e92153SSebastian Andrzej Siewior 	mutex_lock(&pinst->lock);
77430e92153SSebastian Andrzej Siewior 	ret = __padata_remove_cpu(pinst, cpu);
77530e92153SSebastian Andrzej Siewior 	mutex_unlock(&pinst->lock);
77630e92153SSebastian Andrzej Siewior 	return ret;
77716295becSSteffen Klassert }
77830e92153SSebastian Andrzej Siewior 
77930e92153SSebastian Andrzej Siewior static enum cpuhp_state hp_online;
780e2cb2f1cSSteffen Klassert #endif
78116295becSSteffen Klassert 
7825e017dc3SDan Kruchinin static void __padata_free(struct padata_instance *pinst)
7835e017dc3SDan Kruchinin {
7845e017dc3SDan Kruchinin #ifdef CONFIG_HOTPLUG_CPU
78530e92153SSebastian Andrzej Siewior 	cpuhp_state_remove_instance_nocalls(hp_online, &pinst->node);
7865e017dc3SDan Kruchinin #endif
7875e017dc3SDan Kruchinin 
788*bbefa1ddSHerbert Xu 	WARN_ON(!list_empty(&pinst->pslist));
789*bbefa1ddSHerbert Xu 
7905e017dc3SDan Kruchinin 	padata_stop(pinst);
791*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->omask);
792*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->rcpumask.cbcpu);
793*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->rcpumask.pcpu);
7945e017dc3SDan Kruchinin 	free_cpumask_var(pinst->cpumask.pcpu);
7955e017dc3SDan Kruchinin 	free_cpumask_var(pinst->cpumask.cbcpu);
79645d153c0SDaniel Jordan 	destroy_workqueue(pinst->serial_wq);
79745d153c0SDaniel Jordan 	destroy_workqueue(pinst->parallel_wq);
7985e017dc3SDan Kruchinin 	kfree(pinst);
7995e017dc3SDan Kruchinin }
8005e017dc3SDan Kruchinin 
8015e017dc3SDan Kruchinin #define kobj2pinst(_kobj)					\
8025e017dc3SDan Kruchinin 	container_of(_kobj, struct padata_instance, kobj)
8035e017dc3SDan Kruchinin #define attr2pentry(_attr)					\
8045e017dc3SDan Kruchinin 	container_of(_attr, struct padata_sysfs_entry, attr)
8055e017dc3SDan Kruchinin 
8065e017dc3SDan Kruchinin static void padata_sysfs_release(struct kobject *kobj)
8075e017dc3SDan Kruchinin {
8085e017dc3SDan Kruchinin 	struct padata_instance *pinst = kobj2pinst(kobj);
8095e017dc3SDan Kruchinin 	__padata_free(pinst);
8105e017dc3SDan Kruchinin }
8115e017dc3SDan Kruchinin 
8125e017dc3SDan Kruchinin struct padata_sysfs_entry {
8135e017dc3SDan Kruchinin 	struct attribute attr;
8145e017dc3SDan Kruchinin 	ssize_t (*show)(struct padata_instance *, struct attribute *, char *);
8155e017dc3SDan Kruchinin 	ssize_t (*store)(struct padata_instance *, struct attribute *,
8165e017dc3SDan Kruchinin 			 const char *, size_t);
8175e017dc3SDan Kruchinin };
8185e017dc3SDan Kruchinin 
8195e017dc3SDan Kruchinin static ssize_t show_cpumask(struct padata_instance *pinst,
8205e017dc3SDan Kruchinin 			    struct attribute *attr,  char *buf)
8215e017dc3SDan Kruchinin {
8225e017dc3SDan Kruchinin 	struct cpumask *cpumask;
8235e017dc3SDan Kruchinin 	ssize_t len;
8245e017dc3SDan Kruchinin 
8255e017dc3SDan Kruchinin 	mutex_lock(&pinst->lock);
8265e017dc3SDan Kruchinin 	if (!strcmp(attr->name, "serial_cpumask"))
8275e017dc3SDan Kruchinin 		cpumask = pinst->cpumask.cbcpu;
8285e017dc3SDan Kruchinin 	else
8295e017dc3SDan Kruchinin 		cpumask = pinst->cpumask.pcpu;
8305e017dc3SDan Kruchinin 
8314497da6fSTejun Heo 	len = snprintf(buf, PAGE_SIZE, "%*pb\n",
8324497da6fSTejun Heo 		       nr_cpu_ids, cpumask_bits(cpumask));
8335e017dc3SDan Kruchinin 	mutex_unlock(&pinst->lock);
8344497da6fSTejun Heo 	return len < PAGE_SIZE ? len : -EINVAL;
8355e017dc3SDan Kruchinin }
8365e017dc3SDan Kruchinin 
8375e017dc3SDan Kruchinin static ssize_t store_cpumask(struct padata_instance *pinst,
8385e017dc3SDan Kruchinin 			     struct attribute *attr,
8395e017dc3SDan Kruchinin 			     const char *buf, size_t count)
8405e017dc3SDan Kruchinin {
8415e017dc3SDan Kruchinin 	cpumask_var_t new_cpumask;
8425e017dc3SDan Kruchinin 	ssize_t ret;
8435e017dc3SDan Kruchinin 	int mask_type;
8445e017dc3SDan Kruchinin 
8455e017dc3SDan Kruchinin 	if (!alloc_cpumask_var(&new_cpumask, GFP_KERNEL))
8465e017dc3SDan Kruchinin 		return -ENOMEM;
8475e017dc3SDan Kruchinin 
8485e017dc3SDan Kruchinin 	ret = bitmap_parse(buf, count, cpumask_bits(new_cpumask),
8495e017dc3SDan Kruchinin 			   nr_cpumask_bits);
8505e017dc3SDan Kruchinin 	if (ret < 0)
8515e017dc3SDan Kruchinin 		goto out;
8525e017dc3SDan Kruchinin 
8535e017dc3SDan Kruchinin 	mask_type = !strcmp(attr->name, "serial_cpumask") ?
8545e017dc3SDan Kruchinin 		PADATA_CPU_SERIAL : PADATA_CPU_PARALLEL;
8555e017dc3SDan Kruchinin 	ret = padata_set_cpumask(pinst, mask_type, new_cpumask);
8565e017dc3SDan Kruchinin 	if (!ret)
8575e017dc3SDan Kruchinin 		ret = count;
8585e017dc3SDan Kruchinin 
8595e017dc3SDan Kruchinin out:
8605e017dc3SDan Kruchinin 	free_cpumask_var(new_cpumask);
8615e017dc3SDan Kruchinin 	return ret;
8625e017dc3SDan Kruchinin }
8635e017dc3SDan Kruchinin 
8645e017dc3SDan Kruchinin #define PADATA_ATTR_RW(_name, _show_name, _store_name)		\
8655e017dc3SDan Kruchinin 	static struct padata_sysfs_entry _name##_attr =		\
8665e017dc3SDan Kruchinin 		__ATTR(_name, 0644, _show_name, _store_name)
8675e017dc3SDan Kruchinin #define PADATA_ATTR_RO(_name, _show_name)		\
8685e017dc3SDan Kruchinin 	static struct padata_sysfs_entry _name##_attr = \
8695e017dc3SDan Kruchinin 		__ATTR(_name, 0400, _show_name, NULL)
8705e017dc3SDan Kruchinin 
8715e017dc3SDan Kruchinin PADATA_ATTR_RW(serial_cpumask, show_cpumask, store_cpumask);
8725e017dc3SDan Kruchinin PADATA_ATTR_RW(parallel_cpumask, show_cpumask, store_cpumask);
8735e017dc3SDan Kruchinin 
8745e017dc3SDan Kruchinin /*
8755e017dc3SDan Kruchinin  * Padata sysfs provides the following objects:
8765e017dc3SDan Kruchinin  * serial_cpumask   [RW] - cpumask for serial workers
8775e017dc3SDan Kruchinin  * parallel_cpumask [RW] - cpumask for parallel workers
87816295becSSteffen Klassert  */
8795e017dc3SDan Kruchinin static struct attribute *padata_default_attrs[] = {
8805e017dc3SDan Kruchinin 	&serial_cpumask_attr.attr,
8815e017dc3SDan Kruchinin 	&parallel_cpumask_attr.attr,
8825e017dc3SDan Kruchinin 	NULL,
8835e017dc3SDan Kruchinin };
8842064fbc7SKimberly Brown ATTRIBUTE_GROUPS(padata_default);
8855e017dc3SDan Kruchinin 
8865e017dc3SDan Kruchinin static ssize_t padata_sysfs_show(struct kobject *kobj,
8875e017dc3SDan Kruchinin 				 struct attribute *attr, char *buf)
88816295becSSteffen Klassert {
88916295becSSteffen Klassert 	struct padata_instance *pinst;
8905e017dc3SDan Kruchinin 	struct padata_sysfs_entry *pentry;
8915e017dc3SDan Kruchinin 	ssize_t ret = -EIO;
8925e017dc3SDan Kruchinin 
8935e017dc3SDan Kruchinin 	pinst = kobj2pinst(kobj);
8945e017dc3SDan Kruchinin 	pentry = attr2pentry(attr);
8955e017dc3SDan Kruchinin 	if (pentry->show)
8965e017dc3SDan Kruchinin 		ret = pentry->show(pinst, attr, buf);
8975e017dc3SDan Kruchinin 
8985e017dc3SDan Kruchinin 	return ret;
8995e017dc3SDan Kruchinin }
9005e017dc3SDan Kruchinin 
9015e017dc3SDan Kruchinin static ssize_t padata_sysfs_store(struct kobject *kobj, struct attribute *attr,
9025e017dc3SDan Kruchinin 				  const char *buf, size_t count)
9035e017dc3SDan Kruchinin {
9045e017dc3SDan Kruchinin 	struct padata_instance *pinst;
9055e017dc3SDan Kruchinin 	struct padata_sysfs_entry *pentry;
9065e017dc3SDan Kruchinin 	ssize_t ret = -EIO;
9075e017dc3SDan Kruchinin 
9085e017dc3SDan Kruchinin 	pinst = kobj2pinst(kobj);
9095e017dc3SDan Kruchinin 	pentry = attr2pentry(attr);
9105e017dc3SDan Kruchinin 	if (pentry->show)
9115e017dc3SDan Kruchinin 		ret = pentry->store(pinst, attr, buf, count);
9125e017dc3SDan Kruchinin 
9135e017dc3SDan Kruchinin 	return ret;
9145e017dc3SDan Kruchinin }
9155e017dc3SDan Kruchinin 
9165e017dc3SDan Kruchinin static const struct sysfs_ops padata_sysfs_ops = {
9175e017dc3SDan Kruchinin 	.show = padata_sysfs_show,
9185e017dc3SDan Kruchinin 	.store = padata_sysfs_store,
9195e017dc3SDan Kruchinin };
9205e017dc3SDan Kruchinin 
9215e017dc3SDan Kruchinin static struct kobj_type padata_attr_type = {
9225e017dc3SDan Kruchinin 	.sysfs_ops = &padata_sysfs_ops,
9232064fbc7SKimberly Brown 	.default_groups = padata_default_groups,
9245e017dc3SDan Kruchinin 	.release = padata_sysfs_release,
9255e017dc3SDan Kruchinin };
9265e017dc3SDan Kruchinin 
92716295becSSteffen Klassert /**
928e6cc1170SSteffen Klassert  * padata_alloc - allocate and initialize a padata instance and specify
929e6cc1170SSteffen Klassert  *                cpumasks for serial and parallel workers.
930e15bacbeSDan Kruchinin  *
931b128a304SDaniel Jordan  * @name: used to identify the instance
932e15bacbeSDan Kruchinin  * @pcpumask: cpumask that will be used for padata parallelization
933e15bacbeSDan Kruchinin  * @cbcpumask: cpumask that will be used for padata serialization
934e15bacbeSDan Kruchinin  */
935b128a304SDaniel Jordan static struct padata_instance *padata_alloc(const char *name,
936e15bacbeSDan Kruchinin 					    const struct cpumask *pcpumask,
937e15bacbeSDan Kruchinin 					    const struct cpumask *cbcpumask)
93816295becSSteffen Klassert {
93916295becSSteffen Klassert 	struct padata_instance *pinst;
94016295becSSteffen Klassert 
94116295becSSteffen Klassert 	pinst = kzalloc(sizeof(struct padata_instance), GFP_KERNEL);
94216295becSSteffen Klassert 	if (!pinst)
94316295becSSteffen Klassert 		goto err;
94416295becSSteffen Klassert 
945bfde23ceSDaniel Jordan 	pinst->parallel_wq = alloc_workqueue("%s_parallel", WQ_UNBOUND, 0,
946bfde23ceSDaniel Jordan 					     name);
94745d153c0SDaniel Jordan 	if (!pinst->parallel_wq)
94816295becSSteffen Klassert 		goto err_free_inst;
949b128a304SDaniel Jordan 
950cc491d8eSDaniel Jordan 	get_online_cpus();
951cc491d8eSDaniel Jordan 
95245d153c0SDaniel Jordan 	pinst->serial_wq = alloc_workqueue("%s_serial", WQ_MEM_RECLAIM |
95345d153c0SDaniel Jordan 					   WQ_CPU_INTENSIVE, 1, name);
95445d153c0SDaniel Jordan 	if (!pinst->serial_wq)
955cc491d8eSDaniel Jordan 		goto err_put_cpus;
95645d153c0SDaniel Jordan 
95745d153c0SDaniel Jordan 	if (!alloc_cpumask_var(&pinst->cpumask.pcpu, GFP_KERNEL))
95845d153c0SDaniel Jordan 		goto err_free_serial_wq;
959e15bacbeSDan Kruchinin 	if (!alloc_cpumask_var(&pinst->cpumask.cbcpu, GFP_KERNEL)) {
960e15bacbeSDan Kruchinin 		free_cpumask_var(pinst->cpumask.pcpu);
96145d153c0SDaniel Jordan 		goto err_free_serial_wq;
96233e54450SSteffen Klassert 	}
963e15bacbeSDan Kruchinin 	if (!padata_validate_cpumask(pinst, pcpumask) ||
964e15bacbeSDan Kruchinin 	    !padata_validate_cpumask(pinst, cbcpumask))
965e15bacbeSDan Kruchinin 		goto err_free_masks;
96616295becSSteffen Klassert 
967*bbefa1ddSHerbert Xu 	if (!alloc_cpumask_var(&pinst->rcpumask.pcpu, GFP_KERNEL))
968e15bacbeSDan Kruchinin 		goto err_free_masks;
969*bbefa1ddSHerbert Xu 	if (!alloc_cpumask_var(&pinst->rcpumask.cbcpu, GFP_KERNEL))
970*bbefa1ddSHerbert Xu 		goto err_free_rcpumask_pcpu;
971*bbefa1ddSHerbert Xu 	if (!alloc_cpumask_var(&pinst->omask, GFP_KERNEL))
972*bbefa1ddSHerbert Xu 		goto err_free_rcpumask_cbcpu;
97374781387SSteffen Klassert 
974*bbefa1ddSHerbert Xu 	INIT_LIST_HEAD(&pinst->pslist);
97516295becSSteffen Klassert 
976e15bacbeSDan Kruchinin 	cpumask_copy(pinst->cpumask.pcpu, pcpumask);
977e15bacbeSDan Kruchinin 	cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);
978*bbefa1ddSHerbert Xu 	cpumask_and(pinst->rcpumask.pcpu, pcpumask, cpu_online_mask);
979*bbefa1ddSHerbert Xu 	cpumask_and(pinst->rcpumask.cbcpu, cbcpumask, cpu_online_mask);
980*bbefa1ddSHerbert Xu 
981*bbefa1ddSHerbert Xu 	if (padata_setup_cpumasks(pinst))
982*bbefa1ddSHerbert Xu 		goto err_free_omask;
98316295becSSteffen Klassert 
98416295becSSteffen Klassert 	pinst->flags = 0;
98516295becSSteffen Klassert 
986e15bacbeSDan Kruchinin 	BLOCKING_INIT_NOTIFIER_HEAD(&pinst->cpumask_change_notifier);
9875e017dc3SDan Kruchinin 	kobject_init(&pinst->kobj, &padata_attr_type);
98816295becSSteffen Klassert 	mutex_init(&pinst->lock);
98916295becSSteffen Klassert 
990b8b4a416SRichard Weinberger #ifdef CONFIG_HOTPLUG_CPU
991c5a81c8fSSebastian Andrzej Siewior 	cpuhp_state_add_instance_nocalls_cpuslocked(hp_online, &pinst->node);
992b8b4a416SRichard Weinberger #endif
993cc491d8eSDaniel Jordan 
994cc491d8eSDaniel Jordan 	put_online_cpus();
995cc491d8eSDaniel Jordan 
99616295becSSteffen Klassert 	return pinst;
99716295becSSteffen Klassert 
998*bbefa1ddSHerbert Xu err_free_omask:
999*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->omask);
1000*bbefa1ddSHerbert Xu err_free_rcpumask_cbcpu:
1001*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->rcpumask.cbcpu);
1002*bbefa1ddSHerbert Xu err_free_rcpumask_pcpu:
1003*bbefa1ddSHerbert Xu 	free_cpumask_var(pinst->rcpumask.pcpu);
1004e15bacbeSDan Kruchinin err_free_masks:
1005e15bacbeSDan Kruchinin 	free_cpumask_var(pinst->cpumask.pcpu);
1006e15bacbeSDan Kruchinin 	free_cpumask_var(pinst->cpumask.cbcpu);
100745d153c0SDaniel Jordan err_free_serial_wq:
100845d153c0SDaniel Jordan 	destroy_workqueue(pinst->serial_wq);
1009cc491d8eSDaniel Jordan err_put_cpus:
1010cc491d8eSDaniel Jordan 	put_online_cpus();
101145d153c0SDaniel Jordan 	destroy_workqueue(pinst->parallel_wq);
101216295becSSteffen Klassert err_free_inst:
101316295becSSteffen Klassert 	kfree(pinst);
101416295becSSteffen Klassert err:
101516295becSSteffen Klassert 	return NULL;
101616295becSSteffen Klassert }
101716295becSSteffen Klassert 
10180198ffd1SSteffen Klassert /**
10199596695eSThomas Gleixner  * padata_alloc_possible - Allocate and initialize padata instance.
10209596695eSThomas Gleixner  *                         Use the cpu_possible_mask for serial and
10219596695eSThomas Gleixner  *                         parallel workers.
10229596695eSThomas Gleixner  *
1023b128a304SDaniel Jordan  * @name: used to identify the instance
10249596695eSThomas Gleixner  */
1025b128a304SDaniel Jordan struct padata_instance *padata_alloc_possible(const char *name)
10269596695eSThomas Gleixner {
1027b128a304SDaniel Jordan 	return padata_alloc(name, cpu_possible_mask, cpu_possible_mask);
10289596695eSThomas Gleixner }
10299596695eSThomas Gleixner EXPORT_SYMBOL(padata_alloc_possible);
10309596695eSThomas Gleixner 
10319596695eSThomas Gleixner /**
103216295becSSteffen Klassert  * padata_free - free a padata instance
103316295becSSteffen Klassert  *
103416295becSSteffen Klassert  * @padata_inst: padata instance to free
103516295becSSteffen Klassert  */
103616295becSSteffen Klassert void padata_free(struct padata_instance *pinst)
103716295becSSteffen Klassert {
10385e017dc3SDan Kruchinin 	kobject_put(&pinst->kobj);
103916295becSSteffen Klassert }
104016295becSSteffen Klassert EXPORT_SYMBOL(padata_free);
104130e92153SSebastian Andrzej Siewior 
1042*bbefa1ddSHerbert Xu /**
1043*bbefa1ddSHerbert Xu  * padata_alloc_shell - Allocate and initialize padata shell.
1044*bbefa1ddSHerbert Xu  *
1045*bbefa1ddSHerbert Xu  * @pinst: Parent padata_instance object.
1046*bbefa1ddSHerbert Xu  */
1047*bbefa1ddSHerbert Xu struct padata_shell *padata_alloc_shell(struct padata_instance *pinst)
1048*bbefa1ddSHerbert Xu {
1049*bbefa1ddSHerbert Xu 	struct parallel_data *pd;
1050*bbefa1ddSHerbert Xu 	struct padata_shell *ps;
1051*bbefa1ddSHerbert Xu 
1052*bbefa1ddSHerbert Xu 	ps = kzalloc(sizeof(*ps), GFP_KERNEL);
1053*bbefa1ddSHerbert Xu 	if (!ps)
1054*bbefa1ddSHerbert Xu 		goto out;
1055*bbefa1ddSHerbert Xu 
1056*bbefa1ddSHerbert Xu 	ps->pinst = pinst;
1057*bbefa1ddSHerbert Xu 
1058*bbefa1ddSHerbert Xu 	get_online_cpus();
1059*bbefa1ddSHerbert Xu 	pd = padata_alloc_pd(ps);
1060*bbefa1ddSHerbert Xu 	put_online_cpus();
1061*bbefa1ddSHerbert Xu 
1062*bbefa1ddSHerbert Xu 	if (!pd)
1063*bbefa1ddSHerbert Xu 		goto out_free_ps;
1064*bbefa1ddSHerbert Xu 
1065*bbefa1ddSHerbert Xu 	mutex_lock(&pinst->lock);
1066*bbefa1ddSHerbert Xu 	RCU_INIT_POINTER(ps->pd, pd);
1067*bbefa1ddSHerbert Xu 	list_add(&ps->list, &pinst->pslist);
1068*bbefa1ddSHerbert Xu 	mutex_unlock(&pinst->lock);
1069*bbefa1ddSHerbert Xu 
1070*bbefa1ddSHerbert Xu 	return ps;
1071*bbefa1ddSHerbert Xu 
1072*bbefa1ddSHerbert Xu out_free_ps:
1073*bbefa1ddSHerbert Xu 	kfree(ps);
1074*bbefa1ddSHerbert Xu out:
1075*bbefa1ddSHerbert Xu 	return NULL;
1076*bbefa1ddSHerbert Xu }
1077*bbefa1ddSHerbert Xu EXPORT_SYMBOL(padata_alloc_shell);
1078*bbefa1ddSHerbert Xu 
1079*bbefa1ddSHerbert Xu /**
1080*bbefa1ddSHerbert Xu  * padata_free_shell - free a padata shell
1081*bbefa1ddSHerbert Xu  *
1082*bbefa1ddSHerbert Xu  * @ps: padata shell to free
1083*bbefa1ddSHerbert Xu  */
1084*bbefa1ddSHerbert Xu void padata_free_shell(struct padata_shell *ps)
1085*bbefa1ddSHerbert Xu {
1086*bbefa1ddSHerbert Xu 	struct padata_instance *pinst = ps->pinst;
1087*bbefa1ddSHerbert Xu 
1088*bbefa1ddSHerbert Xu 	mutex_lock(&pinst->lock);
1089*bbefa1ddSHerbert Xu 	list_del(&ps->list);
1090*bbefa1ddSHerbert Xu 	padata_free_pd(rcu_dereference_protected(ps->pd, 1));
1091*bbefa1ddSHerbert Xu 	mutex_unlock(&pinst->lock);
1092*bbefa1ddSHerbert Xu 
1093*bbefa1ddSHerbert Xu 	kfree(ps);
1094*bbefa1ddSHerbert Xu }
1095*bbefa1ddSHerbert Xu EXPORT_SYMBOL(padata_free_shell);
1096*bbefa1ddSHerbert Xu 
109730e92153SSebastian Andrzej Siewior #ifdef CONFIG_HOTPLUG_CPU
109830e92153SSebastian Andrzej Siewior 
109930e92153SSebastian Andrzej Siewior static __init int padata_driver_init(void)
110030e92153SSebastian Andrzej Siewior {
110130e92153SSebastian Andrzej Siewior 	int ret;
110230e92153SSebastian Andrzej Siewior 
110330e92153SSebastian Andrzej Siewior 	ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, "padata:online",
110430e92153SSebastian Andrzej Siewior 				      padata_cpu_online,
110530e92153SSebastian Andrzej Siewior 				      padata_cpu_prep_down);
110630e92153SSebastian Andrzej Siewior 	if (ret < 0)
110730e92153SSebastian Andrzej Siewior 		return ret;
110830e92153SSebastian Andrzej Siewior 	hp_online = ret;
110930e92153SSebastian Andrzej Siewior 	return 0;
111030e92153SSebastian Andrzej Siewior }
111130e92153SSebastian Andrzej Siewior module_init(padata_driver_init);
111230e92153SSebastian Andrzej Siewior 
111330e92153SSebastian Andrzej Siewior static __exit void padata_driver_exit(void)
111430e92153SSebastian Andrzej Siewior {
111530e92153SSebastian Andrzej Siewior 	cpuhp_remove_multi_state(hp_online);
111630e92153SSebastian Andrzej Siewior }
111730e92153SSebastian Andrzej Siewior module_exit(padata_driver_exit);
111830e92153SSebastian Andrzej Siewior #endif
1119