From: Tejun Heo <tj@kernel.org>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>,
Thomas Gleixner <tglx@linutronix.de>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: [PATCH 1/3] x86: Add 'percpu_read_stable()' interface for cacheable accesses
Date: Mon, 03 Aug 2009 14:08:48 +0900 [thread overview]
Message-ID: <4A7670E0.4030605@kernel.org> (raw)
In-Reply-To: <alpine.LFD.2.01.0908021913130.3352@localhost.localdomain>
From: Linus Tolvards <torvalds@linux-foundation.org>
This is very useful for some common things like 'get_current()' and
'get_thread_info()', which can be used multiple times in a function, and
where the result is cacheable.
tj: added comment explaining the difference between percpu_read() and
percpu_read_stable()
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Tejun Heo <tj@kernel.org>
---
Three patches queued in my pending tree.
The second patch is a possible bug I've spotted while prepping the
third one. The last one puts current_task and kernel_stack into the
same cacheline as suggested by Linus. I'll hold for a few days for
response and then push them to linux-next.
Ingo, these patches might as well go through x86 tree. If you think
that would be better, please let me know.
Thanks.
arch/x86/include/asm/current.h | 2 +-
arch/x86/include/asm/percpu.h | 22 ++++++++++++++++------
arch/x86/include/asm/thread_info.h | 2 +-
3 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index c68c361..4d447b7 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -11,7 +11,7 @@ DECLARE_PER_CPU(struct task_struct *, current_task);
static __always_inline struct task_struct *get_current(void)
{
- return percpu_read(current_task);
+ return percpu_read_stable(current_task);
}
#define current get_current()
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index a18c038..b421780 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -104,36 +104,46 @@ do { \
} \
} while (0)
-#define percpu_from_op(op, var) \
+#define percpu_from_op(op, var, constraint) \
({ \
typeof(var) ret__; \
switch (sizeof(var)) { \
case 1: \
asm(op "b "__percpu_arg(1)",%0" \
: "=q" (ret__) \
- : "m" (var)); \
+ : constraint); \
break; \
case 2: \
asm(op "w "__percpu_arg(1)",%0" \
: "=r" (ret__) \
- : "m" (var)); \
+ : constraint); \
break; \
case 4: \
asm(op "l "__percpu_arg(1)",%0" \
: "=r" (ret__) \
- : "m" (var)); \
+ : constraint); \
break; \
case 8: \
asm(op "q "__percpu_arg(1)",%0" \
: "=r" (ret__) \
- : "m" (var)); \
+ : constraint); \
break; \
default: __bad_percpu_size(); \
} \
ret__; \
})
-#define percpu_read(var) percpu_from_op("mov", per_cpu__##var)
+/*
+ * percpu_read() makes gcc load the percpu variable every time it is
+ * accessed while percpu_read_stable() allows the value to be cached.
+ * percpu_read_stable() is more efficient and can be used if its value
+ * is guaranteed to be valid across cpus. The current users include
+ * get_current() and get_thread_info() both of which are actually
+ * per-thread variables implemented as per-cpu variables and thus
+ * stable for the duration of the respective task.
+ */
+#define percpu_read(var) percpu_from_op("mov", per_cpu__##var,"m" (per_cpu__##var))
+#define percpu_read_stable(var) percpu_from_op("mov", per_cpu__##var,"p" (&per_cpu__##var))
#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val)
#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val)
#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val)
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index b078352..9fee589 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -213,7 +213,7 @@ DECLARE_PER_CPU(unsigned long, kernel_stack);
static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
- ti = (void *)(percpu_read(kernel_stack) +
+ ti = (void *)(percpu_read_stable(kernel_stack) +
KERNEL_STACK_OFFSET - THREAD_SIZE);
return ti;
}
--
1.6.0.2
next prev parent reply other threads:[~2009-08-03 5:09 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-31 18:13 [GIT PULL] Additional x86 fixes for 2.6.31-rc5 H. Peter Anvin
2009-07-31 19:45 ` Linus Torvalds
2009-07-31 19:57 ` Ingo Molnar
2009-08-01 19:28 ` Linus Torvalds
2009-08-01 19:38 ` H. Peter Anvin
2009-08-01 22:04 ` Linus Torvalds
2009-08-01 22:35 ` H. Peter Anvin
2009-08-02 1:20 ` Paul Mackerras
2009-08-02 3:52 ` H. Peter Anvin
2009-08-03 1:01 ` Tejun Heo
2009-08-03 1:14 ` Linus Torvalds
2009-08-03 1:49 ` Tejun Heo
2009-08-03 2:14 ` Linus Torvalds
2009-08-03 5:08 ` Tejun Heo [this message]
2009-08-03 5:13 ` [PATCH 1/3] x86: Add 'percpu_read_stable()' interface for cacheable accesses H. Peter Anvin
2009-08-03 5:18 ` Tejun Heo
2009-08-03 6:04 ` Ingo Molnar
2009-08-03 6:08 ` H. Peter Anvin
2009-08-03 6:16 ` Ingo Molnar
2009-08-03 7:00 ` Ingo Molnar
2009-08-03 15:13 ` [PATCH 1/3 UPDATED] x86, percpu: " Tejun Heo
2009-08-03 5:10 ` [PATCH 2/3] x86,percpu: fix DECLARE/DEFINE_PER_CPU_PAGE_ALIGNED() Tejun Heo
2009-08-03 5:12 ` [PATCH 3/3] x86: collect hot percpu variables into one cacheline Tejun Heo
2009-08-05 7:34 ` [GIT PULL] Additional x86 fixes for 2.6.31-rc5 Tan, Wei Chong
2009-08-05 8:06 ` Ingo Molnar
2009-08-10 0:42 ` Tan, Wei Chong
2009-08-10 9:05 ` Ingo Molnar
2009-08-10 15:32 ` Linus Torvalds
2009-08-10 9:06 ` [tip:x86/urgent] x86: Fix serialization in pit_expect_msb() tip-bot for Linus Torvalds
2009-08-10 18:01 ` tip-bot for Linus Torvalds
2009-08-05 23:10 ` [GIT PULL] Additional x86 fixes for 2.6.31-rc5 Tan, Wei Chong
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=4A7670E0.4030605@kernel.org \
--to=tj@kernel.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.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