* [PATCH 0/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures
@ 2011-06-27 11:12 Wolfgang BETZ
2011-06-27 11:12 ` [PATCH 1/1] " Wolfgang BETZ
0 siblings, 1 reply; 6+ messages in thread
From: Wolfgang BETZ @ 2011-06-27 11:12 UTC (permalink / raw)
To: linux-arm-kernel
From: Wolfgang Betz <wolfgang.betz@st.com>
The Context ID Register, CONTEXTIDR, identifies the current:
- Process Identifier (PROCID) &
- Address Space Identifier (ASID).
The value of the whole of this register is called the Context ID and is
used by:
- the ARM debug logic, for Linked and Unlinked Context ID matching
(e.g. for breakpoint debug and watchpoint debug events).
- the trace logic, to identify the current process.
The CONTEXTIDR is a 32-bit read/write register whose format is:
- PROCID, bits [31:8]
Process Identifier. This field should be programmed with a unique
value that identifies the current process and is used by the trace logic and
the debug logic to identify the process that is running currently.
- ASID, bits [7:0]
Address Space Identifier. This field must be programmed with the
value of the current ASID and is used by many memory management functions.
This change-set aims at:
- implementing thread tracing support based on the armv6 & v7 CONTEXTIDR
register while leaving the Linux kernel ASID functionality (semantically)
unchanged.
- focusing on compatibility with tracing tools such as Lauterbach's
TRACE32 tool.
- the avoidance of platform specific calls in generic code.
- simplicity, readability, and good performances.
- being general: i.e. the change-set applies to all armv7/v6 platforms &
is in general compilable for all (other) platforms.
The patch has been jointly developed by
Lauterbach GmbH (http://www.lauterbach.com) and
STMicroelectronics Srl (http://www.st.com/).
Main contributors are:
- Khaled Jmal <khaled.jmal@lauterbach.com>
- Rudi Dienstbeck <Rudolf.Dienstbeck@Lauterbach.com>
- Wolfgang Betz <wolfgang.betz@st.com>
Wolfgang Betz (1):
Add Thread Support for the Context ID Register of ARM v6 & v7
Architectures
arch/arm/Kconfig.debug | 14 +++++++++
arch/arm/include/asm/mmu_context.h | 52 ++++++++++++++++++++++++++++++++---
arch/arm/kernel/smp.c | 2 +-
arch/arm/mm/context.c | 41 +++++++++++++++++++++++++++-
arch/arm/mm/proc-v6.S | 1 -
arch/arm/mm/proc-v7.S | 1 -
6 files changed, 101 insertions(+), 10 deletions(-)
--
1.7.4.4
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH 1/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures 2011-06-27 11:12 [PATCH 0/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures Wolfgang BETZ @ 2011-06-27 11:12 ` Wolfgang BETZ 2011-06-27 11:37 ` Russell King - ARM Linux 0 siblings, 1 reply; 6+ messages in thread From: Wolfgang BETZ @ 2011-06-27 11:12 UTC (permalink / raw) To: linux-arm-kernel From: Wolfgang Betz <wolfgang.betz@st.com> The aim of this patch is to enable thread support in the context ID register (CONTEXTIDR) as it comes with ARM architectures v6 & v7. On ARMv6 & v7, we have the following structure in the context ID: 31 7 0 +-------------------------+-----------+ | process ID | ASID | +-------------------------+-----------+ | context ID | +-------------------------------------+ - The ASID is used to tag entries in the CPU caches and TLBs. - The context ID is used by debuggers and trace logic, and should be unique within all running processes. Currently the Linux kernel does correctly support the ASID field of the register, but does not make use of the process ID in a way that would allow trace logic to efficiently identify context switches. In order to achieve this, this patch modifies 6 files of the kernel as described hereafter: - First a new configuration variable THREAD_CONTEXTID has been introduced in file "arch/arm/Kconfig.debug", which basically enables the patch (if not enabled, the kernel behaves as if it would not have been modified at all). This configuration variable depends obviously on the presence of a context ID register and automatically selects TRACING as the patch is partially based on tracepoints. Furthermore it enables both DEBUG_KERNEL and DEBUG_INFO as it is supposed that a backend tool which will analyze the generated trace will require access to debugging information like e.g. the debug symbols of the kernel and modules. - The major part of the modifications of this patch are concentrated in file "arch/arm/include/asm/mmu_context.h", where a new function, i.e. "calc_context_id", has been introduced. The objective of this function is to calculate the contents of the context ID register (CONTEXTIDR), as described above, which should be moved into this register on the next context switch. Furthermore, there is a new convenience function, i.e. "set_context_id", which allows to set the CONTEXTIDR based on the outcome of a call to "calc_context_id". Finally, function "switch_mm" has been modified similarly by replacing the second argument in the call to "cpu_switch_mm" with the outcome of a call to "calc_context_id". The very same modification was necessary also in function "secondary_start_kernel" of file "arch/arm/kernel/smp.c". - File "arch/arm/mm/context.c" has been modified for one thing to make use of the new convenience function "set_context_id", for another thing to register a new "sched_switch" tracepoint function to trace thread switches not already covered by "switch_mm". - Finally, functions "cpu_v6_switch_mm" and "cpu_v7_switch_mm", in files "arch/arm/mm/proc-v6.S" and "arch/arm/mm/proc-v7.S" respectively, have been modified so that these expect now the content to be moved into CONTEXTIDR to be directly passed as second argument (i.e. within "r1"). Signed-off-by: Wolfgang Betz <wolfgang.betz@st.com> --- arch/arm/Kconfig.debug | 14 +++++++++ arch/arm/include/asm/mmu_context.h | 52 ++++++++++++++++++++++++++++++++--- arch/arm/kernel/smp.c | 2 +- arch/arm/mm/context.c | 41 +++++++++++++++++++++++++++- arch/arm/mm/proc-v6.S | 1 - arch/arm/mm/proc-v7.S | 1 - 6 files changed, 101 insertions(+), 10 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 81cbe40..dba51f7 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -129,4 +129,18 @@ config DEBUG_S3C_UART The uncompressor code port configuration is now handled by CONFIG_S3C_LOWLEVEL_UART_PORT. +config THREAD_CONTEXTID + bool "Enable thread support for the Context ID Register" + depends on CPU_HAS_ASID + default n + select DEBUG_KERNEL + select DEBUG_INFO + select TRACING + help + Say Y here if you want to enable thread support for the trace logic of + tools such as Lauterbach's TRACE32 tool. + + This thread tracing support is based on the CONTEXTIDR register of + architectures like the ARM v6 or v7. + endmenu diff --git a/arch/arm/include/asm/mmu_context.h b/arch/arm/include/asm/mmu_context.h index 71605d9..3b26f71 100644 --- a/arch/arm/include/asm/mmu_context.h +++ b/arch/arm/include/asm/mmu_context.h @@ -68,8 +68,50 @@ static inline void check_context(struct mm_struct *mm) #define init_new_context(tsk,mm) (__init_new_context(tsk,mm),0) -#else +#ifdef CONFIG_THREAD_CONTEXTID +/* + * Calculate context ID for task and mm + */ +static inline struct mm_struct *calc_context_id(struct task_struct *tsk, struct mm_struct *mm) +{ + unsigned int ret; + + if (unlikely(tsk == NULL)) { + ret = (current->pid << ASID_BITS); + } else { + ret = (tsk->pid << ASID_BITS); + } + + if (unlikely(!ret)) { + ret = (0xFFFFFFFF << ASID_BITS); + } + + return (struct mm_struct *)((mm->context.id & ~ASID_MASK) | ret); +} +#else /* !CONFIG_THREAD_CONTEXTID */ +/* + * Calculate context ID for task and mm + */ +static inline struct mm_struct *calc_context_id(struct task_struct *tsk, struct mm_struct *mm) +{ + return (struct mm_struct *)(mm->context.id); +} +#endif /* !CONFIG_THREAD_CONTEXTID */ +/* + * Set context ID for task and mm + */ +static inline void set_context_id(struct task_struct *tsk, struct mm_struct *mm) +{ + unsigned int ctxid = (unsigned int)calc_context_id(tsk, mm); + + /* set the new ContextID */ + asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (ctxid)); + isb(); +} + +#else // !CONFIG_CPU_HAS_ASID + static inline void check_context(struct mm_struct *mm) { #ifdef CONFIG_MMU @@ -79,9 +121,9 @@ static inline void check_context(struct mm_struct *mm) } #define init_new_context(tsk,mm) 0 - -#endif - +#define calc_context_id(tsk,mm) (mm) +#endif // !CONFIG_CPU_HAS_ASID + #define destroy_context(mm) do { } while(0) /* @@ -123,7 +165,7 @@ switch_mm(struct mm_struct *prev, struct mm_struct *next, *crt_mm = next; #endif check_context(next); - cpu_switch_mm(next->pgd, next); + cpu_switch_mm(next->pgd, calc_context_id(tsk, next)); if (cache_is_vivt()) cpumask_clear_cpu(cpu, mm_cpumask(prev)); } diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 344e52b..a518a39 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -288,7 +288,7 @@ asmlinkage void __cpuinit secondary_start_kernel(void) atomic_inc(&mm->mm_count); current->active_mm = mm; cpumask_set_cpu(cpu, mm_cpumask(mm)); - cpu_switch_mm(mm->pgd, mm); + cpu_switch_mm(mm->pgd, calc_context_id(current, mm)); enter_lazy_tlb(mm, current); local_flush_tlb_all(); diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index b0ee9ba..a4976af 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -16,6 +16,10 @@ #include <asm/mmu_context.h> #include <asm/tlbflush.h> +#ifdef CONFIG_THREAD_CONTEXTID +#include <trace/events/sched.h> +#endif + static DEFINE_SPINLOCK(cpu_asid_lock); unsigned int cpu_last_asid = ASID_FIRST_VERSION; #ifdef CONFIG_SMP @@ -99,8 +103,7 @@ static void reset_context(void *info) set_mm_context(mm, asid); /* set the new ASID */ - asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id)); - isb(); + set_context_id(current, mm); } #else @@ -155,3 +158,37 @@ void __new_context(struct mm_struct *mm) set_mm_context(mm, asid); spin_unlock(&cpu_asid_lock); } + +#ifdef CONFIG_THREAD_CONTEXTID +/* + * Add support for threads in CONTEXTIDR by registering a + * 'sched_switch' tracepoint event function + */ +static void thrctx_sched_switch(void *ignore, struct task_struct *prev, struct task_struct *next) +{ + struct mm_struct *mm, *oldmm; + + mm = next->mm; + oldmm = prev->active_mm; + + if (!mm) { + set_context_id(next, oldmm); + } else { + if (oldmm == mm) + set_context_id(next, mm); + } +} + +__init static int init_thread_contextid(void) +{ + int ret; + + ret = register_trace_sched_switch(thrctx_sched_switch, NULL); + if (ret) + pr_info("ftrace_graph: Couldn't activate tracepoint" + " probe to kernel_sched_switch\n"); + + return ret; +} +device_initcall(init_thread_contextid); +#endif /* CONFIG_THREAD_CONTEXTID */ diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index 1d2b845..57f3574 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -93,7 +93,6 @@ ENTRY(cpu_v6_dcache_clean_area) ENTRY(cpu_v6_switch_mm) #ifdef CONFIG_MMU mov r2, #0 - ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP) ALT_UP(orr r0, r0, #TTB_FLAGS_UP) mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S index 3c38678..a51097a 100644 --- a/arch/arm/mm/proc-v7.S +++ b/arch/arm/mm/proc-v7.S @@ -102,7 +102,6 @@ ENDPROC(cpu_v7_dcache_clean_area) ENTRY(cpu_v7_switch_mm) #ifdef CONFIG_MMU mov r2, #0 - ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id ALT_SMP(orr r0, r0, #TTB_FLAGS_SMP) ALT_UP(orr r0, r0, #TTB_FLAGS_UP) #ifdef CONFIG_ARM_ERRATA_430973 -- 1.7.4.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 1/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures 2011-06-27 11:12 ` [PATCH 1/1] " Wolfgang BETZ @ 2011-06-27 11:37 ` Russell King - ARM Linux 2011-06-28 9:00 ` Will Deacon [not found] ` <4E097B58.3050301@st.com> 0 siblings, 2 replies; 6+ messages in thread From: Russell King - ARM Linux @ 2011-06-27 11:37 UTC (permalink / raw) To: linux-arm-kernel On Mon, Jun 27, 2011 at 01:12:27PM +0200, Wolfgang BETZ wrote: > The aim of this patch is to enable thread support in the context ID register > (CONTEXTIDR) as it comes with ARM architectures v6 & v7. > > On ARMv6 & v7, we have the following structure in the context ID: > > 31 7 0 > +-------------------------+-----------+ > | process ID | ASID | > +-------------------------+-----------+ > | context ID | > +-------------------------------------+ > > - The ASID is used to tag entries in the CPU caches and TLBs. > - The context ID is used by debuggers and trace logic, and > should be unique within all running processes. When I added ARMv6 and v7 support to the kernel, I purposely ignored that detail because it's silly. The issue here is that the debuggers and trace logic use both the process ID and the ASID together, and the ASID does not have a stable value for any particular process in the system. When we have used the last ASID (255), the next request for a new ASID causes the ASID generation to increment, which in turn causes all processes in the system to have their ASIDs reassigned. At that point, if you have debugging/trace hardware setup to look for a process with a particular process ID+ASID, you're no longer going to get matches for your original process. This makes the whole concept of debuggers/tracing using the context ID rather pointless especially in a multiprocessor system. How are you working around this issue? ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures 2011-06-27 11:37 ` Russell King - ARM Linux @ 2011-06-28 9:00 ` Will Deacon 2011-06-29 13:05 ` Wolfgang BETZ [not found] ` <4E097B58.3050301@st.com> 1 sibling, 1 reply; 6+ messages in thread From: Will Deacon @ 2011-06-28 9:00 UTC (permalink / raw) To: linux-arm-kernel Hi Russell, On Mon, Jun 27, 2011 at 12:37:08PM +0100, Russell King - ARM Linux wrote: > On Mon, Jun 27, 2011 at 01:12:27PM +0200, Wolfgang BETZ wrote: > > The aim of this patch is to enable thread support in the context ID register > > (CONTEXTIDR) as it comes with ARM architectures v6 & v7. > > > > On ARMv6 & v7, we have the following structure in the context ID: > > > > 31 7 0 > > +-------------------------+-----------+ > > | process ID | ASID | > > +-------------------------+-----------+ > > | context ID | > > +-------------------------------------+ > > > > - The ASID is used to tag entries in the CPU caches and TLBs. > > - The context ID is used by debuggers and trace logic, and > > should be unique within all running processes. > > When I added ARMv6 and v7 support to the kernel, I purposely ignored that > detail because it's silly. [...] > How are you working around this issue? I don't know how you could get around this with current implementations, but for Cortex-A15 w/ LPAE the ASID lives in the TTBR rather than the context ID register, so using the PID is straightforward in that case. Will ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures 2011-06-28 9:00 ` Will Deacon @ 2011-06-29 13:05 ` Wolfgang BETZ 0 siblings, 0 replies; 6+ messages in thread From: Wolfgang BETZ @ 2011-06-29 13:05 UTC (permalink / raw) To: linux-arm-kernel Ciao Will, thanks a lot for your statement regarding the ASID overflow issue. In fact, we have never even tried to resolve this issue, not only because most likely there is no perfect solution to it in current implementations (i.e. v6 & v7 architectures), but also because it was out of our scope. In STMicroelectronics we are simply customers of Lauterbach's TRACE32 tool and are very interested in getting an as precise as possible insight in what goes on in our systems when running Linux based environments, with a particular focus on SMP. Together with Lauterbach we are currently working on improving their tool with respect to SMP in general and the tracing of context switches in particular. One result of this collaboration is the patch I have submitted to the ARM kernel mailing list this Monday. Again, we do not aim in improving the handling of ASIDs, but are just caring about getting also the current process ID out of the trace logic. As the way to achieve this is not platform-specific, we thought it might be a good idea to implement it as an architectural feature and provide it through a kernel configuration variable (THREAD_CONTEXTID) for any platform supporting the CONTEXTIDR. Furthermore, we thought it would be a good thing to mainline this modification and provide it to the open-source community. I do not know if you had the time to take a closer look to our patch, but for sure your feedback would be more than welcome. Best regards, Wolfgang On 06/28/2011 11:00 AM, Will Deacon wrote: > Hi Russell, > > On Mon, Jun 27, 2011 at 12:37:08PM +0100, Russell King - ARM Linux wrote: >> On Mon, Jun 27, 2011 at 01:12:27PM +0200, Wolfgang BETZ wrote: >>> The aim of this patch is to enable thread support in the context ID register >>> (CONTEXTIDR) as it comes with ARM architectures v6& v7. >>> >>> On ARMv6& v7, we have the following structure in the context ID: >>> >>> 31 7 0 >>> +-------------------------+-----------+ >>> | process ID | ASID | >>> +-------------------------+-----------+ >>> | context ID | >>> +-------------------------------------+ >>> >>> - The ASID is used to tag entries in the CPU caches and TLBs. >>> - The context ID is used by debuggers and trace logic, and >>> should be unique within all running processes. >> When I added ARMv6 and v7 support to the kernel, I purposely ignored that >> detail because it's silly. > [...] > >> How are you working around this issue? > I don't know how you could get around this with current implementations, but > for Cortex-A15 w/ LPAE the ASID lives in the TTBR rather than the context > ID register, so using the PID is straightforward in that case. > > Will > ^ permalink raw reply [flat|nested] 6+ messages in thread
[parent not found: <4E097B58.3050301@st.com>]
* [PATCH 1/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures [not found] ` <4E097B58.3050301@st.com> @ 2011-06-28 10:29 ` Russell King - ARM Linux 0 siblings, 0 replies; 6+ messages in thread From: Russell King - ARM Linux @ 2011-06-28 10:29 UTC (permalink / raw) To: linux-arm-kernel On Tue, Jun 28, 2011 at 08:57:28AM +0200, Wolfgang BETZ wrote: > First of all, the case you are mentioning is very rarely met in embedded > systems, where we are dealing with less processes - not hundreds. > Furthermore, we are tracing seconds to minutes. So usually this is not > an issue for Lauterbach and above all their customers. They already > have several customers using this patch - without running into this > trouble. It is not about how many processes are running in total, it is about how many processes you are running _and_ how many you've started up. Each time a thread is created via fork(), or it executes a new program via execve(), a new ASID number will be assigned to the new context. So, each time a process decides to execute something as a sub-process, you will eat through two ASID numbers. This means that if your system boot has run around 120 programs, you are very close to an ASID reallocation event, and if you are tracing or debugging at that time using this facility, all your context IDs immediately become invalid. If your system does not involve executing programs after boot, then you are safe, but I suspect that is only true of a very small minority of embedded systems. > In any case - *if* we get into this, it's very simple in TRACE32 to > ignore the ASID while extracting the ContextID from the trace - the > PID should be unique anyway. Therefore we think it is more a problem > of the back-end tool which elaborates the trace. My concern is that you may be tempted to use CONTEXTIDR to control debugging activity, users will set a breakpoint and (to them) for some unknown reason their breakpoint isn't hit because the ASIDs were reallocated. To me it just feels extremely fragile, leads to surprises, and I _really_ don't like that. I've been on the customer end of fragile embedded tools, and I know full well that its these kinds of things that piss customers off and waste their time. I've spent more time debugging CPU ICE systems than debugging my programs which are supposed to be running on those CPUs - and had to because the real CPU was an OTP device. So, when presented with a patch which is inherently fragile, I'm going to say no to it given my personal frustrating experiences of fragile embedded tools. I hope that by saying no to this kind of thing I can save some other poor embedded engineer many hours of head-scratching wondering why the expensive tool they bought/hired doesn't actually work. ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-06-29 13:05 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-27 11:12 [PATCH 0/1] Add Thread Support for the Context ID Register of ARM v6 & v7 Architectures Wolfgang BETZ
2011-06-27 11:12 ` [PATCH 1/1] " Wolfgang BETZ
2011-06-27 11:37 ` Russell King - ARM Linux
2011-06-28 9:00 ` Will Deacon
2011-06-29 13:05 ` Wolfgang BETZ
[not found] ` <4E097B58.3050301@st.com>
2011-06-28 10:29 ` Russell King - ARM Linux
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).