Skip to content

Commit 65c7cde

Browse files
committed
genirq: Provide new interfaces for affinity hints
The discussion about removing the side effect of irq_set_affinity_hint() of actually applying the cpumask (if not NULL) as affinity to the interrupt, unearthed a few unpleasantries: 1) The modular perf drivers rely on the current behaviour for the very wrong reasons. 2) While none of the other drivers prevents user space from changing the affinity, a cursorily inspection shows that there are at least expectations in some drivers. #1 needs to be cleaned up anyway, so that's not a problem #2 might result in subtle regressions especially when irqbalanced (which nowadays ignores the affinity hint) is disabled. Provide new interfaces: irq_update_affinity_hint() - Only sets the affinity hint pointer irq_set_affinity_and_hint() - Set the pointer and apply the affinity to the interrupt Make irq_set_affinity_hint() a wrapper around irq_apply_affinity_hint() and document it to be phased out. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Nitesh Narayan Lal <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Ming Lei <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected]
1 parent 4946f15 commit 65c7cde

File tree

2 files changed

+56
-5
lines changed

2 files changed

+56
-5
lines changed

include/linux/interrupt.h

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,46 @@ extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
329329
extern int irq_can_set_affinity(unsigned int irq);
330330
extern int irq_select_affinity(unsigned int irq);
331331

332-
extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
332+
extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
333+
bool setaffinity);
334+
335+
/**
336+
* irq_update_affinity_hint - Update the affinity hint
337+
* @irq: Interrupt to update
338+
* @m: cpumask pointer (NULL to clear the hint)
339+
*
340+
* Updates the affinity hint, but does not change the affinity of the interrupt.
341+
*/
342+
static inline int
343+
irq_update_affinity_hint(unsigned int irq, const struct cpumask *m)
344+
{
345+
return __irq_apply_affinity_hint(irq, m, false);
346+
}
347+
348+
/**
349+
* irq_set_affinity_and_hint - Update the affinity hint and apply the provided
350+
* cpumask to the interrupt
351+
* @irq: Interrupt to update
352+
* @m: cpumask pointer (NULL to clear the hint)
353+
*
354+
* Updates the affinity hint and if @m is not NULL it applies it as the
355+
* affinity of that interrupt.
356+
*/
357+
static inline int
358+
irq_set_affinity_and_hint(unsigned int irq, const struct cpumask *m)
359+
{
360+
return __irq_apply_affinity_hint(irq, m, true);
361+
}
362+
363+
/*
364+
* Deprecated. Use irq_update_affinity_hint() or irq_set_affinity_and_hint()
365+
* instead.
366+
*/
367+
static inline int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
368+
{
369+
return irq_set_affinity_and_hint(irq, m);
370+
}
371+
333372
extern int irq_update_affinity_desc(unsigned int irq,
334373
struct irq_affinity_desc *affinity);
335374

@@ -361,6 +400,18 @@ static inline int irq_can_set_affinity(unsigned int irq)
361400

362401
static inline int irq_select_affinity(unsigned int irq) { return 0; }
363402

403+
static inline int irq_update_affinity_hint(unsigned int irq,
404+
const struct cpumask *m)
405+
{
406+
return -EINVAL;
407+
}
408+
409+
static inline int irq_set_affinity_and_hint(unsigned int irq,
410+
const struct cpumask *m)
411+
{
412+
return -EINVAL;
413+
}
414+
364415
static inline int irq_set_affinity_hint(unsigned int irq,
365416
const struct cpumask *m)
366417
{

kernel/irq/manage.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,8 @@ int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
486486
}
487487
EXPORT_SYMBOL_GPL(irq_force_affinity);
488488

489-
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
489+
int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
490+
bool setaffinity)
490491
{
491492
unsigned long flags;
492493
struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
@@ -495,12 +496,11 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
495496
return -EINVAL;
496497
desc->affinity_hint = m;
497498
irq_put_desc_unlock(desc, flags);
498-
/* set the initial affinity to prevent every interrupt being on CPU0 */
499-
if (m)
499+
if (m && setaffinity)
500500
__irq_set_affinity(irq, m, false);
501501
return 0;
502502
}
503-
EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
503+
EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
504504

505505
static void irq_affinity_notify(struct work_struct *work)
506506
{

0 commit comments

Comments
 (0)