summaryrefslogtreecommitdiffstats
path: root/kernel/padata.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/padata.c')
-rw-r--r--kernel/padata.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/kernel/padata.c b/kernel/padata.c
index 58728cd7f40c..9a17922ec436 100644
--- a/kernel/padata.c
+++ b/kernel/padata.c
@@ -94,17 +94,19 @@ static void padata_parallel_worker(struct work_struct *parallel_work)
94 * 94 *
95 * @pinst: padata instance 95 * @pinst: padata instance
96 * @padata: object to be parallelized 96 * @padata: object to be parallelized
97 * @cb_cpu: cpu the serialization callback function will run on, 97 * @cb_cpu: pointer to the CPU that the serialization callback function should
98 * must be in the serial cpumask of padata(i.e. cpumask.cbcpu). 98 * run on. If it's not in the serial cpumask of @pinst
99 * (i.e. cpumask.cbcpu), this function selects a fallback CPU and if
100 * none found, returns -EINVAL.
99 * 101 *
100 * The parallelization callback function will run with BHs off. 102 * The parallelization callback function will run with BHs off.
101 * Note: Every object which is parallelized by padata_do_parallel 103 * Note: Every object which is parallelized by padata_do_parallel
102 * must be seen by padata_do_serial. 104 * must be seen by padata_do_serial.
103 */ 105 */
104int padata_do_parallel(struct padata_instance *pinst, 106int padata_do_parallel(struct padata_instance *pinst,
105 struct padata_priv *padata, int cb_cpu) 107 struct padata_priv *padata, int *cb_cpu)
106{ 108{
107 int target_cpu, err; 109 int i, cpu, cpu_index, target_cpu, err;
108 struct padata_parallel_queue *queue; 110 struct padata_parallel_queue *queue;
109 struct parallel_data *pd; 111 struct parallel_data *pd;
110 112
@@ -116,8 +118,19 @@ int padata_do_parallel(struct padata_instance *pinst,
116 if (!(pinst->flags & PADATA_INIT) || pinst->flags & PADATA_INVALID) 118 if (!(pinst->flags & PADATA_INIT) || pinst->flags & PADATA_INVALID)
117 goto out; 119 goto out;
118 120
119 if (!cpumask_test_cpu(cb_cpu, pd->cpumask.cbcpu)) 121 if (!cpumask_test_cpu(*cb_cpu, pd->cpumask.cbcpu)) {
120 goto out; 122 if (!cpumask_weight(pd->cpumask.cbcpu))
123 goto out;
124
125 /* Select an alternate fallback CPU and notify the caller. */
126 cpu_index = *cb_cpu % cpumask_weight(pd->cpumask.cbcpu);
127
128 cpu = cpumask_first(pd->cpumask.cbcpu);
129 for (i = 0; i < cpu_index; i++)
130 cpu = cpumask_next(cpu, pd->cpumask.cbcpu);
131
132 *cb_cpu = cpu;
133 }
121 134
122 err = -EBUSY; 135 err = -EBUSY;
123 if ((pinst->flags & PADATA_RESET)) 136 if ((pinst->flags & PADATA_RESET))
@@ -129,7 +142,7 @@ int padata_do_parallel(struct padata_instance *pinst,
129 err = 0; 142 err = 0;
130 atomic_inc(&pd->refcnt); 143 atomic_inc(&pd->refcnt);
131 padata->pd = pd; 144 padata->pd = pd;
132 padata->cb_cpu = cb_cpu; 145 padata->cb_cpu = *cb_cpu;
133 146
134 target_cpu = padata_cpu_hash(pd); 147 target_cpu = padata_cpu_hash(pd);
135 padata->cpu = target_cpu; 148 padata->cpu = target_cpu;