@@ -345,15 +345,18 @@ EXPORT_SYMBOL_GPL(irq_set_affinity_notifier);
345345/*
346346 * Generic version of the affinity autoselector.
347347 */
348- static int setup_affinity (struct irq_desc * desc , struct cpumask * mask )
348+ static int irq_setup_affinity (struct irq_desc * desc )
349349{
350350 struct cpumask * set = irq_default_affinity ;
351- int node = irq_desc_get_node (desc );
351+ int ret , node = irq_desc_get_node (desc );
352+ static DEFINE_RAW_SPINLOCK (mask_lock );
353+ static struct cpumask mask ;
352354
353355 /* Excludes PER_CPU and NO_BALANCE interrupts */
354356 if (!__irq_can_set_affinity (desc ))
355357 return 0 ;
356358
359+ raw_spin_lock (& mask_lock );
357360 /*
358361 * Preserve the managed affinity setting and a userspace affinity
359362 * setup, but make sure that one of the targets is online.
@@ -367,43 +370,42 @@ static int setup_affinity(struct irq_desc *desc, struct cpumask *mask)
367370 irqd_clear (& desc -> irq_data , IRQD_AFFINITY_SET );
368371 }
369372
370- cpumask_and (mask , cpu_online_mask , set );
373+ cpumask_and (& mask , cpu_online_mask , set );
371374 if (node != NUMA_NO_NODE ) {
372375 const struct cpumask * nodemask = cpumask_of_node (node );
373376
374377 /* make sure at least one of the cpus in nodemask is online */
375- if (cpumask_intersects (mask , nodemask ))
376- cpumask_and (mask , mask , nodemask );
378+ if (cpumask_intersects (& mask , nodemask ))
379+ cpumask_and (& mask , & mask , nodemask );
377380 }
378- irq_do_set_affinity (& desc -> irq_data , mask , false);
379- return 0 ;
381+ ret = irq_do_set_affinity (& desc -> irq_data , & mask , false);
382+ raw_spin_unlock (& mask_lock );
383+ return ret ;
380384}
381385#else
382386/* Wrapper for ALPHA specific affinity selector magic */
383- static inline int setup_affinity (struct irq_desc * d , struct cpumask * mask )
387+ int irq_setup_affinity (struct irq_desc * desc )
384388{
385- return irq_select_affinity (irq_desc_get_irq (d ));
389+ return irq_select_affinity (irq_desc_get_irq (desc ));
386390}
387391#endif
388392
389393/*
390- * Called when affinity is set via /proc/irq
394+ * Called when a bogus affinity is set via /proc/irq
391395 */
392- int irq_select_affinity_usr (unsigned int irq , struct cpumask * mask )
396+ int irq_select_affinity_usr (unsigned int irq )
393397{
394398 struct irq_desc * desc = irq_to_desc (irq );
395399 unsigned long flags ;
396400 int ret ;
397401
398402 raw_spin_lock_irqsave (& desc -> lock , flags );
399- ret = setup_affinity (desc , mask );
403+ ret = irq_setup_affinity (desc );
400404 raw_spin_unlock_irqrestore (& desc -> lock , flags );
401405 return ret ;
402406}
403-
404407#else
405- static inline int
406- setup_affinity (struct irq_desc * desc , struct cpumask * mask )
408+ static inline int setup_affinity (struct irq_desc * desc )
407409{
408410 return 0 ;
409411}
@@ -1128,7 +1130,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
11281130 struct irqaction * old , * * old_ptr ;
11291131 unsigned long flags , thread_mask = 0 ;
11301132 int ret , nested , shared = 0 ;
1131- cpumask_var_t mask ;
11321133
11331134 if (!desc )
11341135 return - EINVAL ;
@@ -1187,11 +1188,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
11871188 }
11881189 }
11891190
1190- if (!alloc_cpumask_var (& mask , GFP_KERNEL )) {
1191- ret = - ENOMEM ;
1192- goto out_thread ;
1193- }
1194-
11951191 /*
11961192 * Drivers are often written to work w/o knowledge about the
11971193 * underlying irq chip implementation, so a request for a
@@ -1256,7 +1252,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
12561252 */
12571253 if (thread_mask == ~0UL ) {
12581254 ret = - EBUSY ;
1259- goto out_mask ;
1255+ goto out_unlock ;
12601256 }
12611257 /*
12621258 * The thread_mask for the action is or'ed to
@@ -1300,15 +1296,15 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
13001296 pr_err ("Threaded irq requested with handler=NULL and !ONESHOT for irq %d\n" ,
13011297 irq );
13021298 ret = - EINVAL ;
1303- goto out_mask ;
1299+ goto out_unlock ;
13041300 }
13051301
13061302 if (!shared ) {
13071303 ret = irq_request_resources (desc );
13081304 if (ret ) {
13091305 pr_err ("Failed to request resources for %s (irq %d) on irqchip %s\n" ,
13101306 new -> name , irq , desc -> irq_data .chip -> name );
1311- goto out_mask ;
1307+ goto out_unlock ;
13121308 }
13131309
13141310 init_waitqueue_head (& desc -> wait_for_threads );
@@ -1320,7 +1316,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
13201316
13211317 if (ret ) {
13221318 irq_release_resources (desc );
1323- goto out_mask ;
1319+ goto out_unlock ;
13241320 }
13251321 }
13261322
@@ -1357,7 +1353,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
13571353 }
13581354
13591355 /* Set default affinity mask once everything is setup */
1360- setup_affinity (desc , mask );
1356+ irq_setup_affinity (desc );
13611357
13621358 } else if (new -> flags & IRQF_TRIGGER_MASK ) {
13631359 unsigned int nmsk = new -> flags & IRQF_TRIGGER_MASK ;
@@ -1401,8 +1397,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
14011397 irq_add_debugfs_entry (irq , desc );
14021398 new -> dir = NULL ;
14031399 register_handler_proc (irq , new );
1404- free_cpumask_var (mask );
1405-
14061400 return 0 ;
14071401
14081402mismatch :
@@ -1415,9 +1409,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
14151409 }
14161410 ret = - EBUSY ;
14171411
1418- out_mask :
1412+ out_unlock :
14191413 raw_spin_unlock_irqrestore (& desc -> lock , flags );
1420- free_cpumask_var (mask );
14211414
14221415out_thread :
14231416 if (new -> thread ) {
0 commit comments