Skip to content

Commit 7b2a673

Browse files
KAGA-KOKOgregkh
authored andcommitted
genirq: Provide new interfaces for affinity hints
[ Upstream commit 65c7cde ] 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 <tglx@linutronix.de> Signed-off-by: Nitesh Narayan Lal <nitesh@redhat.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ming Lei <ming.lei@redhat.com> Link: https://lore.kernel.org/r/20210501021832.743094-1-jesse.brandeburg@intel.com Link: https://lore.kernel.org/r/20210903152430.244937-2-nitesh@redhat.com Stable-dep-of: 915470e ("i40e: fix IRQ freeing in i40e_vsi_request_irq_msix error path") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 4dbabe8 commit 7b2a673

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
@@ -309,7 +309,46 @@ extern int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask);
309309
extern int irq_can_set_affinity(unsigned int irq);
310310
extern int irq_select_affinity(unsigned int irq);
311311

312-
extern int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m);
312+
extern int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
313+
bool setaffinity);
314+
315+
/**
316+
* irq_update_affinity_hint - Update the affinity hint
317+
* @irq: Interrupt to update
318+
* @m: cpumask pointer (NULL to clear the hint)
319+
*
320+
* Updates the affinity hint, but does not change the affinity of the interrupt.
321+
*/
322+
static inline int
323+
irq_update_affinity_hint(unsigned int irq, const struct cpumask *m)
324+
{
325+
return __irq_apply_affinity_hint(irq, m, false);
326+
}
327+
328+
/**
329+
* irq_set_affinity_and_hint - Update the affinity hint and apply the provided
330+
* cpumask to the interrupt
331+
* @irq: Interrupt to update
332+
* @m: cpumask pointer (NULL to clear the hint)
333+
*
334+
* Updates the affinity hint and if @m is not NULL it applies it as the
335+
* affinity of that interrupt.
336+
*/
337+
static inline int
338+
irq_set_affinity_and_hint(unsigned int irq, const struct cpumask *m)
339+
{
340+
return __irq_apply_affinity_hint(irq, m, true);
341+
}
342+
343+
/*
344+
* Deprecated. Use irq_update_affinity_hint() or irq_set_affinity_and_hint()
345+
* instead.
346+
*/
347+
static inline int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
348+
{
349+
return irq_set_affinity_and_hint(irq, m);
350+
}
351+
313352
extern int irq_update_affinity_desc(unsigned int irq,
314353
struct irq_affinity_desc *affinity);
315354

@@ -341,6 +380,18 @@ static inline int irq_can_set_affinity(unsigned int irq)
341380

342381
static inline int irq_select_affinity(unsigned int irq) { return 0; }
343382

383+
static inline int irq_update_affinity_hint(unsigned int irq,
384+
const struct cpumask *m)
385+
{
386+
return -EINVAL;
387+
}
388+
389+
static inline int irq_set_affinity_and_hint(unsigned int irq,
390+
const struct cpumask *m)
391+
{
392+
return -EINVAL;
393+
}
394+
344395
static inline int irq_set_affinity_hint(unsigned int irq,
345396
const struct cpumask *m)
346397
{

kernel/irq/manage.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,8 @@ int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
448448
}
449449
EXPORT_SYMBOL_GPL(irq_force_affinity);
450450

451-
int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
451+
int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
452+
bool setaffinity)
452453
{
453454
unsigned long flags;
454455
struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
@@ -457,12 +458,11 @@ int irq_set_affinity_hint(unsigned int irq, const struct cpumask *m)
457458
return -EINVAL;
458459
desc->affinity_hint = m;
459460
irq_put_desc_unlock(desc, flags);
460-
/* set the initial affinity to prevent every interrupt being on CPU0 */
461-
if (m)
461+
if (m && setaffinity)
462462
__irq_set_affinity(irq, m, false);
463463
return 0;
464464
}
465-
EXPORT_SYMBOL_GPL(irq_set_affinity_hint);
465+
EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
466466

467467
static void irq_affinity_notify(struct work_struct *work)
468468
{

0 commit comments

Comments
 (0)