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 ¶llel_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