From: tip-bot for Andi Kleen <tipbot@zytor.com>
To: linux-tip-commits@vger.kernel.org
Cc: dave.hansen@intel.com, linux-kernel@vger.kernel.org,
mingo@kernel.org, prarit@redhat.com, vkuznets@redhat.com,
ak@linux.intel.com, kirill.shutemov@linux.intel.com,
kan.liang@intel.com, luto@kernel.org, tim.c.chen@linux.intel.com,
eranian@google.com, bp@suse.de, thomas.lendacky@amd.com,
borntraeger@de.ibm.com, he.chen@linux.intel.com,
peterz@infradead.org, arvind.yadav.cs@gmail.com,
tglx@linutronix.de, hpa@zytor.com, minipli@googlemail.com,
piotr.luc@intel.com
Subject: [tip:x86/urgent] x86/topology: Avoid wasting 128k for package id array
Date: Fri, 17 Nov 2017 07:27:28 -0800 [thread overview]
Message-ID: <tip-30bb9811856f667042e746d8033883b1091a46ce@git.kernel.org> (raw)
In-Reply-To: <20171114124257.22013-3-prarit@redhat.com>
Commit-ID: 30bb9811856f667042e746d8033883b1091a46ce
Gitweb: https://git.kernel.org/tip/30bb9811856f667042e746d8033883b1091a46ce
Author: Andi Kleen <ak@linux.intel.com>
AuthorDate: Tue, 14 Nov 2017 07:42:56 -0500
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Fri, 17 Nov 2017 16:22:30 +0100
x86/topology: Avoid wasting 128k for package id array
Analyzing large early boot allocations unveiled the logical package id
storage as a prominent memory waste. Since commit 1f12e32f4cd5
("x86/topology: Create logical package id") every 64-bit system allocates a
128k array to convert logical package ids.
This happens because the array is sized for MAX_LOCAL_APIC which is always
32k on 64bit systems, and it needs 4 bytes for each entry.
This is fairly wasteful, especially for the common case of having only one
socket, which uses exactly 4 byte out of 128K.
There is no user of the package id map which is performance critical, so
the lookup is not required to be O(1). Store the logical processor id in
cpu_data and use a loop based lookup.
To keep the mapping stable accross cpu hotplug operations, add a flag to
cpu_data which is set when the CPU is brought up the first time. When the
flag is set, then cpu_data is not reinitialized by copying boot_cpu_data on
subsequent bringups.
[ tglx: Rename the flag to 'initialized', use proper pointers instead of
repeated cpu_data(x) evaluation and massage changelog. ]
Signed-off-by: Andi Kleen <ak@linux.intel.com>
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Christian Borntraeger <borntraeger@de.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Kan Liang <kan.liang@intel.com>
Cc: He Chen <he.chen@linux.intel.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Dave Hansen <dave.hansen@intel.com>
Cc: Piotr Luc <piotr.luc@intel.com>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arvind Yadav <arvind.yadav.cs@gmail.com>
Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Tim Chen <tim.c.chen@linux.intel.com>
Cc: Mathias Krause <minipli@googlemail.com>
Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
Link: https://lkml.kernel.org/r/20171114124257.22013-3-prarit@redhat.com
---
arch/x86/include/asm/processor.h | 1 +
arch/x86/kernel/smpboot.c | 73 ++++++++++++++++------------------------
2 files changed, 30 insertions(+), 44 deletions(-)
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 2db7cf7..cc16fa8 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -132,6 +132,7 @@ struct cpuinfo_x86 {
/* Index into per_cpu list: */
u16 cpu_index;
u32 microcode;
+ unsigned initialized : 1;
} __randomize_layout;
struct cpuid_regs {
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 5f59e6b..da5e162 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -101,9 +101,6 @@ DEFINE_PER_CPU_READ_MOSTLY(struct cpuinfo_x86, cpu_info);
EXPORT_PER_CPU_SYMBOL(cpu_info);
/* Logical package management. We might want to allocate that dynamically */
-static int *physical_to_logical_pkg __read_mostly;
-static unsigned long *physical_package_map __read_mostly;;
-static unsigned int max_physical_pkg_id __read_mostly;
unsigned int __max_logical_packages __read_mostly;
EXPORT_SYMBOL(__max_logical_packages);
static unsigned int logical_packages __read_mostly;
@@ -281,23 +278,36 @@ static void notrace start_secondary(void *unused)
}
/**
+ * topology_phys_to_logical_pkg - Map a physical package id to a logical
+ *
+ * Returns logical package id or -1 if not found
+ */
+int topology_phys_to_logical_pkg(unsigned int phys_pkg)
+{
+ int cpu;
+
+ for_each_possible_cpu(cpu) {
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+ if (c->initialized && c->phys_proc_id == phys_pkg)
+ return c->logical_proc_id;
+ }
+ return -1;
+}
+EXPORT_SYMBOL(topology_phys_to_logical_pkg);
+
+/**
* topology_update_package_map - Update the physical to logical package map
* @pkg: The physical package id as retrieved via CPUID
* @cpu: The cpu for which this is updated
*/
int topology_update_package_map(unsigned int pkg, unsigned int cpu)
{
- unsigned int new;
-
- /* Called from early boot ? */
- if (!physical_package_map)
- return 0;
-
- if (pkg >= max_physical_pkg_id)
- return -EINVAL;
+ int new;
- /* Set the logical package id */
- if (test_and_set_bit(pkg, physical_package_map))
+ /* Already available somewhere? */
+ new = topology_phys_to_logical_pkg(pkg);
+ if (new >= 0)
goto found;
if (logical_packages >= __max_logical_packages) {
@@ -311,30 +321,14 @@ int topology_update_package_map(unsigned int pkg, unsigned int cpu)
pr_info("CPU %u Converting physical %u to logical package %u\n",
cpu, pkg, new);
}
- physical_to_logical_pkg[pkg] = new;
-
found:
- cpu_data(cpu).logical_proc_id = physical_to_logical_pkg[pkg];
+ cpu_data(cpu).logical_proc_id = new;
return 0;
}
-/**
- * topology_phys_to_logical_pkg - Map a physical package id to a logical
- *
- * Returns logical package id or -1 if not found
- */
-int topology_phys_to_logical_pkg(unsigned int phys_pkg)
-{
- if (phys_pkg >= max_physical_pkg_id)
- return -1;
- return physical_to_logical_pkg[phys_pkg];
-}
-EXPORT_SYMBOL(topology_phys_to_logical_pkg);
-
static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu)
{
unsigned int ncpus;
- size_t size;
/*
* Today neither Intel nor AMD support heterogenous systems. That
@@ -365,19 +359,6 @@ static void __init smp_init_package_map(struct cpuinfo_x86 *c, unsigned int cpu)
}
__max_logical_packages = DIV_ROUND_UP(total_cpus, ncpus);
- logical_packages = 0;
-
- /*
- * Possibly larger than what we need as the number of apic ids per
- * package can be smaller than the actual used apic ids.
- */
- max_physical_pkg_id = DIV_ROUND_UP(MAX_LOCAL_APIC, ncpus);
- size = max_physical_pkg_id * sizeof(unsigned int);
- physical_to_logical_pkg = kmalloc(size, GFP_KERNEL);
- memset(physical_to_logical_pkg, 0xff, size);
- size = BITS_TO_LONGS(max_physical_pkg_id) * sizeof(unsigned long);
- physical_package_map = kzalloc(size, GFP_KERNEL);
-
pr_info("Max logical packages: %u\n", __max_logical_packages);
topology_update_package_map(c->phys_proc_id, cpu);
@@ -391,6 +372,7 @@ void __init smp_store_boot_cpu_info(void)
*c = boot_cpu_data;
c->cpu_index = id;
smp_init_package_map(c, id);
+ c->initialized = true;
}
/*
@@ -401,13 +383,16 @@ void smp_store_cpu_info(int id)
{
struct cpuinfo_x86 *c = &cpu_data(id);
- *c = boot_cpu_data;
+ /* Copy boot_cpu_data only on the first bringup */
+ if (!c->initialized)
+ *c = boot_cpu_data;
c->cpu_index = id;
/*
* During boot time, CPU0 has this setup already. Save the info when
* bringing up AP or offlined CPU0.
*/
identify_secondary_cpu(c);
+ c->initialized = true;
}
static bool
next prev parent reply other threads:[~2017-11-17 15:32 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-14 12:42 [PATCH v6 0/3] Fix panic in logical packages calculation Prarit Bhargava
2017-11-14 12:42 ` [PATCH v6 1/3] perf/x86/intel/uncore: Cache logical pkg id in uncore driver Prarit Bhargava
2017-11-17 15:27 ` [tip:x86/urgent] " tip-bot for Andi Kleen
2017-11-14 12:42 ` [PATCH v6 2/3] x86/topology: Avoid wasting 128k for package id array Prarit Bhargava
2017-11-17 14:59 ` Thomas Gleixner
2017-11-17 15:27 ` tip-bot for Andi Kleen [this message]
2017-11-14 12:42 ` [PATCH v6 3/3] x86/smpboot: Fix __max_logical_packages estimate Prarit Bhargava
2017-11-17 15:27 ` [tip:x86/urgent] " tip-bot for Prarit Bhargava
2018-02-07 18:44 ` [v6,3/3] " Simon Gaiser
2018-02-07 19:04 ` Prarit Bhargava
2018-02-07 19:26 ` Simon Gaiser
2018-02-07 19:31 ` Prarit Bhargava
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-30bb9811856f667042e746d8033883b1091a46ce@git.kernel.org \
--to=tipbot@zytor.com \
--cc=ak@linux.intel.com \
--cc=arvind.yadav.cs@gmail.com \
--cc=borntraeger@de.ibm.com \
--cc=bp@suse.de \
--cc=dave.hansen@intel.com \
--cc=eranian@google.com \
--cc=he.chen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=kan.liang@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@kernel.org \
--cc=minipli@googlemail.com \
--cc=peterz@infradead.org \
--cc=piotr.luc@intel.com \
--cc=prarit@redhat.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=tim.c.chen@linux.intel.com \
--cc=vkuznets@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome