From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751474AbdIAFCe (ORCPT ); Fri, 1 Sep 2017 01:02:34 -0400 Received: from mga07.intel.com ([134.134.136.100]:34079 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751346AbdIAFCc (ORCPT ); Fri, 1 Sep 2017 01:02:32 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,456,1498546800"; d="scan'208";a="1190452940" From: Chen Yu To: x86@kernel.org Cc: Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Rui Zhang , linux-kernel@vger.kernel.org, Chen Yu , "Rafael J. Wysocki" , Len Brown , Dan Williams Subject: [PATCH 3/4] x86/apic: Introduce the per vector cpumask array Date: Fri, 1 Sep 2017 13:04:31 +0800 Message-Id: <4245998740e38fc167014d9735520cfdf9c18732.1504235838.git.yu.c.chen@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org This array is a bitmap for sorting the number of vectors assigned on each CPU, thus to quickly retrieve the CPU which have assigned the least amount of vectors, then choose that CPU as a hint to spread the vectors among multiple CPUs. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Dan Williams Signed-off-by: Chen Yu --- arch/x86/kernel/apic/vector.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c index 4ff84c0..b60cc66 100644 --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -32,6 +32,16 @@ struct irq_domain *x86_vector_domain; EXPORT_SYMBOL_GPL(x86_vector_domain); static DEFINE_RAW_SPINLOCK(vector_lock); static cpumask_var_t vector_cpumask, vector_searchmask, searched_cpumask; +/* + * vectors_alloc_mask[i] records the CPUs which have assigned i vectors each. + * For example, let vectors_alloc_mask[3] = cpumask_or(cpumask_of(8), cpumask_of(9)) + * which means that: + * On CPU8 and CPU9, the number of vectors been assigned is 3. + * This bitmap can be used to quickly find out the CPUs who has allocated the least + * number of vectors, by checking from vectors_alloc_mask[0] to vectors_alloc_mask[255] + * until a non-zero value is found. These CPUs are chosen for vector spreading. + */ +static cpumask_var_t vectors_alloc_mask[NR_VECTORS]; static struct irq_chip lapic_controller; #ifdef CONFIG_X86_IO_APIC static struct apic_chip_data *legacy_irq_data[NR_IRQS_LEGACY]; @@ -65,6 +75,9 @@ static void update_vectors_alloc(const struct cpumask *mask, per_cpu(vector_irq, cpu).alloc -= count; else continue; + /* Update the position for this CPU. */ + cpumask_clear_cpu(cpu, vectors_alloc_mask[cur_alloc]); + cpumask_set_cpu(cpu, vectors_alloc_mask[per_cpu(vector_irq, cpu).alloc]); } } @@ -479,6 +492,25 @@ static void __init init_legacy_irqs(void) static inline void init_legacy_irqs(void) { } #endif +static int __init alloc_assigned_vectors_mask(void) +{ + int i, ret; + + for (i = 0; i < NR_VECTORS; i++) { + ret = alloc_cpumask_var(&vectors_alloc_mask[i], GFP_KERNEL); + if (!ret) + goto free_mask; + } + /* Initially all the CPUs have 0 vector assigned. */ + cpumask_setall(vectors_alloc_mask[0]); + return 0; + + free_mask: + while (i--) + free_cpumask_var(vectors_alloc_mask[i]); + return -ENOMEM; +} + int __init arch_early_irq_init(void) { struct fwnode_handle *fn; @@ -499,6 +531,7 @@ int __init arch_early_irq_init(void) BUG_ON(!alloc_cpumask_var(&vector_cpumask, GFP_KERNEL)); BUG_ON(!alloc_cpumask_var(&vector_searchmask, GFP_KERNEL)); BUG_ON(!alloc_cpumask_var(&searched_cpumask, GFP_KERNEL)); + BUG_ON(alloc_assigned_vectors_mask()); return arch_early_ioapic_init(); } -- 2.7.4