Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d047f53a authored by Yinghai Lu's avatar Yinghai Lu Committed by Ingo Molnar
Browse files

x86/irq: change MSI irq_desc to be more numa aware



Try to get irq_desc on the home node in create_irq_nr().

v2: don't check if we can move it when sparse_irq is not used
v3: use move_irq_des, if that node is not what we want

[ Impact: optimization, make MSI IRQ descriptors more NUMA aware ]

Signed-off-by: default avatarYinghai Lu <yinghai@kernel.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: Rusty Russell <rusty@rustcorp.com.au>
LKML-Reference: <49F6559F.7070005@kernel.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent 024154cf
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -3172,14 +3172,13 @@ static int nr_irqs_gsi = NR_IRQS_LEGACY;
/*
 * Dynamic irq allocate and deallocation
 */
unsigned int create_irq_nr(unsigned int irq_want)
unsigned int create_irq_nr(unsigned int irq_want, int node)
{
	/* Allocate an unused irq */
	unsigned int irq;
	unsigned int new;
	unsigned long flags;
	struct irq_cfg *cfg_new = NULL;
	int node = cpu_to_node(boot_cpu_id);
	struct irq_desc *desc_new = NULL;

	irq = 0;
@@ -3197,6 +3196,13 @@ unsigned int create_irq_nr(unsigned int irq_want)

		if (cfg_new->vector != 0)
			continue;

#ifdef CONFIG_NUMA_IRQ_DESC
		/* different node ?*/
		if (desc_new->node != node)
			desc = move_irq_desc(desc, node);
#endif

		if (__assign_irq_vector(new, cfg_new, apic->target_cpus()) == 0)
			irq = new;
		break;
@@ -3214,11 +3220,12 @@ unsigned int create_irq_nr(unsigned int irq_want)

int create_irq(void)
{
	int node = cpu_to_node(boot_cpu_id);
	unsigned int irq_want;
	int irq;

	irq_want = nr_irqs_gsi;
	irq = create_irq_nr(irq_want);
	irq = create_irq_nr(irq_want, node);

	if (irq == 0)
		irq = -1;
@@ -3476,15 +3483,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
	unsigned int irq_want;
	struct intel_iommu *iommu = NULL;
	int index = 0;
	int node;

	/* x86 doesn't support multiple MSI yet */
	if (type == PCI_CAP_ID_MSI && nvec > 1)
		return 1;

	node = dev_to_node(&dev->dev);
	irq_want = nr_irqs_gsi;
	sub_handle = 0;
	list_for_each_entry(msidesc, &dev->msi_list, list) {
		irq = create_irq_nr(irq_want);
		irq = create_irq_nr(irq_want, node);
		if (irq == 0)
			return -1;
		irq_want = irq + 1;
+1 −1
Original line number Diff line number Diff line
@@ -376,7 +376,7 @@ extern void set_irq_noprobe(unsigned int irq);
extern void set_irq_probe(unsigned int irq);

/* Handle dynamic irq creation and destruction */
extern unsigned int create_irq_nr(unsigned int irq_want);
extern unsigned int create_irq_nr(unsigned int irq_want, int node);
extern int create_irq(void);
extern void destroy_irq(unsigned int irq);