@@ -94,7 +94,7 @@ static int get_nodes_in_cpumask(cpumask_var_t *node_to_cpumask,
94
94
return nodes ;
95
95
}
96
96
97
- static int irq_build_affinity_masks (const struct irq_affinity * affd ,
97
+ static int __irq_build_affinity_masks (const struct irq_affinity * affd ,
98
98
int startvec , int numvecs ,
99
99
cpumask_var_t * node_to_cpumask ,
100
100
const struct cpumask * cpu_mask ,
@@ -165,6 +165,58 @@ static int irq_build_affinity_masks(const struct irq_affinity *affd,
165
165
return done ;
166
166
}
167
167
168
+ /*
169
+ * build affinity in two stages:
170
+ * 1) spread present CPU on these vectors
171
+ * 2) spread other possible CPUs on these vectors
172
+ */
173
+ static int irq_build_affinity_masks (const struct irq_affinity * affd ,
174
+ int startvec , int numvecs ,
175
+ cpumask_var_t * node_to_cpumask ,
176
+ struct cpumask * masks )
177
+ {
178
+ int curvec = startvec , usedvecs = -1 ;
179
+ cpumask_var_t nmsk , npresmsk ;
180
+
181
+ if (!zalloc_cpumask_var (& nmsk , GFP_KERNEL ))
182
+ return usedvecs ;
183
+
184
+ if (!zalloc_cpumask_var (& npresmsk , GFP_KERNEL ))
185
+ goto fail ;
186
+
187
+ /* Stabilize the cpumasks */
188
+ get_online_cpus ();
189
+ build_node_to_cpumask (node_to_cpumask );
190
+
191
+ /* Spread on present CPUs starting from affd->pre_vectors */
192
+ usedvecs = __irq_build_affinity_masks (affd , curvec , numvecs ,
193
+ node_to_cpumask , cpu_present_mask ,
194
+ nmsk , masks );
195
+
196
+ /*
197
+ * Spread on non present CPUs starting from the next vector to be
198
+ * handled. If the spreading of present CPUs already exhausted the
199
+ * vector space, assign the non present CPUs to the already spread
200
+ * out vectors.
201
+ */
202
+ if (usedvecs >= numvecs )
203
+ curvec = affd -> pre_vectors ;
204
+ else
205
+ curvec = affd -> pre_vectors + usedvecs ;
206
+ cpumask_andnot (npresmsk , cpu_possible_mask , cpu_present_mask );
207
+ usedvecs += __irq_build_affinity_masks (affd , curvec , numvecs ,
208
+ node_to_cpumask , npresmsk ,
209
+ nmsk , masks );
210
+ put_online_cpus ();
211
+
212
+ free_cpumask_var (npresmsk );
213
+
214
+ fail :
215
+ free_cpumask_var (nmsk );
216
+
217
+ return usedvecs ;
218
+ }
219
+
168
220
/**
169
221
* irq_create_affinity_masks - Create affinity masks for multiqueue spreading
170
222
* @nvecs: The total number of vectors
@@ -177,7 +229,7 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
177
229
{
178
230
int affvecs = nvecs - affd -> pre_vectors - affd -> post_vectors ;
179
231
int curvec , usedvecs ;
180
- cpumask_var_t nmsk , npresmsk , * node_to_cpumask ;
232
+ cpumask_var_t * node_to_cpumask ;
181
233
struct cpumask * masks = NULL ;
182
234
183
235
/*
@@ -187,15 +239,9 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
187
239
if (nvecs == affd -> pre_vectors + affd -> post_vectors )
188
240
return NULL ;
189
241
190
- if (!zalloc_cpumask_var (& nmsk , GFP_KERNEL ))
191
- return NULL ;
192
-
193
- if (!zalloc_cpumask_var (& npresmsk , GFP_KERNEL ))
194
- goto outcpumsk ;
195
-
196
242
node_to_cpumask = alloc_node_to_cpumask ();
197
243
if (!node_to_cpumask )
198
- goto outnpresmsk ;
244
+ return NULL ;
199
245
200
246
masks = kcalloc (nvecs , sizeof (* masks ), GFP_KERNEL );
201
247
if (!masks )
@@ -205,30 +251,8 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
205
251
for (curvec = 0 ; curvec < affd -> pre_vectors ; curvec ++ )
206
252
cpumask_copy (masks + curvec , irq_default_affinity );
207
253
208
- /* Stabilize the cpumasks */
209
- get_online_cpus ();
210
- build_node_to_cpumask (node_to_cpumask );
211
-
212
- /* Spread on present CPUs starting from affd->pre_vectors */
213
254
usedvecs = irq_build_affinity_masks (affd , curvec , affvecs ,
214
- node_to_cpumask , cpu_present_mask ,
215
- nmsk , masks );
216
-
217
- /*
218
- * Spread on non present CPUs starting from the next vector to be
219
- * handled. If the spreading of present CPUs already exhausted the
220
- * vector space, assign the non present CPUs to the already spread
221
- * out vectors.
222
- */
223
- if (usedvecs >= affvecs )
224
- curvec = affd -> pre_vectors ;
225
- else
226
- curvec = affd -> pre_vectors + usedvecs ;
227
- cpumask_andnot (npresmsk , cpu_possible_mask , cpu_present_mask );
228
- usedvecs += irq_build_affinity_masks (affd , curvec , affvecs ,
229
- node_to_cpumask , npresmsk ,
230
- nmsk , masks );
231
- put_online_cpus ();
255
+ node_to_cpumask , masks );
232
256
233
257
/* Fill out vectors at the end that don't need affinity */
234
258
if (usedvecs >= affvecs )
@@ -240,10 +264,6 @@ irq_create_affinity_masks(int nvecs, const struct irq_affinity *affd)
240
264
241
265
outnodemsk :
242
266
free_node_to_cpumask (node_to_cpumask );
243
- outnpresmsk :
244
- free_cpumask_var (npresmsk );
245
- outcpumsk :
246
- free_cpumask_var (nmsk );
247
267
return masks ;
248
268
}
249
269
0 commit comments