From: Andrew Morton <akpm@digeo.com>
To: Ravikiran G Thirumalai <kiran@in.ibm.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: [patch] Make prof_counter use per-cpu areas patch 1/4 -- x86 arch
Date: Mon, 13 Jan 2003 12:10:47 -0800 [thread overview]
Message-ID: <200301131210.47318.akpm@digeo.com> (raw)
In-Reply-To: <20030113122835.GC2714@in.ibm.com>
On Monday 13 January 2003 04:28 am, Ravikiran G Thirumalai wrote:
>
> Hi,
> Here's a patchset to make prof_counter use percpu area infrastructure.
> ...
> /* initialize the CPU structures (moved from smp_boot_cpus) */
> for(i=0; i<NR_CPUS; i++) {
> - prof_counter[i] = 1;
> + per_cpu(prof_counter, i) = 1;
Please always use the cpu_online() test here.
Yes, it's a bit awkward and yes, we should have a for_each_online_cpu()
helper, but that didn't happen.
The reason (apart from increased efficiency) is that at some time we may
make the per-cpu data areas only exist on online CPUs. We allocate the
area from the CPU's node-local memory when it is coming online.
Code such as the above will oops with that change in place.
We did have all of this running, but I never submitted the patch for reasons
of general scariness and lack of expressed interest from NUMA people.
<dig, dig>
Here it is:
The current per-cpu memory areas are allocated at startup for NR_CPUS,
so we're really not saving much memory from them.
This is a problem for kernel/timer.c (128 kbytes), kernel/sched.c (78
kbytes) and presumably other places.
The patch from Rutsy allocates per-cpu areas only for those CPUs which
may actually exist, before each one comes online.
So the per-cpu storage for not-possible CPUs does not exist, and
accessing them will oops.
init/main.c | 40 ++++++++++++++++++++++++++++------------
1 files changed, 28 insertions(+), 12 deletions(-)
--- 2.5.43/init/main.c~per-cpu-allocation Fri Oct 18 01:19:56 2002
+++ 2.5.43-akpm/init/main.c Fri Oct 18 01:22:32 2002
@@ -304,32 +304,39 @@ static void __init smp_init(void)
#define smp_init() do { } while (0)
#endif
-static inline void setup_per_cpu_areas(void) { }
+static inline void setup_per_cpu_area(unsigned int cpu) { }
static inline void smp_prepare_cpus(unsigned int maxcpus) { }
#else
#ifdef __GENERIC_PER_CPU
+/* Created by linker magic */
+extern char __per_cpu_start[], __per_cpu_end[];
+
unsigned long __per_cpu_offset[NR_CPUS];
-static void __init setup_per_cpu_areas(void)
+/* Sets up per-cpu area for boot CPU. */
+static void __init setup_per_cpu_area(unsigned int cpu)
{
- unsigned long size, i;
+ unsigned long size;
char *ptr;
- /* Created by linker magic */
- extern char __per_cpu_start[], __per_cpu_end[];
/* Copy section for each CPU (we discard the original) */
size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
if (!size)
return;
- ptr = alloc_bootmem(size * NR_CPUS);
+ /* First CPU happens really early... */
+ if (cpu == smp_processor_id())
+ ptr = alloc_bootmem(size);
+ else
+ ptr = kmalloc(size, GFP_ATOMIC);
- for (i = 0; i < NR_CPUS; i++, ptr += size) {
- __per_cpu_offset[i] = ptr - __per_cpu_start;
- memcpy(ptr, __per_cpu_start, size);
- }
+ if (ptr == NULL)
+ panic("failed to allocate per-cpu area for cpu %d\n", cpu);
+
+ __per_cpu_offset[cpu] = ptr - __per_cpu_start;
+ memcpy(ptr, __per_cpu_start, size);
}
#endif /* !__GENERIC_PER_CPU */
@@ -338,7 +345,16 @@ static void __init smp_init(void)
{
unsigned int i;
- /* FIXME: This should be done in userspace --RR */
+ for (i = 0; i < NR_CPUS; i++) {
+ if (cpu_possible(i)) {
+ if (i != smp_processor_id())
+ setup_per_cpu_area(i);
+ } else {
+ /* Force a NULL deref on use */
+ __per_cpu_offset[i] = (char *)0 - __per_cpu_start;
+ }
+ }
+
for (i = 0; i < NR_CPUS; i++) {
if (num_online_cpus() >= max_cpus)
break;
@@ -390,7 +406,7 @@ asmlinkage void __init start_kernel(void
lock_kernel();
printk(linux_banner);
setup_arch(&command_line);
- setup_per_cpu_areas();
+ setup_per_cpu_area(smp_processor_id());
build_all_zonelists();
printk("Kernel command line: %s\n", saved_command_line);
parse_options(command_line);
.
next prev parent reply other threads:[~2003-01-13 20:01 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-01-13 12:28 [patch] Make prof_counter use per-cpu areas patch 1/4 -- x86 arch Ravikiran G Thirumalai
2003-01-13 12:33 ` [patch] Make prof_counter use per-cpu areas patch 2/4 -- ppc arch Ravikiran G Thirumalai
2003-01-14 2:21 ` Paul Mackerras
2003-01-13 12:36 ` [patch] Make prof_counter use per-cpu areas patch 3/4 -- x86_64 arch Ravikiran G Thirumalai
[not found] ` <20030113152110.GA19931@wotan.suse.de>
2003-01-16 12:17 ` Ravikiran G Thirumalai
2003-01-13 12:38 ` [patch] Make prof_counter use per-cpu areas patch 4/4 -- sparc arch Ravikiran G Thirumalai
2003-01-13 16:49 ` Pete Zaitcev
2003-01-14 11:46 ` David S. Miller
2003-01-13 20:10 ` Andrew Morton [this message]
2003-01-16 12:06 ` [patch] Make prof_counter use per-cpu areas patch 1/4 -- x86 arch Ravikiran G Thirumalai
2003-01-16 20:18 ` Andrew Morton
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=200301131210.47318.akpm@digeo.com \
--to=akpm@digeo.com \
--cc=kiran@in.ibm.com \
--cc=linux-kernel@vger.kernel.org \
/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