From 9d4ee7acaa930811bbb8e28894a96fd371702ef4 Mon Sep 17 00:00:00 2001 From: Ali Saidi Date: Wed, 18 Aug 2004 23:06:51 -0400 Subject: [PATCH] Added code using VPtr to be able to extract info from linux thread structures. Added event to print out currently running task base/traceflags.py: Added Thread trace flag kern/linux/linux_system.cc: kern/linux/linux_system.hh: Added event to print out currently running task --HG-- extra : convert_revision : 94347dbaf90f39eb40467b2a43b4628a3deafc6c --- base/traceflags.py | 3 +- kern/linux/aligned.hh | 21 +++++++ kern/linux/hwrpb.hh | 18 ++++++ kern/linux/linux_system.cc | 6 ++ kern/linux/linux_system.hh | 3 + kern/linux/linux_threadinfo.hh | 91 +++++++++++++++++++++++++++ kern/linux/sched.hh | 110 +++++++++++++++++++++++++++++++++ kern/linux/thread_info.hh | 27 ++++++++ 8 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 kern/linux/aligned.hh create mode 100644 kern/linux/hwrpb.hh create mode 100644 kern/linux/linux_threadinfo.hh create mode 100644 kern/linux/sched.hh create mode 100644 kern/linux/thread_info.hh diff --git a/base/traceflags.py b/base/traceflags.py index 4be61d7ee..8f20a9692 100644 --- a/base/traceflags.py +++ b/base/traceflags.py @@ -122,7 +122,8 @@ baseFlags = [ 'Tsunami', 'Uart', 'Split', - 'SQL' + 'SQL', + 'Thread' ] # diff --git a/kern/linux/aligned.hh b/kern/linux/aligned.hh new file mode 100644 index 000000000..55035c6e4 --- /dev/null +++ b/kern/linux/aligned.hh @@ -0,0 +1,21 @@ +#ifndef __ALIGNED_HH__ +#define __ALIGNED_HH__ + +#include +#include "targetarch/isa_traits.hh" + +/* GCC 3.3.X has a bug in which attributes+typedefs don't work. 3.2.X is fine + * as in 3.4.X, but the bug is marked will not fix in 3.3.X so here is + * the work around. + */ +#if __GNUC__ == 3 && __GNUC_MINOR__ != 3 +typedef uint64_t uint64_ta __attribute__ ((aligned (8))) ; +typedef int64_t int64_ta __attribute__ ((aligned (8))) ; +typedef Addr Addr_a __attribute__ ((aligned (8))) ; +#else +#define uint64_ta uint64_t __attribute__ ((aligned (8))) +#define int64_ta int64_t __attribute__ ((aligned (8))) +#define Addr_a Addr __attribute__ ((aligned (8))) +#endif /* __GNUC__ __GNUC_MINOR__ */ + +#endif /* __ALIGNED_H__ */ diff --git a/kern/linux/hwrpb.hh b/kern/linux/hwrpb.hh new file mode 100644 index 000000000..3ce03efd7 --- /dev/null +++ b/kern/linux/hwrpb.hh @@ -0,0 +1,18 @@ +#ifndef __ALPHA_HWRPB_H__ +#define __ALPHA_HWRPB_H__ + +#include "kern/linux/aligned.hh" + +namespace Linux { + struct pcb_struct { + uint64_ta ksp; + uint64_ta usp; + uint64_ta ptbr; + uint32_t pcc; + uint32_t asn; + uint64_ta unique; + uint64_ta flags; + uint64_ta res1, res2; + }; +} +#endif /* __ALPHA_HWRPB_H */ diff --git a/kern/linux/linux_system.cc b/kern/linux/linux_system.cc index bc2753908..dd188ffe0 100644 --- a/kern/linux/linux_system.cc +++ b/kern/linux/linux_system.cc @@ -132,6 +132,8 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, debugPrintkEvent = new DebugPrintkEvent(&pcEventQueue, "dprintk"); + printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo"); + Addr addr = 0; /** @@ -242,6 +244,10 @@ LinuxSystem::LinuxSystem(const string _name, const uint64_t _init_param, if (kernelSymtab->findAddress("dprintk", addr)) debugPrintkEvent->schedule(addr+sizeof(MachInst)*2); + + if (kernelSymtab->findAddress("alpha_switch_to", addr) && + DTRACE(Thread)) + printThreadEvent->schedule(addr+sizeof(MachInst)*6); } LinuxSystem::~LinuxSystem() diff --git a/kern/linux/linux_system.hh b/kern/linux/linux_system.hh index e7cdf140d..fbfcb788f 100644 --- a/kern/linux/linux_system.hh +++ b/kern/linux/linux_system.hh @@ -52,6 +52,7 @@ class LinuxSkipDelayLoopEvent; class SkipFuncEvent; class FnEvent; class AlphaArguments; +class PrintThreadInfo; /** * This class contains linux specific system code (Loading, Events, Binning). @@ -95,6 +96,8 @@ class LinuxSystem : public System */ LinuxSkipDelayLoopEvent *skipDelayLoopEvent; + PrintThreadInfo *printThreadEvent; + /** Begining of kernel code */ Addr kernelStart; diff --git a/kern/linux/linux_threadinfo.hh b/kern/linux/linux_threadinfo.hh new file mode 100644 index 000000000..83a746059 --- /dev/null +++ b/kern/linux/linux_threadinfo.hh @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2004 The Regents of The University of Michigan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __LINUX_TREADNIFO_HH__ +#define __LINUX_TREADNIFO_HH__ + + +#include "targetarch/isa_traits.hh" +#include "targetarch/vptr.hh" +#include "cpu/exec_context.hh" +#include "kern/linux/thread_info.hh" +#include "kern/linux/sched.hh" + + +namespace Linux { + +class ThreadInfo +{ + private: + ExecContext *xc; + + public: + ThreadInfo(ExecContext *exec) : xc(exec) {} + ~ThreadInfo() {} + + inline VPtr + curThreadInfo() + { + Addr current; + + /* Each kernel stack is only 2 pages, the start of which is the + * thread_info struct. So we can get the address by masking off + * the lower 14 bits. + */ + current = xc->regs.intRegFile[StackPointerReg] & ~0x3fff; + return VPtr(xc, current); + } + + inline VPtr + curTaskInfo() + { + Addr task = curThreadInfo()->task; + return VPtr(xc, task); + } + + string + curTaskName() + { + return curTaskInfo()->comm; + } + + int32_t + curTaskPID() + { + return curTaskInfo()->pid; + } + + uint64_t + curTaskStart() + { + return curTaskInfo()->start_time; + } +}; +} + +#endif /* __LINUX_THREADINFO_HH__ */ diff --git a/kern/linux/sched.hh b/kern/linux/sched.hh new file mode 100644 index 000000000..287214b2b --- /dev/null +++ b/kern/linux/sched.hh @@ -0,0 +1,110 @@ +#ifndef __LINUX_SCHED_H__ +#define __LINUX_SCHED_H__ + +#include "targetarch/isa_traits.hh" +#include "kern/linux/atomic.hh" +#include "kern/linux/list.hh" +#include "kern/linux/wait.hh" +#include "kern/linux/timer.hh" +#include "kern/linux/pid.hh" +#include "kern/linux/aligned.hh" + +namespace Linux { + + struct rlimit { + uint64_ta rlim_cur; + uint64_ta rlim_max; + }; + + const uint32_t RLIM_NLIMITS = 11; + + struct task_struct { + int64_ta state; /* -1 unrunnable, 0 runnable, >0 stopped */ + Addr_a thread_info; + atomic_t usage; + + uint64_ta flags; /* per process flags, defined below */ + uint64_ta ptrace; + + int32_t lock_depth; /* Lock depth */ + + int32_t prio, static_prio; + + struct list_head run_list; + Addr_a array; + + uint64_ta sleep_avg; + int64_ta interactive_credit; + uint64_ta timestamp; + int32_t activated; + + uint64_ta policy; + uint64_ta cpus_allowed; + uint32_t time_slice, first_time_slice; + + struct list_head tasks; + struct list_head ptrace_children; + struct list_head ptrace_list; + + Addr_a mm, active_mm; + + /* task state */ + Addr_a binfmt; + int32_t exit_code, exit_signal; + int32_t pdeath_signal; /* The signal sent when the parent dies */ + /* ??? */ + uint64_ta personality; + int32_t did_exec:1; + int32_t pid; + int32_t __pgrp; /* Accessed via process_group() */ + int32_t tty_old_pgrp; + int32_t session; + int32_t tgid; + /* boolean value for session group leader */ + int32_t leader; + /* + * pointers to (original) parent process, youngest child, younger sibling, + * older sibling, respectively. (p->father can be replaced with + * p->parent->pid) + */ + Addr_a real_parent; /* real parent process (when being debugged) */ + Addr_a parent; /* parent process */ + struct list_head children; /* list of my children */ + struct list_head sibling; /* linkage in my parent's children list */ + Addr_a group_leader; /* threadgroup leader */ + + /* PID/PID hash table linkage. */ + struct pid_link pids[PIDTYPE_MAX]; + + wait_queue_head_t wait_chldexit; /* for wait4() */ + Addr_a vfork_done; /* for vfork() */ + Addr_a set_child_tid; /* CLONE_CHILD_SETTID */ + Addr_a clear_child_tid; /* CLONE_CHILD_CLEARTID */ + + uint64_ta rt_priority; + uint64_ta it_real_value, it_prof_value, it_virt_value; + uint64_ta it_real_incr, it_prof_incr, it_virt_incr; + struct timer_list real_timer; + struct list_head posix_timers; /* POSIX.1b Interval Timers */ + uint64_ta utime, stime, cutime, cstime; + uint64_ta nvcsw, nivcsw, cnvcsw, cnivcsw; /* context switch counts */ + uint64_ta start_time; + /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */ + uint64_ta min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap; + /* process credentials */ + uint32_t uid,euid,suid,fsuid; + uint32_t gid,egid,sgid,fsgid; + Addr_a group_info; + uint32_t cap_effective, cap_inheritable, cap_permitted; + int32_t keep_capabilities:1; + Addr user; + /* limits */ + struct rlimit rlim[RLIM_NLIMITS]; + uint16_t used_math; + char comm[16]; + }; + + +} + +#endif diff --git a/kern/linux/thread_info.hh b/kern/linux/thread_info.hh new file mode 100644 index 000000000..1b4053a78 --- /dev/null +++ b/kern/linux/thread_info.hh @@ -0,0 +1,27 @@ +#ifndef __ALPHA_THREAD_INFO_H__ +#define __ALPHA_THREAD_INFO_H__ + +#include "kern/linux/hwrpb.hh" +#include "kern/linux/aligned.hh" + +namespace Linux { + struct thread_info { + struct pcb_struct pcb; /* palcode state */ + + Addr_a task; /* main task structure */ + uint32_t flags; /* low level flags */ + uint32_t ieee_state; /* see fpu.h */ + + Addr_a exec_domain; /* execution domain */ + uint64_ta addr_limit; /* thread address space */ + int64_ta cpu; /* current CPU */ + int32_t preempt_count; /* 0 => preemptable, <0 => BUG */ + + int32_t bpt_nsaved; + uint64_ta bpt_addr[2]; /* breakpoint handling */ + uint32_t bpt_insn[2]; + + /*restart_block;*/ + }; +} +#endif /* __ALPHA_THREAD_INFO_H__ */