public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Fitzhardinge <jeremy@goop.org>
To: linux-kernel@vger.kernel.org
Cc: Chuck Ebbert <76306.1226@compuserve.com>,
	Zachary Amsden <zach@vmware.com>,
	Jan Beulich <jbeulich@novell.com>, Andi Kleen <ak@suse.de>,
	Andrew Morton <akpm@osdl.org>
Subject: [PATCH 7/8] Implement smp_processor_id() with the PDA.
Date: Thu, 31 Aug 2006 23:47:25 -0700	[thread overview]
Message-ID: <20060901064825.813636915@goop.org> (raw)
In-Reply-To: 20060901064718.918494029@goop.org

[-- Attachment #1: i386-pda-smp_processor_id.patch --]
[-- Type: text/plain, Size: 5005 bytes --]

Use the cpu_number in the PDA to implement raw_smp_processor_id.  This
is a little simpler than using thread_info, though the cpu field in
thread_info cannot be removed since it is used for things other than
getting the current CPU in common code.

The slightly subtle part of this patch is dealing with very early uses
of smp_processor_id().  This is handled on the boot CPU by setting up
a very early PDA, which is later replaced when cpu_init() is called on
the boot CPU.  For other CPUs, it uses the thread_info cpu field until
the PDA has been set up.

This is more or less an example of using the PDA, and to give it a
proper exercising.

Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Cc: Chuck Ebbert <76306.1226@compuserve.com>
Cc: Zachary Amsden <zach@vmware.com>
Cc: Jan Beulich <jbeulich@novell.com>
Cc: Andi Kleen <ak@suse.de>

---
 arch/i386/kernel/asm-offsets.c |    2 +-
 arch/i386/kernel/cpu/common.c  |   19 +++++++++++++++++--
 include/asm-i386/smp.h         |    7 ++++++-
 init/main.c                    |    9 +++++++--
 4 files changed, 31 insertions(+), 6 deletions(-)


===================================================================
--- a/arch/i386/kernel/asm-offsets.c
+++ b/arch/i386/kernel/asm-offsets.c
@@ -52,7 +52,6 @@ void foo(void)
 	OFFSET(TI_exec_domain, thread_info, exec_domain);
 	OFFSET(TI_flags, thread_info, flags);
 	OFFSET(TI_status, thread_info, status);
-	OFFSET(TI_cpu, thread_info, cpu);
 	OFFSET(TI_preempt_count, thread_info, preempt_count);
 	OFFSET(TI_addr_limit, thread_info, addr_limit);
 	OFFSET(TI_restart_block, thread_info, restart_block);
@@ -96,4 +95,5 @@ void foo(void)
 
 	BLANK();
 	OFFSET(PDA_pcurrent, i386_pda, pcurrent);
+	OFFSET(PDA_cpu, i386_pda, cpu_number);
 }
===================================================================
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -19,6 +19,7 @@
 #include <mach_apic.h>
 #endif
 #include <asm/pda.h>
+#include <asm/smp.h>
 
 #include "cpu.h"
 
@@ -666,7 +667,7 @@ static inline void set_kernel_gs(void)
 /* Initialize the CPU's GDT and PDA */
 static __cpuinit void init_gdt(void)
 {
-	int cpu = smp_processor_id();
+	int cpu = early_smp_processor_id();
 	struct task_struct *curr = current;
 	struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);
 	__u32 stk16_off = (__u32)&per_cpu(cpu_16bit_stack, cpu);
@@ -709,6 +710,20 @@ static __cpuinit void init_gdt(void)
 
 	/* Do this once everything GDT-related has been set up. */
 	pda_init(cpu, curr);
+}
+
+/* Set up a very early PDA for the boot CPU so that smp_processor_id will work */
+void __init smp_setup_processor_id(void)
+{
+	static const __initdata struct i386_pda boot_pda;
+
+	pack_descriptor((u32 *)&cpu_gdt_table[GDT_ENTRY_PDA].a,
+			(u32 *)&cpu_gdt_table[GDT_ENTRY_PDA].b,
+			(unsigned long)&boot_pda, sizeof(struct i386_pda) - 1,
+			0x80 | DESCTYPE_S | 0x2, 0); /* present read-write data segment */
+
+	/* Set %gs for this CPU's PDA */
+	set_kernel_gs();
 }
 
 /*
@@ -719,7 +734,7 @@ static __cpuinit void init_gdt(void)
  */
 void __cpuinit cpu_init(void)
 {
-	int cpu = smp_processor_id();
+	int cpu = early_smp_processor_id();
 	struct tss_struct * t = &per_cpu(init_tss, cpu);
 	struct thread_struct *thread = &current->thread;
 
===================================================================
--- a/include/asm-i386/smp.h
+++ b/include/asm-i386/smp.h
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/threads.h>
 #include <linux/cpumask.h>
+#include <asm/pda.h>
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC
@@ -58,7 +59,10 @@ extern void cpu_uninit(void);
  * from the initial startup. We map APIC_BASE very early in page_setup(),
  * so this is correct in the x86 case.
  */
-#define raw_smp_processor_id() (current_thread_info()->cpu)
+#define raw_smp_processor_id() (read_pda(cpu_number))
+/* This is valid from the very earliest point in boot that we care
+   about. */
+#define early_smp_processor_id() (current_thread_info()->cpu)
 
 extern cpumask_t cpu_callout_map;
 extern cpumask_t cpu_callin_map;
@@ -94,6 +98,7 @@ extern unsigned int num_processors;
 #else /* CONFIG_SMP */
 
 #define safe_smp_processor_id()		0
+#define early_smp_processor_id()	0
 #define cpu_physical_id(cpu)		boot_cpu_physical_apicid
 
 #define NO_PROC_ID		0xFF		/* No processor magic marker */
===================================================================
--- a/init/main.c
+++ b/init/main.c
@@ -473,8 +473,13 @@ static void __init boot_cpu_init(void)
 	cpu_set(cpu, cpu_possible_map);
 }
 
-void __init __attribute__((weak)) smp_setup_processor_id(void)
-{
+/* Some versions of gcc seem to want to inline/eliminate the call to
+   this function, even though it is weak and could therefore be
+   replaced at link time.  Mark it noinline, and add an asm() to make
+   it harder to digest. */
+noinline void __init __attribute__((weak)) smp_setup_processor_id(void)
+{
+	asm volatile("" : : : "memory");
 }
 
 asmlinkage void __init start_kernel(void)

--


  parent reply	other threads:[~2006-09-01  6:49 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-09-01  6:47 [PATCH 0/8] Implement per-processor data areas for i386 Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 1/8] Use asm-offsets for the offsets of registers into the pt_regs struct, rather than having hard-coded constants Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 2/8] Basic definitions for i386-pda Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 3/8] Initialize the per-CPU data area Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 4/8] Use %gs as the PDA base-segment in the kernel Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 5/8] Fix places where using %gs changes the usermode ABI Jeremy Fitzhardinge
2006-09-01  6:47 ` [PATCH 6/8] Update sys_vm86 to cope with changed pt_regs and %gs usage Jeremy Fitzhardinge
2006-09-01  6:47 ` Jeremy Fitzhardinge [this message]
2006-09-01  6:47 ` [PATCH 8/8] Implement "current" with the PDA Jeremy Fitzhardinge
2006-09-01  8:16 ` [PATCH 0/8] Implement per-processor data areas for i386 Andi Kleen
2006-09-01  8:26   ` Jeremy Fitzhardinge
2006-09-01  8:30     ` Andi Kleen
2006-09-01 19:08       ` Jeremy Fitzhardinge
  -- strict thread matches above, loose matches on Subject: below --
2006-08-30 23:52 Jeremy Fitzhardinge
2006-08-30 23:52 ` [PATCH 7/8] Implement smp_processor_id() with the PDA Jeremy Fitzhardinge
2006-08-31 12:35   ` Ian Campbell
2006-08-31 16:04     ` Jeremy Fitzhardinge
2006-08-31 19:10     ` Jeremy Fitzhardinge
2006-08-31 21:34       ` Ian Campbell
2006-08-31 21:39         ` Jeremy Fitzhardinge

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=20060901064825.813636915@goop.org \
    --to=jeremy@goop.org \
    --cc=76306.1226@compuserve.com \
    --cc=ak@suse.de \
    --cc=akpm@osdl.org \
    --cc=jbeulich@novell.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=zach@vmware.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