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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.