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: Yinghai 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: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
024154cfdd
Коммит
d047f53a2e
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче