diff options
author | Paul Rosenfeld <prosenfeld@micron.com> | 2017-04-04 09:06:38 -0600 |
---|---|---|
committer | Paul Rosenfeld <prosenfeld@micron.com> | 2017-06-22 13:32:04 +0000 |
commit | 1d7ff84f126e5e1b138c7250a275ebe3a46fa27c (patch) | |
tree | 629f6fb5b21b3f8603cdb32477108547d90881c3 /src/arch/generic | |
parent | 9cdfcf93470ca11c12eeac50aea9536ef914790f (diff) | |
download | gem5-1d7ff84f126e5e1b138c7250a275ebe3a46fa27c.tar.xz |
arm,sim: fix context switch stats dumps for ARM64/Linux
32bit and 64bit Linux have different arguments passed to the
__switch_to() function that gem5 hooks into in order to collect context
switch statistics. 64bit Linux provides the task_struct pointer to the
next task that will be switched to, which means we don't have to look
up the task_struct from thread_info as we do in 32bit ARM Linux.
This patch adds a second set of accessors to ThreadInfo to extract
details such as the pid, tgid, task name, etc., directly from a
task_struct. The existing accessors maintain their existing behavior by
first looking up the task_struct and then calling these new accessors.
A 64-bit variant of the DumpStatsPCEvent class is added that uses these
new accessors to get the task details for the context switch dumps
directly from the task_struct passed to __switch_to().
Change-Id: I63c4b3e1ad64446751a91f6340901d5180d7382d
Reviewed-on: https://gem5-review.googlesource.com/2640
Reviewed-by: Curtis Dunham <curtis.dunham@arm.com>
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Pau Cabre <pau.cabre@metempsy.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src/arch/generic')
-rw-r--r-- | src/arch/generic/linux/threadinfo.hh | 54 |
1 files changed, 43 insertions, 11 deletions
diff --git a/src/arch/generic/linux/threadinfo.hh b/src/arch/generic/linux/threadinfo.hh index 6a5d031fa..89db36a30 100644 --- a/src/arch/generic/linux/threadinfo.hh +++ b/src/arch/generic/linux/threadinfo.hh @@ -95,6 +95,9 @@ class ThreadInfo inline Addr curTaskInfo(Addr thread_info = 0) { + // Note that in Linux 4.10 the thread_info struct will no longer have a + // pointer to the task_struct for arm64. See: + // https://patchwork.kernel.org/patch/9333699/ int32_t offset; if (!get_data("thread_info_task", offset)) return 0; @@ -109,33 +112,44 @@ class ThreadInfo } int32_t - curTaskPID(Addr thread_info = 0) - { + curTaskPIDFromTaskStruct(Addr task_struct) { int32_t offset; if (!get_data("task_struct_pid", offset)) return -1; int32_t pid; - CopyOut(tc, &pid, curTaskInfo(thread_info) + offset, sizeof(pid)); + CopyOut(tc, &pid, task_struct + offset, sizeof(pid)); return pid; } int32_t - curTaskTGID(Addr thread_info = 0) + curTaskPID(Addr thread_info = 0) + { + return curTaskPIDFromTaskStruct(curTaskInfo(thread_info)); + } + + int32_t + curTaskTGIDFromTaskStruct(Addr task_struct) { int32_t offset; if (!get_data("task_struct_tgid", offset)) return -1; int32_t tgid; - CopyOut(tc, &tgid, curTaskInfo(thread_info) + offset, sizeof(tgid)); + CopyOut(tc, &tgid, task_struct + offset, sizeof(tgid)); return tgid; } + int32_t + curTaskTGID(Addr thread_info = 0) + { + return curTaskTGIDFromTaskStruct(curTaskInfo(thread_info)); + } + int64_t - curTaskStart(Addr thread_info = 0) + curTaskStartFromTaskStruct(Addr task_struct) { int32_t offset; if (!get_data("task_struct_start_time", offset)) @@ -144,13 +158,19 @@ class ThreadInfo int64_t data; // start_time is actually of type timespec, but if we just // grab the first long, we'll get the seconds out of it - CopyOut(tc, &data, curTaskInfo(thread_info) + offset, sizeof(data)); + CopyOut(tc, &data, task_struct + offset, sizeof(data)); return data; } + int64_t + curTaskStart(Addr thread_info = 0) + { + return curTaskStartFromTaskStruct(curTaskInfo(thread_info)); + } + std::string - curTaskName(Addr thread_info = 0) + curTaskNameFromTaskStruct(Addr task_struct) { int32_t offset; int32_t size; @@ -162,23 +182,35 @@ class ThreadInfo return "FailureIn_curTaskName"; char buffer[size + 1]; - CopyStringOut(tc, buffer, curTaskInfo(thread_info) + offset, size); + CopyStringOut(tc, buffer, task_struct + offset, size); return buffer; } + std::string + curTaskName(Addr thread_info = 0) + { + return curTaskNameFromTaskStruct(curTaskInfo(thread_info)); + } + int32_t - curTaskMm(Addr thread_info = 0) + curTaskMmFromTaskStruct(Addr task_struct) { int32_t offset; if (!get_data("task_struct_mm", offset)) return -1; int32_t mm_ptr; - CopyOut(tc, &mm_ptr, curTaskInfo(thread_info) + offset, sizeof(mm_ptr)); + CopyOut(tc, &mm_ptr, task_struct + offset, sizeof(mm_ptr)); return mm_ptr; } + + int32_t + curTaskMm(Addr thread_info = 0) + { + return curTaskMmFromTaskStruct(curTaskInfo(thread_info)); + } }; } // namespace Linux |