summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript4
-rw-r--r--arch/alpha/isa_traits.hh2
-rw-r--r--arch/alpha/stacktrace.cc324
-rw-r--r--arch/alpha/stacktrace.hh99
-rwxr-xr-xarch/isa_parser.py17
-rw-r--r--base/traceflags.py3
-rw-r--r--cpu/base.cc42
-rw-r--r--cpu/base.hh17
-rw-r--r--cpu/exec_context.cc38
-rw-r--r--cpu/exec_context.hh9
-rw-r--r--cpu/profile.cc147
-rw-r--r--cpu/profile.hh74
-rw-r--r--cpu/simple/cpu.cc23
-rw-r--r--dev/ns_gige.cc117
-rw-r--r--dev/ns_gige.hh2
-rw-r--r--dev/ns_gige_reg.h4
-rw-r--r--dev/sinic.cc460
-rw-r--r--dev/sinic.hh49
-rw-r--r--dev/sinicreg.hh181
-rw-r--r--kern/kernel_stats.hh5
-rw-r--r--python/m5/objects/Ethernet.py51
-rw-r--r--sim/system.cc16
-rw-r--r--sim/system.hh3
-rw-r--r--test/Makefile4
-rw-r--r--test/nmtest.cc60
-rwxr-xr-xutil/pbs/job.py2
-rwxr-xr-xutil/pbs/pbs.py26
-rwxr-xr-xutil/pbs/send.py29
-rwxr-xr-xutil/qdo16
-rw-r--r--util/stats/categories.py575
-rw-r--r--util/stats/db.py72
-rw-r--r--util/stats/display.py97
-rw-r--r--util/stats/info.py669
-rw-r--r--util/stats/output.py66
-rw-r--r--util/stats/profile.py483
-rwxr-xr-xutil/stats/stats.py104
36 files changed, 2611 insertions, 1279 deletions
diff --git a/SConscript b/SConscript
index 2726bbf20..677a06d1f 100644
--- a/SConscript
+++ b/SConscript
@@ -143,7 +143,6 @@ base_sources = Split('''
encumbered/cpu/full/issue.cc
encumbered/cpu/full/ls_queue.cc
encumbered/cpu/full/machine_queue.cc
- encumbered/cpu/full/pc_sample_profile.cc
encumbered/cpu/full/pipetrace.cc
encumbered/cpu/full/readyq.cc
encumbered/cpu/full/reg_info.cc
@@ -244,6 +243,7 @@ full_system_sources = Split('''
arch/alpha/ev5.cc
arch/alpha/osfpal.cc
arch/alpha/pseudo_inst.cc
+ arch/alpha/stacktrace.cc
arch/alpha/vtophys.cc
base/crc.cc
@@ -251,6 +251,7 @@ full_system_sources = Split('''
base/remote_gdb.cc
cpu/intr_control.cc
+ cpu/profile.cc
dev/alpha_console.cc
dev/baddev.cc
@@ -348,6 +349,7 @@ targetarch_files = Split('''
isa_traits.hh
osfpal.hh
pseudo_inst.hh
+ stacktrace.hh
vptr.hh
vtophys.hh
''')
diff --git a/arch/alpha/isa_traits.hh b/arch/alpha/isa_traits.hh
index cc6d81478..2570d12f0 100644
--- a/arch/alpha/isa_traits.hh
+++ b/arch/alpha/isa_traits.hh
@@ -73,8 +73,10 @@ class AlphaISA
// the rest of these depend on the ABI
StackPointerReg = 30,
GlobalPointerReg = 29,
+ ProcedureValueReg = 27,
ReturnAddressReg = 26,
ReturnValueReg = 0,
+ FramePointerReg = 15,
ArgumentReg0 = 16,
ArgumentReg1 = 17,
ArgumentReg2 = 18,
diff --git a/arch/alpha/stacktrace.cc b/arch/alpha/stacktrace.cc
new file mode 100644
index 000000000..fdad9d673
--- /dev/null
+++ b/arch/alpha/stacktrace.cc
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+#include <string>
+
+#include "arch/alpha/isa_traits.hh"
+#include "arch/alpha/stacktrace.hh"
+#include "arch/alpha/vtophys.hh"
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/exec_context.hh"
+
+using namespace std;
+
+ProcessInfo::ProcessInfo(ExecContext *_xc)
+ : xc(_xc)
+{
+ Addr addr = 0;
+
+ if (!xc->system->kernelSymtab->findAddress("thread_info_size", addr))
+ panic("thread info not compiled into kernel\n");
+ thread_info_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
+
+ if (!xc->system->kernelSymtab->findAddress("task_struct_size", addr))
+ panic("thread info not compiled into kernel\n");
+ task_struct_size = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
+
+ if (!xc->system->kernelSymtab->findAddress("thread_info_task", addr))
+ panic("thread info not compiled into kernel\n");
+ task_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
+
+ if (!xc->system->kernelSymtab->findAddress("task_struct_pid", addr))
+ panic("thread info not compiled into kernel\n");
+ pid_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
+
+ if (!xc->system->kernelSymtab->findAddress("task_struct_comm", addr))
+ panic("thread info not compiled into kernel\n");
+ name_off = *(int32_t *)vtomem(xc, addr, sizeof(int32_t));
+}
+
+Addr
+ProcessInfo::task(Addr ksp) const
+{
+ Addr base = ksp & ~0x3fff;
+ if (base == ULL(0xfffffc0000000000))
+ return 0;
+
+ Addr task;
+ CopyOut(xc, &task, base + task_off, sizeof(task));
+ return task;
+}
+
+int
+ProcessInfo::pid(Addr ksp) const
+{
+ Addr task = this->task(ksp);
+ if (!task)
+ return -1;
+
+ uint16_t pid;
+ CopyOut(xc, &pid, task + pid_off, sizeof(pid));
+ return pid;
+}
+
+string
+ProcessInfo::name(Addr ksp) const
+{
+ Addr task = this->task(ksp);
+ if (!task)
+ return "console";
+
+ char comm[256];
+ CopyString(xc, comm, task + name_off, sizeof(comm));
+ if (!comm[0])
+ return "startup";
+
+ return comm;
+}
+
+StackTrace::StackTrace(ExecContext *_xc, bool is_call)
+ : xc(_xc)
+{
+ bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0;
+
+ Addr pc = xc->regs.npc;
+ bool kernel = xc->system->kernelStart <= pc && pc <= xc->system->kernelEnd;
+
+ if (usermode) {
+ stack.push_back(1);
+ return;
+ }
+
+ if (!kernel) {
+ stack.push_back(2);
+ return;
+ }
+
+ SymbolTable *symtab = xc->system->allSymtab;
+ Addr ksp = xc->regs.intRegFile[TheISA::StackPointerReg];
+ Addr bottom = ksp & ~0x3fff;
+ Addr addr;
+
+ if (is_call) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find address %#x", pc);
+
+ stack.push_back(addr);
+ pc = xc->regs.pc;
+ }
+
+ Addr ra;
+ int size;
+
+ while (ksp > bottom) {
+ if (!symtab->findNearestAddr(pc, addr))
+ panic("could not find symbol for pc=%#x", pc);
+ assert(pc >= addr && "symbol botch: callpc < func");
+
+ stack.push_back(addr);
+
+ if (isEntry(addr))
+ return;
+
+ if (decodePrologue(ksp, pc, addr, size, ra)) {
+ if (!ra)
+ return;
+
+ pc = ra;
+ ksp += size;
+ } else {
+ stack.push_back(3);
+ return;
+ }
+
+ bool kernel = xc->system->kernelStart <= pc &&
+ pc <= xc->system->kernelEnd;
+ if (!kernel)
+ return;
+ }
+
+ panic("unwinding too far");
+}
+
+StackTrace::~StackTrace()
+{
+}
+
+bool
+StackTrace::isEntry(Addr addr)
+{
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp12])
+ return true;
+
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp7])
+ return true;
+
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp11])
+ return true;
+
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp21])
+ return true;
+
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp9])
+ return true;
+
+ if (addr == xc->regs.ipr[AlphaISA::IPR_PALtemp2])
+ return true;
+
+ return false;
+}
+
+bool
+StackTrace::decodeStack(MachInst inst, int &disp)
+{
+ // lda $sp, -disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == 30
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst mem_mask = 0xffff0000;
+ const MachInst lda_pattern = 0x23de0000;
+ const MachInst lda_disp_mask = 0x0000ffff;
+
+ // subq $sp, disp, $sp
+ // addq $sp, disp, $sp
+ //
+ // Opcode<31:26> == 0x10
+ // RA<25:21> == 30
+ // Lit<20:13>
+ // One<12> = 1
+ // Func<11:5> == 0x20 (addq)
+ // Func<11:5> == 0x29 (subq)
+ // RC<4:0> == 30
+ const MachInst intop_mask = 0xffe01fff;
+ const MachInst addq_pattern = 0x43c0141e;
+ const MachInst subq_pattern = 0x43c0153e;
+ const MachInst intop_disp_mask = 0x001fe000;
+ const int intop_disp_shift = 13;
+
+ if ((inst & mem_mask) == lda_pattern)
+ disp = -sext<16>(inst & lda_disp_mask);
+ else if ((inst & intop_mask) == addq_pattern)
+ disp = -int((inst & intop_disp_mask) >> intop_disp_shift);
+ else if ((inst & intop_mask) == subq_pattern)
+ disp = int((inst & intop_disp_mask) >> intop_disp_shift);
+ else
+ return false;
+
+ return true;
+}
+
+bool
+StackTrace::decodeSave(MachInst inst, int &reg, int &disp)
+{
+ // lda $stq, disp($sp)
+ //
+ // Opcode<31:26> == 0x08
+ // RA<25:21> == ?
+ // RB<20:16> == 30
+ // Disp<15:0>
+ const MachInst stq_mask = 0xfc1f0000;
+ const MachInst stq_pattern = 0xb41e0000;
+ const MachInst stq_disp_mask = 0x0000ffff;
+ const MachInst reg_mask = 0x03e00000;
+ const int reg_shift = 21;
+
+ if ((inst & stq_mask) == stq_pattern) {
+ reg = (inst & reg_mask) >> reg_shift;
+ disp = sext<16>(inst & stq_disp_mask);
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Decode the function prologue for the function we're in, and note
+ * which registers are stored where, and how large the stack frame is.
+ */
+bool
+StackTrace::decodePrologue(Addr sp, Addr callpc, Addr func,
+ int &size, Addr &ra)
+{
+ size = 0;
+ ra = 0;
+
+ for (Addr pc = func; pc < callpc; pc += sizeof(MachInst)) {
+ MachInst inst;
+ CopyOut(xc, (uint8_t *)&inst, pc, sizeof(MachInst));
+
+ int reg, disp;
+ if (decodeStack(inst, disp)) {
+ if (size) {
+ // panic("decoding frame size again");
+ return true;
+ }
+ size += disp;
+ } else if (decodeSave(inst, reg, disp)) {
+ if (!ra && reg == ReturnAddressReg) {
+ CopyOut(xc, (uint8_t *)&ra, sp + disp, sizeof(Addr));
+ if (!ra) {
+ // panic("no return address value pc=%#x\n", pc);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+#if TRACING_ON
+void
+StackTrace::dump()
+{
+ StringWrap name(xc->cpu->name());
+ SymbolTable *symtab = xc->system->allSymtab;
+
+ DPRINTFN("------ Stack ------\n");
+
+ string symbol;
+ for (int i = 0, size = stack.size(); i < size; ++i) {
+ Addr addr = stack[size - i - 1];
+ if (addr == 1)
+ symbol = "user";
+ else if (addr == 2)
+ symbol = "console";
+ else if (addr == 3)
+ symbol = "unknown";
+ else
+ symtab->findSymbol(addr, symbol);
+
+ DPRINTFN("%#x: %s\n", addr, symbol);
+ }
+}
+#endif
diff --git a/arch/alpha/stacktrace.hh b/arch/alpha/stacktrace.hh
new file mode 100644
index 000000000..5a4741eba
--- /dev/null
+++ b/arch/alpha/stacktrace.hh
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2005 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 __ARCH_ALPHA_STACKTRACE_HH__
+#define __ARCH_ALPHA_STACKTRACE_HH__
+
+#include "base/trace.hh"
+#include "cpu/static_inst.hh"
+
+class ExecContext;
+class StackTrace;
+class SymbolTable;
+
+class ProcessInfo
+{
+ private:
+ ExecContext *xc;
+
+ int thread_info_size;
+ int task_struct_size;
+ int task_off;
+ int pid_off;
+ int name_off;
+
+ public:
+ ProcessInfo(ExecContext *_xc);
+
+ Addr task(Addr ksp) const;
+ int pid(Addr ksp) const;
+ std::string name(Addr ksp) const;
+};
+
+class StackTrace
+{
+ private:
+ ExecContext *xc;
+ std::vector<Addr> stack;
+
+ private:
+ bool isEntry(Addr addr);
+ bool decodePrologue(Addr sp, Addr callpc, Addr func, int &size, Addr &ra);
+ bool decodeSave(MachInst inst, int &reg, int &disp);
+ bool decodeStack(MachInst inst, int &disp);
+
+ public:
+ StackTrace(ExecContext *xc, bool is_call);
+ ~StackTrace();
+
+ public:
+ const std::vector<Addr> &getstack() const { return stack; }
+ static StackTrace *create(ExecContext *xc, StaticInstPtr<TheISA> inst);
+
+#if TRACING_ON
+ private:
+ void dump();
+
+ public:
+ void dprintf() { if (DTRACE(Stack)) dump(); }
+#else
+ public:
+ void dprintf() {}
+#endif
+};
+
+inline StackTrace *
+StackTrace::create(ExecContext *xc, StaticInstPtr<TheISA> inst)
+{
+ if (!inst->isCall() && !inst->isReturn())
+ return NULL;
+
+ return new StackTrace(xc, !inst->isReturn());
+}
+
+#endif // __ARCH_ALPHA_STACKTRACE_HH__
diff --git a/arch/isa_parser.py b/arch/isa_parser.py
index eaef4b798..8f4c6bce7 100755
--- a/arch/isa_parser.py
+++ b/arch/isa_parser.py
@@ -794,20 +794,19 @@ def defFormat(id, params, code, lineno):
##############
# Stack: a simple stack object. Used for both formats (formatStack)
-# and default cases (defaultStack).
+# and default cases (defaultStack). Simply wraps a list to give more
+# stack-like syntax and enable initialization with an argument list
+# (as opposed to an argument that's a list).
-class Stack:
- def __init__(self, initItem):
- self.stack = [ initItem ]
+class Stack(list):
+ def __init__(self, *items):
+ list.__init__(self, items)
def push(self, item):
- self.stack.append(item);
-
- def pop(self):
- return self.stack.pop()
+ self.append(item);
def top(self):
- return self.stack[-1]
+ return self[-1]
# The global format stack.
formatStack = Stack(NoFormat())
diff --git a/base/traceflags.py b/base/traceflags.py
index a7d9ff9bf..d44d44681 100644
--- a/base/traceflags.py
+++ b/base/traceflags.py
@@ -140,7 +140,8 @@ baseFlags = [
'FullCPU',
'CommitRate',
'OoOCPU',
- 'HWPrefetch'
+ 'HWPrefetch',
+ 'Stack',
]
#
diff --git a/cpu/base.cc b/cpu/base.cc
index 8d97bc330..a6e71c808 100644
--- a/cpu/base.cc
+++ b/cpu/base.cc
@@ -142,8 +142,19 @@ BaseCPU::BaseCPU(Params *p)
e->schedule(p->functionTraceStart);
}
}
+#if FULL_SYSTEM
+ profileEvent = NULL;
+ if (params->profile)
+ profileEvent = new ProfileEvent(this, params->profile);
+#endif
}
+BaseCPU::Params::Params()
+{
+#if FULL_SYSTEM
+ profile = false;
+#endif
+}
void
BaseCPU::enableFunctionTrace()
@@ -163,6 +174,16 @@ BaseCPU::init()
}
void
+BaseCPU::startup()
+{
+#if FULL_SYSTEM
+ if (!params->deferRegistration && profileEvent)
+ profileEvent->schedule(curTick);
+#endif
+}
+
+
+void
BaseCPU::regStats()
{
using namespace Stats;
@@ -231,11 +252,32 @@ BaseCPU::takeOverFrom(BaseCPU *oldCPU)
for (int i = 0; i < NumInterruptLevels; ++i)
interrupts[i] = oldCPU->interrupts[i];
intstatus = oldCPU->intstatus;
+
+ for (int i = 0; i < execContexts.size(); ++i)
+ execContexts[i]->profile->clear();
+
+ if (profileEvent)
+ profileEvent->schedule(curTick);
#endif
}
#if FULL_SYSTEM
+BaseCPU::ProfileEvent::ProfileEvent(BaseCPU *_cpu, int _interval)
+ : Event(&mainEventQueue), cpu(_cpu), interval(_interval)
+{ }
+
+void
+BaseCPU::ProfileEvent::process()
+{
+ for (int i = 0, size = cpu->execContexts.size(); i < size; ++i) {
+ ExecContext *xc = cpu->execContexts[i];
+ xc->profile->sample(xc->profileNode, xc->profilePC);
+ }
+
+ schedule(curTick + interval);
+}
+
void
BaseCPU::post_interrupt(int int_num, int index)
{
diff --git a/cpu/base.hh b/cpu/base.hh
index b9617a730..914d06982 100644
--- a/cpu/base.hh
+++ b/cpu/base.hh
@@ -33,6 +33,7 @@
#include "base/statistics.hh"
#include "config/full_system.hh"
+#include "cpu/profile.hh"
#include "cpu/sampler/sampler.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
@@ -76,6 +77,18 @@ class BaseCPU : public SimObject
bool check_interrupts() const { return intstatus != 0; }
uint64_t intr_status() const { return intstatus; }
+
+ class ProfileEvent : public Event
+ {
+ private:
+ BaseCPU *cpu;
+ int interval;
+
+ public:
+ ProfileEvent(BaseCPU *cpu, int interval);
+ void process();
+ };
+ ProfileEvent *profileEvent;
#endif
protected:
@@ -113,7 +126,10 @@ class BaseCPU : public SimObject
#if FULL_SYSTEM
System *system;
int cpu_id;
+ Tick profile;
#endif
+
+ Params();
};
const Params *params;
@@ -122,6 +138,7 @@ class BaseCPU : public SimObject
virtual ~BaseCPU();
virtual void init();
+ virtual void startup();
virtual void regStats();
void registerExecContexts();
diff --git a/cpu/exec_context.cc b/cpu/exec_context.cc
index 91578bdf1..3fe951387 100644
--- a/cpu/exec_context.cc
+++ b/cpu/exec_context.cc
@@ -32,10 +32,15 @@
#include "cpu/exec_context.hh"
#if FULL_SYSTEM
+#include "base/callback.hh"
#include "base/cprintf.hh"
+#include "base/output.hh"
+#include "cpu/profile.hh"
#include "kern/kernel_stats.hh"
#include "sim/serialize.hh"
+#include "sim/sim_exit.hh"
#include "sim/system.hh"
+#include "targetarch/stacktrace.hh"
#else
#include "sim/process.hh"
#endif
@@ -51,10 +56,24 @@ ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num, System *_sys,
cpu_id(-1), mem(_mem), itb(_itb), dtb(_dtb), system(_sys),
memctrl(_sys->memctrl), physmem(_sys->physmem),
kernelBinning(system->kernelBinning), bin(kernelBinning->bin),
- fnbin(kernelBinning->fnbin), func_exe_inst(0), storeCondFailures(0)
+ fnbin(kernelBinning->fnbin), profile(NULL),
+ func_exe_inst(0), storeCondFailures(0)
{
kernelStats = new Kernel::Statistics(this);
memset(&regs, 0, sizeof(RegFile));
+
+ if (cpu->params->profile) {
+ profile = new FunctionProfile(system->allSymtab);
+ Callback *cb =
+ new MakeCallback<ExecContext, &ExecContext::dumpFuncProfile>(this);
+ registerExitCallback(cb);
+ }
+
+ // let's fill with a dummy node for now so we don't get a segfault
+ // on the first cycle when there's no node available.
+ static ProfileNode dummyNode;
+ profileNode = &dummyNode;
+ profilePC = 3;
}
#else
ExecContext::ExecContext(BaseCPU *_cpu, int _thread_num,
@@ -83,6 +102,14 @@ ExecContext::~ExecContext()
#endif
}
+#if FULL_SYSTEM
+void
+ExecContext::dumpFuncProfile()
+{
+ std::ostream *os = simout.create(csprintf("profile.%s.dat", cpu->name()));
+ profile->dump(this, *os);
+}
+#endif
void
ExecContext::takeOverFrom(ExecContext *oldContext)
@@ -106,15 +133,6 @@ ExecContext::takeOverFrom(ExecContext *oldContext)
oldContext->_status = ExecContext::Unallocated;
}
-#if FULL_SYSTEM
-void
-ExecContext::execute(const StaticInstBase *inst)
-{
- assert(kernelStats);
- system->kernelBinning->execute(this, inst);
-}
-#endif
-
void
ExecContext::serialize(ostream &os)
{
diff --git a/cpu/exec_context.hh b/cpu/exec_context.hh
index 6a17951f9..6f38a6960 100644
--- a/cpu/exec_context.hh
+++ b/cpu/exec_context.hh
@@ -46,8 +46,9 @@ class BaseCPU;
#include "sim/system.hh"
#include "targetarch/alpha_memory.hh"
+class FunctionProfile;
+class ProfileNode;
class MemoryController;
-class StaticInstBase;
namespace Kernel { class Binning; class Statistics; }
#else // !FULL_SYSTEM
@@ -138,7 +139,11 @@ class ExecContext
Kernel::Statistics *kernelStats;
bool bin;
bool fnbin;
- void execute(const StaticInstBase *inst);
+
+ FunctionProfile *profile;
+ ProfileNode *profileNode;
+ Addr profilePC;
+ void dumpFuncProfile();
#else
Process *process;
diff --git a/cpu/profile.cc b/cpu/profile.cc
new file mode 100644
index 000000000..b17a3c74e
--- /dev/null
+++ b/cpu/profile.cc
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2005 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.
+ */
+
+#include <string>
+
+#include "base/bitfield.hh"
+#include "base/trace.hh"
+#include "cpu/base.hh"
+#include "cpu/exec_context.hh"
+#include "cpu/profile.hh"
+
+using namespace std;
+
+ProfileNode::ProfileNode()
+ : count(0)
+{ }
+
+void
+ProfileNode::dump(const string &symbol, uint64_t id, const SymbolTable *symtab,
+ ostream &os) const
+{
+ ccprintf(os, "%#x %s %d ", id, symbol, count);
+ ChildList::const_iterator i, end = children.end();
+ for (i = children.begin(); i != end; ++i) {
+ const ProfileNode &node = i->second;
+ ccprintf(os, "%#x ", (intptr_t)&node);
+ }
+
+ ccprintf(os, "\n");
+
+ for (i = children.begin(); i != end; ++i) {
+ Addr addr = i->first;
+ string symbol;
+ if (addr == 1)
+ symbol = "user";
+ else if (addr == 2)
+ symbol = "console";
+ else if (addr == 3)
+ symbol = "unknown";
+ else if (!symtab->findSymbol(addr, symbol))
+ panic("could not find symbol for address %#x\n", addr);
+
+ const ProfileNode &node = i->second;
+ node.dump(symbol, (intptr_t)&node, symtab, os);
+ }
+}
+
+void
+ProfileNode::clear()
+{
+ count = 0;
+ ChildList::iterator i, end = children.end();
+ for (i = children.begin(); i != end; ++i) {
+ ProfileNode &node = i->second;
+ node.clear();
+ }
+
+}
+
+FunctionProfile::FunctionProfile(const SymbolTable *_symtab)
+ : symtab(_symtab)
+{
+}
+
+FunctionProfile::~FunctionProfile()
+{
+}
+
+ProfileNode *
+FunctionProfile::consume(const StackTrace *trace)
+{
+ const vector<Addr> &stack = trace->getstack();
+ ProfileNode *current = &top;
+ for (int i = 0, size = stack.size(); i < size; ++i)
+ current = &current->children[stack[size - i - 1]];
+
+ return current;
+}
+
+void
+FunctionProfile::clear()
+{
+ top.clear();
+ pc_count.clear();
+}
+
+void
+FunctionProfile::dump(ExecContext *xc, ostream &os) const
+{
+ ccprintf(os, ">>>PC data\n");
+ map<Addr, Counter>::const_iterator i, end = pc_count.end();
+ for (i = pc_count.begin(); i != end; ++i) {
+ Addr pc = i->first;
+ Counter count = i->second;
+
+ std::string symbol;
+ if (pc == 1)
+ ccprintf(os, "user %d\n", count);
+ else if (symtab->findSymbol(pc, symbol) && !symbol.empty())
+ ccprintf(os, "%s %d\n", symbol, count);
+ else
+ ccprintf(os, "%#x %d\n", pc, count);
+ }
+
+ ccprintf(os, ">>>function data\n");
+ top.dump("top", 0, symtab, os);
+}
+
+void
+FunctionProfile::sample(ProfileNode *node, Addr pc)
+{
+ node->count++;
+
+ Addr symaddr;
+ if (symtab->findNearestAddr(pc, symaddr)) {
+ pc_count[symaddr]++;
+ } else {
+ // record PC even if we don't have a symbol to avoid
+ // silently biasing the histogram
+ pc_count[pc]++;
+ }
+}
diff --git a/cpu/profile.hh b/cpu/profile.hh
new file mode 100644
index 000000000..9da170eb4
--- /dev/null
+++ b/cpu/profile.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2005 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 __CPU_PROFILE_HH__
+#define __CPU_PROFILE_HH__
+
+#include <map>
+
+#include "cpu/static_inst.hh"
+#include "sim/host.hh"
+#include "targetarch/stacktrace.hh"
+
+class ProfileNode
+{
+ private:
+ friend class FunctionProfile;
+
+ typedef std::map<Addr, ProfileNode> ChildList;
+ ChildList children;
+
+ public:
+ int count;
+
+ public:
+ ProfileNode();
+
+ void dump(const std::string &symbol, uint64_t id,
+ const SymbolTable *symtab, std::ostream &os) const;
+ void clear();
+};
+
+class FunctionProfile
+{
+ private:
+ const SymbolTable *symtab;
+ ProfileNode top;
+ std::map<Addr, Counter> pc_count;
+
+ public:
+ FunctionProfile(const SymbolTable *symtab);
+ ~FunctionProfile();
+
+ ProfileNode *consume(const StackTrace *trace);
+ void clear();
+ void dump(ExecContext *xc, std::ostream &out) const;
+ void sample(ProfileNode *node, Addr pc);
+};
+
+#endif // __CPU_PROFILE_HH__
diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc
index 1bd5547e7..8f7534e16 100644
--- a/cpu/simple/cpu.cc
+++ b/cpu/simple/cpu.cc
@@ -50,6 +50,7 @@
#include "cpu/simple/cpu.hh"
#include "cpu/smt.hh"
#include "cpu/static_inst.hh"
+#include "kern/kernel_stats.hh"
#include "mem/base_mem.hh"
#include "mem/mem_interface.hh"
#include "sim/builder.hh"
@@ -65,6 +66,7 @@
#include "mem/functional/physical.hh"
#include "sim/system.hh"
#include "targetarch/alpha_memory.hh"
+#include "targetarch/stacktrace.hh"
#include "targetarch/vtophys.hh"
#else // !FULL_SYSTEM
#include "mem/functional/functional.hh"
@@ -753,8 +755,21 @@ SimpleCPU::tick()
fault = curStaticInst->execute(this, traceData);
#if FULL_SYSTEM
- if (xc->fnbin)
- xc->execute(curStaticInst.get());
+ if (xc->fnbin) {
+ assert(xc->kernelStats);
+ system->kernelBinning->execute(xc, inst);
+ }
+
+ if (xc->profile) {
+ bool usermode = (xc->regs.ipr[AlphaISA::IPR_DTB_CM] & 0x18) != 0;
+ xc->profilePC = usermode ? 1 : xc->regs.pc;
+ StackTrace *trace = StackTrace::create(xc, inst);
+ if (trace) {
+ xc->profileNode = xc->profile->consume(trace);
+ trace->dprintf();
+ delete trace;
+ }
+ }
#endif
if (curStaticInst->isMemRef()) {
@@ -806,7 +821,6 @@ SimpleCPU::tick()
tickEvent.schedule(curTick + cycles(1));
}
-
////////////////////////////////////////////////////////////////////////
//
// SimpleCPU Simulation Object
@@ -824,6 +838,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(SimpleCPU)
SimObjectParam<FunctionalMemory *> mem;
SimObjectParam<System *> system;
Param<int> cpu_id;
+ Param<Tick> profile;
#else
SimObjectParam<Process *> workload;
#endif // FULL_SYSTEM
@@ -856,6 +871,7 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(SimpleCPU)
INIT_PARAM(mem, "memory"),
INIT_PARAM(system, "system object"),
INIT_PARAM(cpu_id, "processor ID"),
+ INIT_PARAM(profile, ""),
#else
INIT_PARAM(workload, "processes to run"),
#endif // FULL_SYSTEM
@@ -894,6 +910,7 @@ CREATE_SIM_OBJECT(SimpleCPU)
params->mem = mem;
params->system = system;
params->cpu_id = cpu_id;
+ params->profile = profile;
#else
params->process = workload;
#endif
diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc
index d67c6cf95..0537c344a 100644
--- a/dev/ns_gige.cc
+++ b/dev/ns_gige.cc
@@ -127,7 +127,7 @@ NSGigE::NSGigE(Params *p)
p->header_bus, 1,
p->dma_no_allocate);
} else if (p->payload_bus) {
- pioInterface = newPioInterface(name() + ".pio2", p->hier,
+ pioInterface = newPioInterface(name() + ".pio", p->hier,
p->payload_bus, this,
&NSGigE::cacheAccess);
@@ -771,7 +771,9 @@ NSGigE::read(MemReqPtr &req, uint8_t *data)
break;
case M5REG:
- reg = params()->m5reg;
+ reg = 0;
+ if (params()->dedicated)
+ reg |= M5REG_DEDICATED;
break;
default:
@@ -2529,20 +2531,17 @@ NSGigE::recvPacket(PacketPtr packet)
if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n");
- interface->recvDone();
return true;
}
if (!rxFilterEnable) {
DPRINTF(Ethernet,
"receive packet filtering disabled . . . packet dropped\n");
- interface->recvDone();
return true;
}
if (rxFilter(packet)) {
DPRINTF(Ethernet, "packet filtered...dropped\n");
- interface->recvDone();
return true;
}
@@ -2565,7 +2564,6 @@ NSGigE::recvPacket(PacketPtr packet)
}
rxFifo.push(packet);
- interface->recvDone();
rxKick();
return true;
@@ -2982,69 +2980,77 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
- Param<Addr> addr;
Param<Tick> clock;
- Param<Tick> tx_delay;
- Param<Tick> rx_delay;
- Param<Tick> intr_delay;
+
+ Param<Addr> addr;
SimObjectParam<MemoryController *> mmu;
SimObjectParam<PhysicalMemory *> physmem;
- Param<bool> rx_filter;
- Param<string> hardware_address;
+ SimObjectParam<PciConfigAll *> configspace;
+ SimObjectParam<PciConfigData *> configdata;
+ SimObjectParam<Platform *> platform;
+ Param<uint32_t> pci_bus;
+ Param<uint32_t> pci_dev;
+ Param<uint32_t> pci_func;
+
+ SimObjectParam<HierParams *> hier;
SimObjectParam<Bus*> io_bus;
SimObjectParam<Bus*> payload_bus;
- SimObjectParam<HierParams *> hier;
- Param<Tick> pio_latency;
Param<bool> dma_desc_free;
Param<bool> dma_data_free;
Param<Tick> dma_read_delay;
Param<Tick> dma_write_delay;
Param<Tick> dma_read_factor;
Param<Tick> dma_write_factor;
- SimObjectParam<PciConfigAll *> configspace;
- SimObjectParam<PciConfigData *> configdata;
- SimObjectParam<Platform *> platform;
- Param<uint32_t> pci_bus;
- Param<uint32_t> pci_dev;
- Param<uint32_t> pci_func;
- Param<uint32_t> tx_fifo_size;
- Param<uint32_t> rx_fifo_size;
- Param<uint32_t> m5reg;
Param<bool> dma_no_allocate;
+ Param<Tick> pio_latency;
+ Param<Tick> intr_delay;
+
+ Param<Tick> rx_delay;
+ Param<Tick> tx_delay;
+ Param<uint32_t> rx_fifo_size;
+ Param<uint32_t> tx_fifo_size;
+
+ Param<bool> rx_filter;
+ Param<string> hardware_address;
+ Param<bool> dedicated;
END_DECLARE_SIM_OBJECT_PARAMS(NSGigE)
BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE)
- INIT_PARAM(addr, "Device Address"),
INIT_PARAM(clock, "State machine processor frequency"),
- INIT_PARAM(tx_delay, "Transmit Delay"),
- INIT_PARAM(rx_delay, "Receive Delay"),
- INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
+
+ INIT_PARAM(addr, "Device Address"),
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(physmem, "Physical Memory"),
- INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
- INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
- INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL),
- INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL),
- INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
- INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
- INIT_PARAM_DFLT(dma_desc_free, "DMA of Descriptors is free", false),
- INIT_PARAM_DFLT(dma_data_free, "DMA of Data is free", false),
- INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0),
- INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0),
- INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0),
- INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0),
INIT_PARAM(configspace, "PCI Configspace"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(platform, "Platform"),
INIT_PARAM(pci_bus, "PCI bus"),
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
- INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 131072),
- INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 131072),
- INIT_PARAM(m5reg, "m5 register"),
- INIT_PARAM_DFLT(dma_no_allocate, "Should DMA reads allocate cache lines", true)
+
+ INIT_PARAM(hier, "Hierarchy global variables"),
+ INIT_PARAM(io_bus, "The IO Bus to attach to for headers"),
+ INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"),
+ INIT_PARAM(dma_desc_free, "DMA of Descriptors is free"),
+ INIT_PARAM(dma_data_free, "DMA of Data is free"),
+ INIT_PARAM(dma_read_delay, "fixed delay for dma reads"),
+ INIT_PARAM(dma_write_delay, "fixed delay for dma writes"),
+ INIT_PARAM(dma_read_factor, "multiplier for dma reads"),
+ INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
+ INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"),
+ INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
+ INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"),
+
+ INIT_PARAM(rx_delay, "Receive Delay"),
+ INIT_PARAM(tx_delay, "Transmit Delay"),
+ INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"),
+ INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"),
+
+ INIT_PARAM(rx_filter, "Enable Receive Filter"),
+ INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
+ INIT_PARAM(dedicated, "dedicate a kernel thread to the driver")
END_INIT_SIM_OBJECT_PARAMS(NSGigE)
@@ -3054,7 +3060,11 @@ CREATE_SIM_OBJECT(NSGigE)
NSGigE::Params *params = new NSGigE::Params;
params->name = getInstanceName();
+
+ params->clock = clock;
+
params->mmu = mmu;
+ params->pmem = physmem;
params->configSpace = configspace;
params->configData = configdata;
params->plat = platform;
@@ -3062,27 +3072,28 @@ CREATE_SIM_OBJECT(NSGigE)
params->deviceNum = pci_dev;
params->functionNum = pci_func;
- params->clock = clock;
- params->intr_delay = intr_delay;
- params->pmem = physmem;
- params->tx_delay = tx_delay;
- params->rx_delay = rx_delay;
params->hier = hier;
params->header_bus = io_bus;
params->payload_bus = payload_bus;
- params->pio_latency = pio_latency;
params->dma_desc_free = dma_desc_free;
params->dma_data_free = dma_data_free;
params->dma_read_delay = dma_read_delay;
params->dma_write_delay = dma_write_delay;
params->dma_read_factor = dma_read_factor;
params->dma_write_factor = dma_write_factor;
+ params->dma_no_allocate = dma_no_allocate;
+ params->pio_latency = pio_latency;
+ params->intr_delay = intr_delay;
+
+ params->rx_delay = rx_delay;
+ params->tx_delay = tx_delay;
+ params->rx_fifo_size = rx_fifo_size;
+ params->tx_fifo_size = tx_fifo_size;
+
params->rx_filter = rx_filter;
params->eaddr = hardware_address;
- params->tx_fifo_size = tx_fifo_size;
- params->rx_fifo_size = rx_fifo_size;
- params->m5reg = m5reg;
- params->dma_no_allocate = dma_no_allocate;
+ params->dedicated = dedicated;
+
return new NSGigE(params);
}
diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh
index 111003432..a04b52fe9 100644
--- a/dev/ns_gige.hh
+++ b/dev/ns_gige.hh
@@ -385,7 +385,7 @@ class NSGigE : public PciDev
Net::EthAddr eaddr;
uint32_t tx_fifo_size;
uint32_t rx_fifo_size;
- uint32_t m5reg;
+ bool dedicated;
bool dma_no_allocate;
};
diff --git a/dev/ns_gige_reg.h b/dev/ns_gige_reg.h
index 54ffb9075..f919ff086 100644
--- a/dev/ns_gige_reg.h
+++ b/dev/ns_gige_reg.h
@@ -304,6 +304,10 @@
#define TANAR_FULL_DUP 0x00000020
#define TANAR_UNUSED 0x00000E1F
+/* M5 control register */
+#define M5REG_RESERVED 0xfffffffe
+#define M5REG_DEDICATED 0x00000001
+
struct ns_desc32 {
uint32_t link; /* link field to next descriptor in linked list */
uint32_t bufptr; /* pointer to the first fragment or buffer */
diff --git a/dev/sinic.cc b/dev/sinic.cc
index 1914367bd..1a1456e5f 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -77,7 +77,7 @@ const char *TxStateStrings[] =
// Sinic PCI Device
//
Base::Base(Params *p)
- : PciDev(p), rxEnable(false), txEnable(false), cycleTime(p->cycle_time),
+ : PciDev(p), rxEnable(false), txEnable(false), clock(p->clock),
intrDelay(p->intr_delay), intrTick(0), cpuIntrEnable(false),
cpuPendingIntr(false), intrEvent(0), interface(NULL)
{
@@ -94,8 +94,8 @@ Device::Device(Params *p)
reset();
if (p->io_bus) {
- pioInterface = newPioInterface(p->name, p->hier, p->io_bus, this,
- &Device::cacheAccess);
+ pioInterface = newPioInterface(p->name + ".pio", p->hier, p->io_bus,
+ this, &Device::cacheAccess);
pioLatency = p->pio_latency * p->io_bus->clockRate;
@@ -108,7 +108,8 @@ Device::Device(Params *p)
p->io_bus, 1,
p->dma_no_allocate);
} else if (p->payload_bus) {
- pioInterface = newPioInterface(p->name, p->hier, p->payload_bus, this,
+ pioInterface = newPioInterface(p->name + ".pio", p->hier,
+ p->payload_bus, this,
&Device::cacheAccess);
pioLatency = p->pio_latency * p->payload_bus->clockRate;
@@ -315,9 +316,26 @@ Device::writeConfig(int offset, int size, const uint8_t *data)
}
}
+void
+Device::prepareRead()
+{
+ using namespace Regs;
+
+ // update rx registers
+ regs.RxDone = set_RxDone_Packets(regs.RxDone, rxFifo.packets());
+ regs.RxWait = regs.RxDone;
+
+ // update tx regsiters
+ regs.TxDone = set_TxDone_Packets(regs.TxDone, txFifo.packets());
+ regs.TxDone = set_TxDone_Full(regs.TxDone,
+ txFifo.avail() < regs.TxMaxCopy);
+ regs.TxDone = set_TxDone_Low(regs.TxDone,
+ txFifo.size() < regs.TxFifoMark);
+ regs.TxWait = regs.TxDone;
+}
+
/**
- * This reads the device registers, which are detailed in the NS83820
- * spec sheet
+ * I/O read of device register
*/
Fault
Device::read(MemReqPtr &req, uint8_t *data)
@@ -327,118 +345,115 @@ Device::read(MemReqPtr &req, uint8_t *data)
//The mask is to give you only the offset into the device register file
Addr daddr = req->paddr & 0xfff;
- if (Regs::regSize(daddr) == 0)
- panic("invalid address: da=%#x pa=%#x va=%#x size=%d",
+ if (!regValid(daddr))
+ panic("invalid register: da=%#x pa=%#x va=%#x size=%d",
daddr, req->paddr, req->vaddr, req->size);
- if (req->size != Regs::regSize(daddr))
- panic("invalid size for reg %s: da=%#x pa=%#x va=%#x size=%d",
- Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size);
-
- DPRINTF(EthernetPIO, "read reg=%s da=%#x pa=%#x va=%#x size=%d\n",
- Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size);
-
- uint32_t &reg32 = *(uint32_t *)data;
- uint64_t &reg64 = *(uint64_t *)data;
+ const Regs::Info &info = regInfo(daddr);
+ if (!info.read)
+ panic("reading write only register: %s: da=%#x pa=%#x va=%#x size=%d",
+ info.name, daddr, req->paddr, req->vaddr, req->size);
- switch (daddr) {
- case Regs::Config:
- reg32 = regs.Config;
- break;
+ if (req->size != info.size)
+ panic("invalid size for reg %s: da=%#x pa=%#x va=%#x size=%d",
+ info.name, daddr, req->paddr, req->vaddr, req->size);
- case Regs::RxMaxCopy:
- reg32 = regs.RxMaxCopy;
- break;
+ prepareRead();
- case Regs::TxMaxCopy:
- reg32 = regs.TxMaxCopy;
- break;
+ uint64_t value = 0;
+ if (req->size == 4) {
+ uint32_t &reg = *(uint32_t *)data;
+ reg = regData32(daddr);
+ value = reg;
+ }
- case Regs::RxThreshold:
- reg32 = regs.RxThreshold;
- break;
+ if (req->size == 8) {
+ uint64_t &reg = *(uint64_t *)data;
+ reg = regData64(daddr);
+ value = reg;
+ }
- case Regs::TxThreshold:
- reg32 = regs.TxThreshold;
- break;
+ DPRINTF(EthernetPIO, "read reg=%s da=%#x pa=%#x va=%#x size=%d val=%#x\n",
+ info.name, daddr, req->paddr, req->vaddr, req->size, value);
- case Regs::IntrStatus:
- reg32 = regs.IntrStatus;
+ // reading the interrupt status register has the side effect of
+ // clearing it
+ if (daddr == Regs::IntrStatus)
devIntrClear();
- break;
- case Regs::IntrMask:
- reg32 = regs.IntrMask;
- break;
+ return No_Fault;
+}
- case Regs::RxData:
- reg64 = regs.RxData;
- break;
+/**
+ * IPR read of device register
+ */
+Fault
+Device::iprRead(Addr daddr, uint64_t &result)
+{
+ if (!regValid(daddr))
+ panic("invalid address: da=%#x", daddr);
- case Regs::RxDone:
- case Regs::RxWait:
- reg64 = Regs::set_RxDone_FifoLen(regs.RxDone,
- min(rxFifo.packets(), 255));
- break;
+ const Regs::Info &info = regInfo(daddr);
+ if (!info.read)
+ panic("reading write only register %s: da=%#x", info.name, daddr);
- case Regs::TxData:
- reg64 = regs.TxData;
- break;
+ DPRINTF(EthernetPIO, "read reg=%s da=%#x\n", info.name, daddr);
- case Regs::TxDone:
- case Regs::TxWait:
- reg64 = Regs::set_TxDone_FifoLen(regs.TxDone,
- min(txFifo.packets(), 255));
- break;
+ prepareRead();
- case Regs::HwAddr:
- reg64 = params()->eaddr;
- break;
+ if (info.size == 4)
+ result = regData32(daddr);
- default:
- panic("reading write only register %s: da=%#x pa=%#x va=%#x size=%d",
- Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size);
- }
+ if (info.size == 8)
+ result = regData64(daddr);
- DPRINTF(EthernetPIO, "read reg=%s done val=%#x\n", Regs::regName(daddr),
- Regs::regSize(daddr) == 4 ? reg32 : reg64);
+ DPRINTF(EthernetPIO, "IPR read reg=%s da=%#x val=%#x\n",
+ info.name, result);
return No_Fault;
}
+/**
+ * I/O write of device register
+ */
Fault
Device::write(MemReqPtr &req, const uint8_t *data)
{
assert(config.command & PCI_CMD_MSE);
+
+ //The mask is to give you only the offset into the device register file
Addr daddr = req->paddr & 0xfff;
- if (Regs::regSize(daddr) == 0)
+ if (!regValid(daddr))
panic("invalid address: da=%#x pa=%#x va=%#x size=%d",
daddr, req->paddr, req->vaddr, req->size);
- if (req->size != Regs::regSize(daddr))
- panic("invalid size: reg=%s da=%#x pa=%#x va=%#x size=%d",
- Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size);
+ const Regs::Info &info = regInfo(daddr);
+ if (!info.write)
+ panic("writing read only register %s: da=%#x", info.name, daddr);
+
+ if (req->size != info.size)
+ panic("invalid size for reg %s: da=%#x pa=%#x va=%#x size=%d",
+ info.name, daddr, req->paddr, req->vaddr, req->size);
uint32_t reg32 = *(uint32_t *)data;
uint64_t reg64 = *(uint64_t *)data;
DPRINTF(EthernetPIO, "write reg=%s val=%#x da=%#x pa=%#x va=%#x size=%d\n",
- Regs::regName(daddr), Regs::regSize(daddr) == 4 ? reg32 : reg64,
- daddr, req->paddr, req->vaddr, req->size);
-
+ info.name, info.size == 4 ? reg32 : reg64, daddr, req->paddr,
+ req->vaddr, req->size);
switch (daddr) {
case Regs::Config:
changeConfig(reg32);
break;
- case Regs::RxThreshold:
- regs.RxThreshold = reg32;
+ case Regs::Command:
+ command(reg32);
break;
- case Regs::TxThreshold:
- regs.TxThreshold = reg32;
+ case Regs::IntrStatus:
+ devIntrClear(regs.IntrStatus & reg32);
break;
case Regs::IntrMask:
@@ -447,9 +462,10 @@ Device::write(MemReqPtr &req, const uint8_t *data)
case Regs::RxData:
if (rxState != rxIdle)
- panic("receive machine busy with another request!");
+ panic("receive machine busy with another request! rxState=%s",
+ RxStateStrings[rxState]);
- regs.RxDone = 0;
+ regs.RxDone = Regs::RxDone_Busy;
regs.RxData = reg64;
if (rxEnable) {
rxState = rxFifoBlock;
@@ -459,19 +475,16 @@ Device::write(MemReqPtr &req, const uint8_t *data)
case Regs::TxData:
if (txState != txIdle)
- panic("transmit machine busy with another request!");
+ panic("transmit machine busy with another request! txState=%s",
+ TxStateStrings[txState]);
- regs.TxDone = 0;
+ regs.TxDone = Regs::TxDone_Busy;
regs.TxData = reg64;
if (txEnable) {
txState = txFifoBlock;
txKick();
}
break;
-
- default:
- panic("writing read only register %s: da=%#x pa=%#x va=%#x size=%d",
- Regs::regName(daddr), daddr, req->paddr, req->vaddr, req->size);
}
return No_Fault;
@@ -489,9 +502,25 @@ Device::devIntrPost(uint32_t interrupts)
"interrupt written to intStatus: intr=%#x status=%#x mask=%#x\n",
interrupts, regs.IntrStatus, regs.IntrMask);
- if ((regs.IntrStatus & regs.IntrMask)) {
+ interrupts = regs.IntrStatus & regs.IntrMask;
+
+ // Intr_RxHigh is special, we only signal it if we've emptied the fifo
+ // and then filled it above the high watermark
+ if (rxEmpty)
+ rxEmpty = false;
+ else
+ interrupts &= ~Regs::Intr_RxHigh;
+
+ // Intr_TxLow is special, we only signal it if we've filled up the fifo
+ // and then dropped below the low watermark
+ if (txFull)
+ txFull = false;
+ else
+ interrupts &= ~Regs::Intr_TxLow;
+
+ if (interrupts) {
Tick when = curTick;
- if ((regs.IntrStatus & regs.IntrMask & Regs::Intr_NoDelay) == 0)
+ if ((interrupts & Regs::Intr_NoDelay) == 0)
when += intrDelay;
cpuIntrPost(when);
}
@@ -627,12 +656,6 @@ Device::changeConfig(uint32_t newconf)
regs.Config = newconf;
- if ((changed & Regs::Config_Reset)) {
- assert(regs.Config & Regs::Config_Reset);
- reset();
- regs.Config &= ~Regs::Config_Reset;
- }
-
if ((changed & Regs::Config_IntEn)) {
cpuIntrEnable = regs.Config & Regs::Config_IntEn;
if (cpuIntrEnable) {
@@ -657,19 +680,39 @@ Device::changeConfig(uint32_t newconf)
}
void
+Device::command(uint32_t command)
+{
+ if (command & Regs::Command_Reset)
+ reset();
+}
+
+void
Device::reset()
{
using namespace Regs;
+
memset(&regs, 0, sizeof(regs));
+
+ regs.Config = 0;
+ if (params()->dedicated)
+ regs.Config |= Config_Thread;
+ regs.IntrMask = Intr_RxHigh | Intr_RxDMA | Intr_TxLow;
regs.RxMaxCopy = params()->rx_max_copy;
regs.TxMaxCopy = params()->tx_max_copy;
- regs.IntrMask = Intr_TxFifo | Intr_RxFifo | Intr_RxData;
+ regs.RxMaxIntr = params()->rx_max_intr;
+ regs.RxFifoSize = params()->rx_fifo_size;
+ regs.TxFifoSize = params()->tx_fifo_size;
+ regs.RxFifoMark = params()->rx_fifo_threshold;
+ regs.TxFifoMark = params()->tx_fifo_threshold;
+ regs.HwAddr = params()->eaddr;
rxState = rxIdle;
txState = txIdle;
rxFifo.clear();
txFifo.clear();
+ rxEmpty = false;
+ txFull = false;
}
void
@@ -680,13 +723,18 @@ Device::rxDmaCopy()
physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen);
DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
rxDmaAddr, rxDmaLen);
- DDUMP(EthernetDMA, rxDmaData, rxDmaLen);
+ DDUMP(EthernetData, rxDmaData, rxDmaLen);
}
void
Device::rxDmaDone()
{
rxDmaCopy();
+
+ // If the transmit state machine has a pending DMA, let it go first
+ if (txState == txBeginCopy)
+ txKick();
+
rxKick();
}
@@ -706,6 +754,8 @@ Device::rxKick()
switch (rxState) {
case rxIdle:
if (rxPioRequest) {
+ DPRINTF(EthernetPIO, "rxIdle: PIO waiting responding at %d\n",
+ curTick + pioLatency);
pioInterface->respond(rxPioRequest, curTick);
rxPioRequest = 0;
}
@@ -761,20 +811,20 @@ Device::rxKick()
break;
case rxBeginCopy:
+ if (dmaInterface && dmaInterface->busy())
+ goto exit;
+
rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(regs.RxData));
rxDmaLen = min<int>(Regs::get_RxData_Len(regs.RxData), rxPktBytes);
rxDmaData = rxPacketBufPtr;
+ rxState = rxCopy;
if (dmaInterface) {
- if (!dmaInterface->busy()) {
- dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen,
- curTick, &rxDmaEvent, true);
- rxState = rxCopy;
- }
+ dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen,
+ curTick, &rxDmaEvent, true);
goto exit;
}
- rxState = rxCopy;
if (dmaWriteDelay != 0 || dmaWriteFactor != 0) {
Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor;
Tick start = curTick + dmaWriteDelay + factor;
@@ -802,7 +852,7 @@ Device::rxKick()
}
regs.RxDone |= Regs::RxDone_Complete;
- devIntrPost(Regs::Intr_RxData);
+ devIntrPost(Regs::Intr_RxDMA);
rxState = rxIdle;
break;
@@ -831,13 +881,18 @@ Device::txDmaCopy()
physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen);
DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n",
txDmaAddr, txDmaLen);
- DDUMP(EthernetDMA, txDmaData, txDmaLen);
+ DDUMP(EthernetData, txDmaData, txDmaLen);
}
void
Device::txDmaDone()
{
txDmaCopy();
+
+ // If the receive state machine has a pending DMA, let it go first
+ if (rxState == rxBeginCopy)
+ rxKick();
+
txKick();
}
@@ -849,6 +904,7 @@ Device::transmit()
return;
}
+ uint32_t interrupts;
PacketPtr packet = txFifo.front();
if (!interface->sendPacket(packet)) {
DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n",
@@ -857,7 +913,6 @@ Device::transmit()
}
txFifo.pop();
-
#if TRACING_ON
if (DTRACE(Ethernet)) {
IpPtr ip(packet);
@@ -872,17 +927,17 @@ Device::transmit()
}
#endif
- DDUMP(Ethernet, packet->data, packet->length);
+ DDUMP(EthernetData, packet->data, packet->length);
txBytes += packet->length;
txPackets++;
DPRINTF(Ethernet, "Packet Transmit: successful txFifo Available %d\n",
txFifo.avail());
- if (txFifo.size() <= params()->tx_fifo_threshold)
- devIntrPost(Regs::Intr_TxFifo);
-
- devIntrPost(Regs::Intr_TxDone);
+ interrupts = Regs::Intr_TxPacket;
+ if (txFifo.size() < regs.TxFifoMark)
+ interrupts |= Regs::Intr_TxLow;
+ devIntrPost(interrupts);
reschedule:
if (!txFifo.empty() && !txEvent.scheduled()) {
@@ -907,6 +962,8 @@ Device::txKick()
switch (txState) {
case txIdle:
if (txPioRequest) {
+ DPRINTF(EthernetPIO, "txIdle: PIO waiting responding at %d\n",
+ curTick + pioLatency);
pioInterface->respond(txPioRequest, curTick + pioLatency);
txPioRequest = 0;
}
@@ -929,21 +986,20 @@ Device::txKick()
break;
case txBeginCopy:
+ if (dmaInterface && dmaInterface->busy())
+ goto exit;
+
txDmaAddr = plat->pciToDma(Regs::get_TxData_Addr(regs.TxData));
txDmaLen = Regs::get_TxData_Len(regs.TxData);
txDmaData = txPacketBufPtr;
+ txState = txCopy;
if (dmaInterface) {
- if (!dmaInterface->busy()) {
- dmaInterface->doDMA(Read, txDmaAddr, txDmaLen,
- curTick, &txDmaEvent, true);
- txState = txCopy;
- }
-
+ dmaInterface->doDMA(Read, txDmaAddr, txDmaLen,
+ curTick, &txDmaEvent, true);
goto exit;
}
- txState = txCopy;
if (dmaReadDelay != 0 || dmaReadFactor != 0) {
Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor;
Tick start = curTick + dmaReadDelay + factor;
@@ -987,12 +1043,16 @@ Device::txKick()
}
}
txFifo.push(txPacket);
+ if (txFifo.avail() < regs.TxMaxCopy) {
+ devIntrPost(Regs::Intr_TxFull);
+ txFull = true;
+ }
txPacket = 0;
transmit();
}
regs.TxDone = txDmaLen | Regs::TxDone_Complete;
- devIntrPost(Regs::Intr_TxData);
+ devIntrPost(Regs::Intr_TxDMA);
txState = txIdle;
break;
@@ -1085,18 +1145,16 @@ Device::recvPacket(PacketPtr packet)
if (!rxEnable) {
DPRINTF(Ethernet, "receive disabled...packet dropped\n");
- interface->recvDone();
return true;
}
if (rxFilter(packet)) {
DPRINTF(Ethernet, "packet filtered...dropped\n");
- interface->recvDone();
return true;
}
- if (rxFifo.size() >= params()->rx_fifo_threshold)
- devIntrPost(Regs::Intr_RxFifo);
+ if (rxFifo.size() >= regs.RxFifoMark)
+ devIntrPost(Regs::Intr_RxHigh);
if (!rxFifo.push(packet)) {
DPRINTF(Ethernet,
@@ -1104,8 +1162,7 @@ Device::recvPacket(PacketPtr packet)
return false;
}
- interface->recvDone();
- devIntrPost(Regs::Intr_RxDone);
+ devIntrPost(Regs::Intr_RxPacket);
rxKick();
return true;
}
@@ -1163,22 +1220,23 @@ Device::serialize(ostream &os)
// Serialize the PciDev base class
Base::serialize(os);
- if (rxDmaEvent.scheduled())
- rxDmaCopy();
+ if (rxState == rxCopy)
+ panic("can't serialize with an in flight dma request rxState=%s",
+ RxStateStrings[rxState]);
- if (txDmaEvent.scheduled())
- txDmaCopy();
+ if (txState == txCopy)
+ panic("can't serialize with an in flight dma request txState=%s",
+ TxStateStrings[txState]);
/*
* Serialize the device registers
*/
SERIALIZE_SCALAR(regs.Config);
- SERIALIZE_SCALAR(regs.RxMaxCopy);
- SERIALIZE_SCALAR(regs.TxMaxCopy);
- SERIALIZE_SCALAR(regs.RxThreshold);
- SERIALIZE_SCALAR(regs.TxThreshold);
SERIALIZE_SCALAR(regs.IntrStatus);
SERIALIZE_SCALAR(regs.IntrMask);
+ SERIALIZE_SCALAR(regs.RxMaxCopy);
+ SERIALIZE_SCALAR(regs.TxMaxCopy);
+ SERIALIZE_SCALAR(regs.RxMaxIntr);
SERIALIZE_SCALAR(regs.RxData);
SERIALIZE_SCALAR(regs.RxDone);
SERIALIZE_SCALAR(regs.TxData);
@@ -1189,6 +1247,7 @@ Device::serialize(ostream &os)
*/
int rxState = this->rxState;
SERIALIZE_SCALAR(rxState);
+ SERIALIZE_SCALAR(rxEmpty);
rxFifo.serialize("rxFifo", os);
bool rxPacketExists = rxPacket;
SERIALIZE_SCALAR(rxPacketExists);
@@ -1205,6 +1264,7 @@ Device::serialize(ostream &os)
*/
int txState = this->txState;
SERIALIZE_SCALAR(txState);
+ SERIALIZE_SCALAR(txFull);
txFifo.serialize("txFifo", os);
bool txPacketExists = txPacket;
SERIALIZE_SCALAR(txPacketExists);
@@ -1233,12 +1293,11 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
* Unserialize the device registers
*/
UNSERIALIZE_SCALAR(regs.Config);
- UNSERIALIZE_SCALAR(regs.RxMaxCopy);
- UNSERIALIZE_SCALAR(regs.TxMaxCopy);
- UNSERIALIZE_SCALAR(regs.RxThreshold);
- UNSERIALIZE_SCALAR(regs.TxThreshold);
UNSERIALIZE_SCALAR(regs.IntrStatus);
UNSERIALIZE_SCALAR(regs.IntrMask);
+ UNSERIALIZE_SCALAR(regs.RxMaxCopy);
+ UNSERIALIZE_SCALAR(regs.TxMaxCopy);
+ UNSERIALIZE_SCALAR(regs.RxMaxIntr);
UNSERIALIZE_SCALAR(regs.RxData);
UNSERIALIZE_SCALAR(regs.RxDone);
UNSERIALIZE_SCALAR(regs.TxData);
@@ -1249,6 +1308,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
*/
int rxState;
UNSERIALIZE_SCALAR(rxState);
+ UNSERIALIZE_SCALAR(rxEmpty);
this->rxState = (RxState) rxState;
rxFifo.unserialize("rxFifo", cp, section);
bool rxPacketExists;
@@ -1269,6 +1329,7 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
*/
int txState;
UNSERIALIZE_SCALAR(txState);
+ UNSERIALIZE_SCALAR(txFull);
this->txState = (TxState) txState;
txFifo.unserialize("txFifo", cp, section);
bool txPacketExists;
@@ -1310,15 +1371,19 @@ Device::cacheAccess(MemReqPtr &req)
Tick when = curTick + pioLatency;
switch (daddr) {
- case Regs::RxDone:
+ case Regs::RxWait:
if (rxState != rxIdle) {
+ DPRINTF(EthernetPIO, "rxState=%s (not idle)... waiting\n",
+ TxStateStrings[txState]);
rxPioRequest = req;
when = 0;
}
break;
- case Regs::TxDone:
+ case Regs::TxWait:
if (txState != txIdle) {
+ DPRINTF(EthernetPIO, "txState=%s (not idle)... waiting\n",
+ TxStateStrings[txState]);
txPioRequest = req;
when = 0;
}
@@ -1360,71 +1425,83 @@ REGISTER_SIM_OBJECT("SinicInt", Interface)
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
+ Param<Tick> clock;
+
Param<Addr> addr;
- Param<Tick> cycle_time;
- Param<Tick> tx_delay;
- Param<Tick> rx_delay;
- Param<Tick> intr_delay;
SimObjectParam<MemoryController *> mmu;
SimObjectParam<PhysicalMemory *> physmem;
- Param<bool> rx_filter;
- Param<string> hardware_address;
- SimObjectParam<Bus*> io_bus;
- SimObjectParam<Bus*> payload_bus;
- SimObjectParam<HierParams *> hier;
- Param<Tick> pio_latency;
SimObjectParam<PciConfigAll *> configspace;
SimObjectParam<PciConfigData *> configdata;
SimObjectParam<Platform *> platform;
Param<uint32_t> pci_bus;
Param<uint32_t> pci_dev;
Param<uint32_t> pci_func;
+
+ SimObjectParam<HierParams *> hier;
+ SimObjectParam<Bus*> io_bus;
+ SimObjectParam<Bus*> payload_bus;
+ Param<Tick> dma_read_delay;
+ Param<Tick> dma_read_factor;
+ Param<Tick> dma_write_delay;
+ Param<Tick> dma_write_factor;
+ Param<bool> dma_no_allocate;
+ Param<Tick> pio_latency;
+ Param<Tick> intr_delay;
+
+ Param<Tick> rx_delay;
+ Param<Tick> tx_delay;
Param<uint32_t> rx_max_copy;
Param<uint32_t> tx_max_copy;
+ Param<uint32_t> rx_max_intr;
Param<uint32_t> rx_fifo_size;
Param<uint32_t> tx_fifo_size;
Param<uint32_t> rx_fifo_threshold;
Param<uint32_t> tx_fifo_threshold;
- Param<Tick> dma_read_delay;
- Param<Tick> dma_read_factor;
- Param<Tick> dma_write_delay;
- Param<Tick> dma_write_factor;
- Param<bool> dma_no_allocate;
+
+ Param<bool> rx_filter;
+ Param<string> hardware_address;
+ Param<bool> dedicated;
END_DECLARE_SIM_OBJECT_PARAMS(Device)
BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
+ INIT_PARAM(clock, "State machine cycle time"),
+
INIT_PARAM(addr, "Device Address"),
- INIT_PARAM(cycle_time, "State machine cycle time"),
- INIT_PARAM_DFLT(tx_delay, "Transmit Delay", 1000),
- INIT_PARAM_DFLT(rx_delay, "Receive Delay", 1000),
- INIT_PARAM_DFLT(intr_delay, "Interrupt Delay in microseconds", 0),
INIT_PARAM(mmu, "Memory Controller"),
INIT_PARAM(physmem, "Physical Memory"),
- INIT_PARAM_DFLT(rx_filter, "Enable Receive Filter", true),
- INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
- INIT_PARAM_DFLT(io_bus, "The IO Bus to attach to for headers", NULL),
- INIT_PARAM_DFLT(payload_bus, "The IO Bus to attach to for payload", NULL),
- INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams),
- INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1),
INIT_PARAM(configspace, "PCI Configspace"),
INIT_PARAM(configdata, "PCI Config data"),
INIT_PARAM(platform, "Platform"),
INIT_PARAM(pci_bus, "PCI bus"),
INIT_PARAM(pci_dev, "PCI device number"),
INIT_PARAM(pci_func, "PCI function code"),
- INIT_PARAM_DFLT(rx_max_copy, "rx max copy", 16*1024),
- INIT_PARAM_DFLT(tx_max_copy, "rx max copy", 16*1024),
- INIT_PARAM_DFLT(rx_fifo_size, "max size in bytes of rxFifo", 64*1024),
- INIT_PARAM_DFLT(tx_fifo_size, "max size in bytes of txFifo", 64*1024),
- INIT_PARAM_DFLT(rx_fifo_threshold, "max size in bytes of rxFifo", 48*1024),
- INIT_PARAM_DFLT(tx_fifo_threshold, "max size in bytes of txFifo", 16*1024),
- INIT_PARAM_DFLT(dma_read_delay, "fixed delay for dma reads", 0),
- INIT_PARAM_DFLT(dma_read_factor, "multiplier for dma reads", 0),
- INIT_PARAM_DFLT(dma_write_delay, "fixed delay for dma writes", 0),
- INIT_PARAM_DFLT(dma_write_factor, "multiplier for dma writes", 0),
- INIT_PARAM_DFLT(dma_no_allocate, "Should we allocat on read in cache", true)
+
+ INIT_PARAM(hier, "Hierarchy global variables"),
+ INIT_PARAM(io_bus, "The IO Bus to attach to for headers"),
+ INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"),
+ INIT_PARAM(dma_read_delay, "fixed delay for dma reads"),
+ INIT_PARAM(dma_read_factor, "multiplier for dma reads"),
+ INIT_PARAM(dma_write_delay, "fixed delay for dma writes"),
+ INIT_PARAM(dma_write_factor, "multiplier for dma writes"),
+ INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"),
+ INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"),
+ INIT_PARAM(intr_delay, "Interrupt Delay"),
+
+ INIT_PARAM(rx_delay, "Receive Delay"),
+ INIT_PARAM(tx_delay, "Transmit Delay"),
+ INIT_PARAM(rx_max_copy, "rx max copy"),
+ INIT_PARAM(tx_max_copy, "rx max copy"),
+ INIT_PARAM(rx_max_intr, "rx max intr"),
+ INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"),
+ INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"),
+ INIT_PARAM(rx_fifo_threshold, "max size in bytes of rxFifo"),
+ INIT_PARAM(tx_fifo_threshold, "max size in bytes of txFifo"),
+
+ INIT_PARAM(rx_filter, "Enable Receive Filter"),
+ INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
+ INIT_PARAM(dedicated, "dedicate a kernel thread to the driver")
END_INIT_SIM_OBJECT_PARAMS(Device)
@@ -1432,36 +1509,45 @@ END_INIT_SIM_OBJECT_PARAMS(Device)
CREATE_SIM_OBJECT(Device)
{
Device::Params *params = new Device::Params;
+
params->name = getInstanceName();
- params->intr_delay = intr_delay;
- params->physmem = physmem;
- params->cycle_time = cycle_time;
- params->tx_delay = tx_delay;
- params->rx_delay = rx_delay;
+
+ params->clock = clock;
+
params->mmu = mmu;
- params->hier = hier;
- params->io_bus = io_bus;
- params->payload_bus = payload_bus;
- params->pio_latency = pio_latency;
+ params->physmem = physmem;
params->configSpace = configspace;
params->configData = configdata;
params->plat = platform;
params->busNum = pci_bus;
params->deviceNum = pci_dev;
params->functionNum = pci_func;
- params->rx_filter = rx_filter;
- params->eaddr = hardware_address;
+
+ params->hier = hier;
+ params->io_bus = io_bus;
+ params->payload_bus = payload_bus;
+ params->dma_read_delay = dma_read_delay;
+ params->dma_read_factor = dma_read_factor;
+ params->dma_write_delay = dma_write_delay;
+ params->dma_write_factor = dma_write_factor;
+ params->dma_no_allocate = dma_no_allocate;
+ params->pio_latency = pio_latency;
+ params->intr_delay = intr_delay;
+
+ params->tx_delay = tx_delay;
+ params->rx_delay = rx_delay;
params->rx_max_copy = rx_max_copy;
params->tx_max_copy = tx_max_copy;
+ params->rx_max_intr = rx_max_intr;
params->rx_fifo_size = rx_fifo_size;
params->tx_fifo_size = tx_fifo_size;
params->rx_fifo_threshold = rx_fifo_threshold;
params->tx_fifo_threshold = tx_fifo_threshold;
- params->dma_read_delay = dma_read_delay;
- params->dma_read_factor = dma_read_factor;
- params->dma_write_delay = dma_write_delay;
- params->dma_write_factor = dma_write_factor;
- params->dma_no_allocate = dma_no_allocate;
+
+ params->rx_filter = rx_filter;
+ params->eaddr = hardware_address;
+ params->dedicated = dedicated;
+
return new Device(params);
}
diff --git a/dev/sinic.hh b/dev/sinic.hh
index d190746a4..e01015061 100644
--- a/dev/sinic.hh
+++ b/dev/sinic.hh
@@ -48,8 +48,8 @@ class Base : public PciDev
protected:
bool rxEnable;
bool txEnable;
- Tick cycleTime;
- inline Tick cycles(int numCycles) const { return numCycles * cycleTime; }
+ Tick clock;
+ inline Tick cycles(int numCycles) const { return numCycles * clock; }
protected:
Tick intrDelay;
@@ -81,7 +81,7 @@ class Base : public PciDev
public:
struct Params : public PciDev::Params
{
- Tick cycle_time;
+ Tick clock;
Tick intr_delay;
};
@@ -115,19 +115,31 @@ class Device : public Base
/** device register file */
struct {
- uint32_t Config;
- uint32_t RxMaxCopy;
- uint32_t TxMaxCopy;
- uint32_t RxThreshold;
- uint32_t TxThreshold;
- uint32_t IntrStatus;
- uint32_t IntrMask;
- uint64_t RxData;
- uint64_t RxDone;
- uint64_t TxData;
- uint64_t TxDone;
+ uint32_t Config; // 0x00
+ uint32_t Command; // 0x04
+ uint32_t IntrStatus; // 0x08
+ uint32_t IntrMask; // 0x0c
+ uint32_t RxMaxCopy; // 0x10
+ uint32_t TxMaxCopy; // 0x14
+ uint32_t RxMaxIntr; // 0x18
+ uint32_t Reserved0; // 0x1c
+ uint32_t RxFifoSize; // 0x20
+ uint32_t TxFifoSize; // 0x24
+ uint32_t RxFifoMark; // 0x28
+ uint32_t TxFifoMark; // 0x2c
+ uint64_t RxData; // 0x30
+ uint64_t RxDone; // 0x38
+ uint64_t RxWait; // 0x40
+ uint64_t TxData; // 0x48
+ uint64_t TxDone; // 0x50
+ uint64_t TxWait; // 0x58
+ uint64_t HwAddr; // 0x60
} regs;
+ uint8_t &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
+ uint32_t &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
+ uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(daddr); }
+
private:
Addr addr;
static const Addr size = Regs::Size;
@@ -135,6 +147,7 @@ class Device : public Base
protected:
RxState rxState;
PacketFifo rxFifo;
+ bool rxEmpty;
PacketPtr rxPacket;
uint8_t *rxPacketBufPtr;
int rxPktBytes;
@@ -145,6 +158,7 @@ class Device : public Base
TxState txState;
PacketFifo txFifo;
+ bool txFull;
PacketPtr txPacket;
uint8_t *txPacketBufPtr;
int txPktBytes;
@@ -191,6 +205,7 @@ class Device : public Base
* device configuration
*/
void changeConfig(uint32_t newconfig);
+ void command(uint32_t command);
/**
* device ethernet interface
@@ -212,7 +227,7 @@ class Device : public Base
void txDmaCopy();
void txDmaDone();
friend class EventWrapper<Device, &Device::txDmaDone>;
- EventWrapper<Device, &Device::rxDmaDone> txDmaEvent;
+ EventWrapper<Device, &Device::txDmaDone> txDmaEvent;
Tick dmaReadDelay;
Tick dmaReadFactor;
@@ -244,6 +259,8 @@ class Device : public Base
* Memory Interface
*/
public:
+ void prepareRead();
+ Fault iprRead(Addr daddr, uint64_t &result);
virtual Fault read(MemReqPtr &req, uint8_t *data);
virtual Fault write(MemReqPtr &req, const uint8_t *data);
Tick cacheAccess(MemReqPtr &req);
@@ -308,6 +325,7 @@ class Device : public Base
Net::EthAddr eaddr;
uint32_t rx_max_copy;
uint32_t tx_max_copy;
+ uint32_t rx_max_intr;
uint32_t rx_fifo_size;
uint32_t tx_fifo_size;
uint32_t rx_fifo_threshold;
@@ -317,6 +335,7 @@ class Device : public Base
Tick dma_write_delay;
Tick dma_write_factor;
bool dma_no_allocate;
+ bool dedicated;
};
protected:
diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh
index 78b175f71..12f545255 100644
--- a/dev/sinicreg.hh
+++ b/dev/sinicreg.hh
@@ -57,23 +57,28 @@ namespace Regs {
// Registers
__SINIC_REG32(Config, 0x00); // 32: configuration register
-__SINIC_REG32(RxMaxCopy, 0x04); // 32: max rx copy
-__SINIC_REG32(TxMaxCopy, 0x08); // 32: max tx copy
-__SINIC_REG32(RxThreshold, 0x0c); // 32: receive fifo threshold
-__SINIC_REG32(TxThreshold, 0x10); // 32: transmit fifo threshold
-__SINIC_REG32(IntrStatus, 0x14); // 32: interrupt status
-__SINIC_REG32(IntrMask, 0x18); // 32: interrupt mask
-__SINIC_REG32(RxData, 0x20); // 64: receive data
-__SINIC_REG32(RxDone, 0x28); // 64: receive done
-__SINIC_REG32(RxWait, 0x30); // 64: receive done (busy wait)
-__SINIC_REG32(TxData, 0x38); // 64: transmit data
-__SINIC_REG32(TxDone, 0x40); // 64: transmit done
-__SINIC_REG32(TxWait, 0x48); // 64: transmit done (busy wait)
-__SINIC_REG32(HwAddr, 0x50); // 64: mac address
-__SINIC_REG32(Size, 0x58);
+__SINIC_REG32(Command, 0x04); // 32: command register
+__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status
+__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask
+__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy
+__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy
+__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt
+__SINIC_REG32(Reserved0, 0x1c); // 32: reserved
+__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes
+__SINIC_REG32(TxFifoSize, 0x24); // 32: tx fifo capacity in bytes
+__SINIC_REG32(RxFifoMark, 0x28); // 32: rx fifo high watermark
+__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark
+__SINIC_REG32(RxData, 0x30); // 64: receive data
+__SINIC_REG32(RxDone, 0x38); // 64: receive done
+__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait)
+__SINIC_REG32(TxData, 0x48); // 64: transmit data
+__SINIC_REG32(TxDone, 0x50); // 64: transmit done
+__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait)
+__SINIC_REG32(HwAddr, 0x60); // 64: mac address
+__SINIC_REG32(Size, 0x68); // register addres space size
// Config register bits
-__SINIC_VAL32(Config_Reset, 31, 1); // reset chip
+__SINIC_VAL32(Config_Thread, 8, 1); // enable receive filter
__SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter
__SINIC_VAL32(Config_Vlan, 6, 1); // enable vlan tagging
__SINIC_VAL32(Config_Virtual, 5, 1); // enable virtual addressing
@@ -83,105 +88,103 @@ __SINIC_VAL32(Config_IntEn, 2, 1); // enable interrupts
__SINIC_VAL32(Config_TxEn, 1, 1); // enable transmit
__SINIC_VAL32(Config_RxEn, 0, 1); // enable receive
+// Command register bits
+__SINIC_VAL32(Command_Reset, 0, 1); // reset chip
+
// Interrupt register bits
-__SINIC_VAL32(Intr_TxFifo, 5, 1); // Fifo oflow/uflow/threshold
-__SINIC_VAL32(Intr_TxData, 4, 1); // DMA Completed w/ interrupt
-__SINIC_VAL32(Intr_TxDone, 3, 1); // Packet transmitted
-__SINIC_VAL32(Intr_RxFifo, 2, 1); // Fifo oflow/uflow/threshold
-__SINIC_VAL32(Intr_RxData, 1, 1); // DMA Completed w/ interrupt
-__SINIC_VAL32(Intr_RxDone, 0, 1); // Packet received
-__SINIC_REG32(Intr_All, 0x3f);
-__SINIC_REG32(Intr_NoDelay, 0x24);
-__SINIC_REG32(Intr_Res, ~0x3f);
+__SINIC_VAL32(Intr_TxLow, 7, 1); // tx fifo dropped below watermark
+__SINIC_VAL32(Intr_TxFull, 6, 1); // tx fifo full
+__SINIC_VAL32(Intr_TxDMA, 5, 1); // tx dma completed w/ interrupt
+__SINIC_VAL32(Intr_TxPacket, 4, 1); // packet transmitted
+__SINIC_VAL32(Intr_RxHigh, 3, 1); // rx fifo above high watermark
+__SINIC_VAL32(Intr_RxEmpty, 2, 1); // rx fifo empty
+__SINIC_VAL32(Intr_RxDMA, 1, 1); // rx dma completed w/ interrupt
+__SINIC_VAL32(Intr_RxPacket, 0, 1); // packet received
+__SINIC_REG32(Intr_All, 0xff); // all valid interrupts
+__SINIC_REG32(Intr_NoDelay, 0xcc); // interrupts that shouldn't be coalesced
+__SINIC_REG32(Intr_Res, ~0xff); // reserved interrupt bits
// RX Data Description
__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M
__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB
// TX Data Description
-__SINIC_VAL64(TxData_More, 63, 1);
-__SINIC_VAL64(TxData_Checksum, 62, 1);
+__SINIC_VAL64(TxData_More, 63, 1); // Packet not complete (will dma more)
+__SINIC_VAL64(TxData_Checksum, 62, 1); // do checksum
__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 1M
__SINIC_VAL64(TxData_Addr, 0, 40); // Address 1TB
// RX Done/Busy Information
-__SINIC_VAL64(RxDone_Complete, 63, 1);
-__SINIC_VAL64(RxDone_IpPacket, 45, 1);
-__SINIC_VAL64(RxDone_TcpPacket, 44, 1);
-__SINIC_VAL64(RxDone_UdpPacket, 43, 1);
-__SINIC_VAL64(RxDone_IpError, 42, 1);
-__SINIC_VAL64(RxDone_TcpError, 41, 1);
-__SINIC_VAL64(RxDone_UdpError, 40, 1);
-__SINIC_VAL64(RxDone_More, 32, 1);
-__SINIC_VAL64(RxDone_FifoLen, 20, 8); // up to 255 packets
+__SINIC_VAL64(RxDone_Packets, 32, 16); // number of packets in rx fifo
+__SINIC_VAL64(RxDone_Busy, 31, 1); // receive dma busy copying
+__SINIC_VAL64(RxDone_Complete, 30, 1); // valid data (packet complete)
+__SINIC_VAL64(RxDone_More, 29, 1); // Packet has more data (dma again)
+__SINIC_VAL64(RxDone_TcpError, 25, 1); // TCP packet error (bad checksum)
+__SINIC_VAL64(RxDone_UdpError, 24, 1); // UDP packet error (bad checksum)
+__SINIC_VAL64(RxDone_IpError, 23, 1); // IP packet error (bad checksum)
+__SINIC_VAL64(RxDone_TcpPacket, 22, 1); // this is a TCP packet
+__SINIC_VAL64(RxDone_UdpPacket, 21, 1); // this is a UDP packet
+__SINIC_VAL64(RxDone_IpPacket, 20, 1); // this is an IP packet
__SINIC_VAL64(RxDone_CopyLen, 0, 20); // up to 256k
// TX Done/Busy Information
-__SINIC_VAL64(TxDone_Complete, 63, 1);
-__SINIC_VAL64(TxDone_FifoLen, 20, 8); // up to 255 packets
-__SINIC_VAL64(TxDone_CopyLen, 0, 20); // up to 256k
-
-inline int
-regSize(int offset)
+__SINIC_VAL64(TxDone_Packets, 32, 16); // number of packets in tx fifo
+__SINIC_VAL64(TxDone_Busy, 31, 1); // transmit dma busy copying
+__SINIC_VAL64(TxDone_Complete, 30, 1); // valid data (packet complete)
+__SINIC_VAL64(TxDone_Full, 29, 1); // tx fifo is full
+__SINIC_VAL64(TxDone_Low, 28, 1); // tx fifo is below the watermark
+__SINIC_VAL64(TxDone_CopyLen, 0, 20); // up to 256k
+
+struct Info
{
- static const char sizes[] = {
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 4,
- 0,
- 8, 0,
- 8, 0,
- 8, 0,
- 8, 0,
- 8, 0,
- 8, 0,
- 8, 0
- };
+ uint8_t size;
+ bool read;
+ bool write;
+ const char *name;
+};
- if (offset & 0x3)
- return 0;
+/* namespace Regs */ }
- if (offset >= Size)
- return 0;
+inline const Regs::Info&
+regInfo(Addr daddr)
+{
+ static Regs::Info info [] = {
+ { 4, true, true, "Config" },
+ { 4, false, true, "Command" },
+ { 4, true, true, "IntrStatus" },
+ { 4, true, true, "IntrMask" },
+ { 4, true, false, "RxMaxCopy" },
+ { 4, true, false, "TxMaxCopy" },
+ { 4, true, false, "RxMaxIntr" },
+ { 0, false, false, "invalid" },
+ { 4, true, false, "RxFifoSize" },
+ { 4, true, false, "TxFifoSize" },
+ { 4, true, false, "RxFifoMark" },
+ { 4, true, false, "TxFifoMark" },
+ { 8, true, true, "RxData" }, { 0, false, false, "invalid" },
+ { 8, true, false, "RxDone" }, { 0, false, false, "invalid" },
+ { 8, true, false, "RxWait" }, { 0, false, false, "invalid" },
+ { 8, true, true, "TxData" }, { 0, false, false, "invalid" },
+ { 8, true, false, "TxDone" }, { 0, false, false, "invalid" },
+ { 8, true, false, "TxWait" }, { 0, false, false, "invalid" },
+ { 8, true, false, "HwAddr" }, { 0, false, false, "invalid" }
+ };
- return sizes[offset / 4];
+ return info[daddr / 4];
}
-inline const char *
-regName(int offset)
+inline bool
+regValid(Addr daddr)
{
- static const char *names[] = {
- "Config",
- "RxMaxCopy",
- "TxMaxCopy",
- "RxThreshold",
- "TxThreshold",
- "IntrStatus",
- "IntrMask",
- "invalid",
- "RxData", "invalid",
- "RxDone", "invalid",
- "RxWait", "invalid",
- "TxData", "invalid",
- "TxDone", "invalid",
- "TxWait", "invalid",
- "HwAddr", "invalid"
- };
+ if (daddr > Regs::Size)
+ return false;
- if (offset & 0x3)
- return "invalid";
+ if (regInfo(daddr).size == 0)
+ return false;
- if (offset >= Size)
- return "invalid";
-
- return names[offset / 4];
+ return true;
}
-/* namespace Regs */ }
/* namespace Sinic */ }
#endif // __DEV_SINICREG_HH__
diff --git a/kern/kernel_stats.hh b/kern/kernel_stats.hh
index 7b931ef79..62dd84a28 100644
--- a/kern/kernel_stats.hh
+++ b/kern/kernel_stats.hh
@@ -34,11 +34,12 @@
#include <string>
#include <vector>
+#include "cpu/static_inst.hh"
+
class BaseCPU;
class ExecContext;
class FnEvent;
// What does kernel stats expect is included?
-class StaticInstBase;
class System;
enum Fault;
@@ -105,7 +106,7 @@ class Binning
cpu_mode themode;
void palSwapContext(ExecContext *xc);
- void execute(ExecContext *xc, const StaticInstBase *inst);
+ void execute(ExecContext *xc, StaticInstPtr<TheISA> inst);
void call(ExecContext *xc, Stats::MainBin *myBin);
void changeMode(cpu_mode mode);
diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py
index d3e8c2811..a97e58bda 100644
--- a/python/m5/objects/Ethernet.py
+++ b/python/m5/objects/Ethernet.py
@@ -60,66 +60,51 @@ if build_env['ALPHA_TLASER']:
type = 'EtherDevInt'
device = Param.EtherDev("Ethernet device of this interface")
-class NSGigE(PciDevice):
- type = 'NSGigE'
+class EtherDevBase(PciDevice):
hardware_address = Param.EthernetAddr(NextEthernetAddr,
"Ethernet Hardware Address")
clock = Param.Clock('0ns', "State machine processor frequency")
- dma_data_free = Param.Bool(False, "DMA of Data is free")
- dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
+ physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
+
+ hier = Param.HierParams(Parent.any, "Hierarchy global variables")
+ payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
dma_no_allocate = Param.Bool(True, "Should we allocate cache on read")
-
- rx_filter = Param.Bool(True, "Enable Receive Filter")
rx_delay = Param.Latency('1us', "Receive Delay")
tx_delay = Param.Latency('1us', "Transmit Delay")
+ rx_fifo_size = Param.MemorySize('512kB', "max size of rx fifo")
+ tx_fifo_size = Param.MemorySize('512kB', "max size of tx fifo")
- rx_fifo_size = Param.MemorySize('128kB', "max size in bytes of rxFifo")
- tx_fifo_size = Param.MemorySize('128kB', "max size in bytes of txFifo")
+ rx_filter = Param.Bool(True, "Enable Receive Filter")
+ intr_delay = Param.Latency('10us', "Interrupt Propagation Delay")
+ dedicated = Param.Bool(False, "dedicate a kernel thread to the driver")
- m5reg = Param.UInt32(0, "Register for m5 usage")
+class NSGigE(EtherDevBase):
+ type = 'NSGigE'
+
+ dma_data_free = Param.Bool(False, "DMA of Data is free")
+ dma_desc_free = Param.Bool(False, "DMA of Descriptors is free")
- intr_delay = Param.Latency('0us', "Interrupt Delay in microseconds")
- payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
- physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
class NSGigEInt(EtherInt):
type = 'NSGigEInt'
device = Param.NSGigE("Ethernet device of this interface")
-class Sinic(PciDevice):
+class Sinic(EtherDevBase):
type = 'Sinic'
- hardware_address = Param.EthernetAddr(NextEthernetAddr,
- "Ethernet Hardware Address")
-
- clock = Param.Clock('100MHz', "State machine processor frequency")
-
- dma_read_delay = Param.Latency('0us', "fixed delay for dma reads")
- dma_read_factor = Param.Latency('0us', "multiplier for dma reads")
- dma_write_delay = Param.Latency('0us', "fixed delay for dma writes")
- dma_write_factor = Param.Latency('0us', "multiplier for dma writes")
- rx_filter = Param.Bool(True, "Enable Receive Filter")
- rx_delay = Param.Latency('1us', "Receive Delay")
- tx_delay = Param.Latency('1us', "Transmit Delay")
-
- rx_max_copy = Param.MemorySize('16kB', "rx max copy")
+ rx_max_copy = Param.MemorySize('1514B', "rx max copy")
tx_max_copy = Param.MemorySize('16kB', "tx max copy")
- rx_fifo_size = Param.MemorySize('64kB', "max size of rx fifo")
- tx_fifo_size = Param.MemorySize('64kB', "max size of tx fifo")
+ rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
rx_fifo_threshold = Param.MemorySize('48kB', "rx fifo high threshold")
tx_fifo_threshold = Param.MemorySize('16kB', "tx fifo low threshold")
- intr_delay = Param.Latency('0us', "Interrupt Delay in microseconds")
- payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload")
- physmem = Param.PhysicalMemory(Parent.any, "Physical Memory")
-
class SinicInt(EtherInt):
type = 'SinicInt'
device = Param.Sinic("Ethernet device of this interface")
diff --git a/sim/system.cc b/sim/system.cc
index e67cae333..f14a97603 100644
--- a/sim/system.cc
+++ b/sim/system.cc
@@ -54,6 +54,7 @@ System::System(Params *p)
kernelSymtab = new SymbolTable;
consoleSymtab = new SymbolTable;
palSymtab = new SymbolTable;
+ allSymtab = new SymbolTable;
debugSymbolTable = new SymbolTable;
/**
@@ -101,6 +102,21 @@ System::System(Params *p)
if (!pal->loadLocalSymbols(palSymtab))
panic("could not load pal symbols\n");
+ if (!kernel->loadGlobalSymbols(allSymtab))
+ panic("could not load kernel symbols\n");
+
+ if (!kernel->loadLocalSymbols(allSymtab))
+ panic("could not load kernel local symbols\n");
+
+ if (!console->loadGlobalSymbols(allSymtab))
+ panic("could not load console symbols\n");
+
+ if (!pal->loadGlobalSymbols(allSymtab))
+ panic("could not load pal symbols\n");
+
+ if (!pal->loadLocalSymbols(allSymtab))
+ panic("could not load pal symbols\n");
+
if (!kernel->loadGlobalSymbols(debugSymbolTable))
panic("could not load kernel symbols\n");
diff --git a/sim/system.hh b/sim/system.hh
index 8cfe790de..ed78eb3d4 100644
--- a/sim/system.hh
+++ b/sim/system.hh
@@ -77,6 +77,9 @@ class System : public SimObject
/** pal symbol table */
SymbolTable *palSymtab;
+ /** all symbols table */
+ SymbolTable *allSymtab;
+
/** Object pointer for the kernel code */
ObjectFile *kernel;
diff --git a/test/Makefile b/test/Makefile
index 20abe8466..6fe0e5f48 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -33,8 +33,8 @@ initest: test/initest.cc base/str.cc base/inifile.cc base/cprintf.cc
lrutest: test/lru_test.cc
$(CXX) $(CCFLAGS) -o $@ $^
-nmtest: test/nmtest.cc base/object_file.cc base/symtab.cc base/misc.cc base/str.cc
- $(CXX) $(CCFLAGS) -o $@ $^
+nmtest: test/nmtest.cc base/output.cc base/hostinfo.cc base/cprintf.cc base/misc.cc base/loader/object_file.cc base/loader/symtab.cc base/misc.cc base/str.cc base/loader/aout_object.cc base/loader/ecoff_object.cc base/loader/elf_object.cc
+ $(CXX) $(CCFLAGS) -I/n/ziff/z/binkertn/build/work/ALPHA_FS -lelf -o $@ $^
offtest: test/offtest.cc
$(CXX) $(CCFLAGS) -o $@ $^
diff --git a/test/nmtest.cc b/test/nmtest.cc
index 90166adf3..e9c20d19d 100644
--- a/test/nmtest.cc
+++ b/test/nmtest.cc
@@ -30,45 +30,53 @@
#include <string>
#include <vector>
-#include "ecoff.hh"
#include "base/loader/object_file.hh"
-#include "base/str.hh"
#include "base/loader/symtab.hh"
+#include "base/misc.hh"
+#include "base/str.hh"
+using namespace std;
Tick curTick;
+ostream *outputStream = &cout;
+
int
main(int argc, char *argv[])
{
- EcoffObject obj;
- if (argc != 3) {
- cout << "usage: " << argv[0] << " <filename> <symbol>\n";
- return 1;
- }
+ if (argc != 2 && argc != 3)
+ panic("usage: %s <filename> <symbol>\n", argv[0]);
- if (!obj.open(argv[1])) {
- cout << "file not found\n";
- return 1;
- }
+ ObjectFile *obj = createObjectFile(argv[1]);
+ if (!obj)
+ panic("file not found\n");
SymbolTable symtab;
- obj.loadGlobals(&symtab);
-
- string symbol = argv[2];
- Addr address;
+ obj->loadGlobalSymbols(&symtab);
+ obj->loadLocalSymbols(&symtab);
- if (symbol[0] == '0' && symbol[1] == 'x') {
- if (to_number(symbol, address) && symtab.findSymbol(address, symbol))
- cout << "address = 0x" << hex << address
- << ", symbol = " << symbol << "\n";
- else
- cout << "address = 0x" << hex << address << " was not found\n";
+ if (argc == 2) {
+ SymbolTable::ATable::const_iterator i = symtab.getAddrTable().begin();
+ SymbolTable::ATable::const_iterator end = symtab.getAddrTable().end();
+ while (i != end) {
+ cprintf("%#x %s\n", i->first, i->second);
+ ++i;
+ }
} else {
- if (symtab.findAddress(symbol, address))
- cout << "symbol = " << symbol << ", address = 0x" << hex
- << address << "\n";
- else
- cout << "symbol = " << symbol << " was not found\n";
+ string symbol = argv[2];
+ Addr address;
+
+ if (symbol[0] == '0' && symbol[1] == 'x') {
+ if (to_number(symbol, address) &&
+ symtab.findSymbol(address, symbol))
+ cprintf("address = %#x, symbol = %s\n", address, symbol);
+ else
+ cprintf("address = %#x was not found\n", address);
+ } else {
+ if (symtab.findAddress(symbol, address))
+ cprintf("symbol = %s address = %#x\n", symbol, address);
+ else
+ cprintf("symbol = %s was not found\n", symbol);
+ }
}
return 0;
diff --git a/util/pbs/job.py b/util/pbs/job.py
index fb375cf5d..0fd3b4f97 100755
--- a/util/pbs/job.py
+++ b/util/pbs/job.py
@@ -149,7 +149,7 @@ if __name__ == '__main__':
pbs_jobname = env['PBS_JOBNAME']
basedir = joinpath(rootdir, 'Base')
jobname = env.setdefault('JOBNAME', pbs_jobname)
- jobfile = env.setdefault('JOBFILE', joinpath(basedir, 'test.py'))
+ jobfile = env.setdefault('JOBFILE', joinpath(rootdir, 'Test.py'))
outdir = env.setdefault('OUTPUT_DIR', joinpath(rootdir, jobname))
env['POOLJOB'] = 'True'
diff --git a/util/pbs/pbs.py b/util/pbs/pbs.py
index ecacbeba2..70a0c6bed 100755
--- a/util/pbs/pbs.py
+++ b/util/pbs/pbs.py
@@ -91,19 +91,20 @@ class MyPOpen(object):
class qsub:
def __init__(self):
+ self.afterok = None
self.hold = False
self.join = False
self.keep_stdout = False
self.keep_stderr = False
- self.node_type = ''
+ self.node_type = None
self.mail_abort = False
self.mail_begin = False
self.mail_end = False
- self.name = ''
- self.stdout = ''
- self.priority = 0
- self.queue = ''
- self.pbshost = ''
+ self.name = None
+ self.stdout = None
+ self.priority = None
+ self.queue = None
+ self.pbshost = None
self.qsub = 'qsub'
self.env = {}
@@ -118,7 +119,7 @@ class qsub:
if self.hold:
self.cmd.append('-h')
- if len(self.stdout):
+ if self.stdout:
self.cmd.append('-olocalhost:' + self.stdout)
if self.keep_stdout and self.keep_stderr:
@@ -133,7 +134,7 @@ class qsub:
if self.join:
self.cmd.append('-joe')
- if len(self.node_type):
+ if self.node_type:
self.cmd.append('-lnodes=' + self.node_type)
if self.mail_abort or self.mail_begin or self.mail_end:
@@ -147,15 +148,18 @@ class qsub:
if len(flags):
self.cmd.append('-m ' + flags)
- if len(self.name):
+ if self.name:
self.cmd.append("-N%s" % self.name)
- if self.priority != 0:
+ if self.priority:
self.cmd.append('-p' + self.priority)
- if len(self.queue):
+ if self.queue:
self.cmd.append('-q' + self.queue)
+ if self.afterok:
+ self.cmd.append('-Wdepend=afterok:%s' % self.afterok)
+
self.cmd.extend(args)
self.script = script
self.command = ' '.join(self.cmd + [ self.script ])
diff --git a/util/pbs/send.py b/util/pbs/send.py
index 51eb8425e..d04f9066b 100755
--- a/util/pbs/send.py
+++ b/util/pbs/send.py
@@ -82,11 +82,11 @@ Usage:
-e only echo pbs command info, don't actually send the job
-f force the job to run regardless of state
-q <queue> submit job to the named queue
- -j <jobfile> specify the jobfile (default is <basedir>/test.py)
+ -j <jobfile> specify the jobfile (default is <rootdir>/Test.py)
-v be verbose
%(progname)s [-j <jobfile>] -l [-v] <regexp>
- -j <jobfile> specify the jobfile (default is <basedir>/test.py)
+ -j <jobfile> specify the jobfile (default is <rootdir>/Test.py)
-l list job names, don't submit
-v be verbose (list job parameters)
@@ -96,10 +96,11 @@ Usage:
try:
import getopt
- opts, args = getopt.getopt(sys.argv[1:], '-CRcd:efhj:lq:v')
+ opts, args = getopt.getopt(sys.argv[1:], '-Ccdefhj:lq:Rt:v')
except getopt.GetoptError:
sys.exit(usage)
+depend = False
clean = False
onlyecho = False
exprs = []
@@ -107,18 +108,19 @@ force = False
listonly = False
queue = ''
verbose = False
-jfile = 'Base/test.py'
+jfile = 'Test.py'
docpts = False
doruns = True
runflag = False
+node_type = 'FAST'
for opt,arg in opts:
if opt == '-C':
docpts = True
- if opt == '-R':
- runflag = True
if opt == '-c':
clean = True
+ if opt == '-d':
+ depend = True
if opt == '-e':
onlyecho = True
if opt == '-f':
@@ -132,6 +134,10 @@ for opt,arg in opts:
listonly = True
if opt == '-q':
queue = arg
+ if opt == '-R':
+ runflag = True
+ if opt == '-t':
+ node_type = arg
if opt == '-v':
verbose = True
@@ -149,6 +155,8 @@ conf = jobfile.JobFile(jfile)
if not listonly and not onlyecho and isdir(conf.linkdir):
if verbose:
print 'Checking for outdated files in Link directory'
+ if not isdir(conf.basedir):
+ os.mkdir(conf.basedir)
syncdir(conf.linkdir, conf.basedir)
jobnames = {}
@@ -237,6 +245,9 @@ namehack = NameHack()
for job in joblist:
jobdir = JobDir(joinpath(conf.rootdir, job.name))
+ if depend:
+ cptdir = JobDir(joinpath(conf.rootdir, job.checkpoint.name))
+ cptjob = cptdir.readval('.pbs_jobid')
if not onlyecho:
jobdir.create()
@@ -249,10 +260,12 @@ for job in joblist:
qsub.stdout = jobdir.file('jobout')
qsub.name = job.name[:15]
qsub.join = True
- qsub.node_type = 'FAST'
+ qsub.node_type = node_type
qsub.env['ROOTDIR'] = conf.rootdir
qsub.env['JOBNAME'] = job.name
- if len(queue):
+ if depend:
+ qsub.afterok = cptjob
+ if queue:
qsub.queue = queue
qsub.build(joinpath(progpath, 'job.py'))
diff --git a/util/qdo b/util/qdo
index 3a475b420..339d944a7 100755
--- a/util/qdo
+++ b/util/qdo
@@ -45,7 +45,11 @@ optparser.add_option('-o', dest='stdout_file',
help='command stdout output file')
optparser.add_option('-l', dest='save_log', action='store_true',
help='save qsub output log file')
-optparser.add_option('-q', dest='qsub_timeout', type='int',
+optparser.add_option('-N', dest='job_name',
+ help='qsub job name')
+optparser.add_option('-q', dest='dest_queue',
+ help='qsub destination queue')
+optparser.add_option('--qwait', dest='qsub_timeout', type='int',
help='qsub queue wait timeout', default=30*60)
optparser.add_option('-t', dest='cmd_timeout', type='int',
help='command execution timeout', default=600*60)
@@ -56,6 +60,12 @@ if cmd == []:
print >>sys.stderr, "%s: missing command" % progname
sys.exit(1)
+# If we want to do this, need to add check here to make sure cmd[0] is
+# a valid PBS job name, else qsub will die on us.
+#
+#if not options.job_name:
+# options.job_name = cmd[0]
+
cwd = os.getcwd()
# Deal with systems where /n is a symlink to /.automount
@@ -137,6 +147,10 @@ if False and len(cmd) > 50:
print "%s: running %s on poolfs" % (progname, cmd[0])
else:
shell_cmd = 'qsub -I -S /bin/sh'
+ if options.job_name:
+ shell_cmd += ' -N "%s"' % options.job_name
+ if options.dest_queue:
+ shell_cmd += ' -q ' + options.dest_queue
shell = Shell(shell_cmd)
diff --git a/util/stats/categories.py b/util/stats/categories.py
index 0c359b856..8d5d506a2 100644
--- a/util/stats/categories.py
+++ b/util/stats/categories.py
@@ -26,7 +26,95 @@
#
# Authors: Nathan Binkert
-categories = {
+func_categories = { \
+ # Buffer management functions
+ '__skb_linearize' : 'buffer',
+ 'skb_clone' : 'buffer',
+ 'skb_clone_fraglist' : 'buffer',
+ 'skb_seq_read' : 'buffer',
+ 'sock_alloc_send_skb' : 'buffer',
+
+ # Copy functions
+ '__copy_user' : 'copy',
+ 'skb_copy_bits' : 'copy',
+
+ # Driver functions
+ 'do_tx_done' : 'driver',
+ 'ns83820_get_drvinfo' : 'driver',
+ 'ns83820_get_stats' : 'driver',
+ 'ns83820_hard_start_xmit' : 'driver',
+ 'ns83820_open' : 'driver',
+ 'ns83820_rx_kick' : 'driver',
+ 'ns83820_update_stats' : 'driver',
+ 'ns83820_irq' : 'driver',
+ 'phy_intr' : 'driver',
+ 'rx_irq' : 'driver',
+ 'rx_action' : 'driver',
+ 'sinic_intr' : 'driver',
+ 'sinic_xmit' : 'driver',
+ 'sinic_rxskb_new' : 'driver',
+
+ # Idle functions
+ 'cpu_idle' : 'idle',
+
+ # Interrupt functions
+ 'do_entInt' : 'interrupt',
+ 'entInt' : 'interrupt',
+ 'handle_IRQ_event' : 'interrupt',
+ 'irq_exit' : 'interrupt',
+
+ # Other functions
+ 'ret_from_sys_call' : 'other',
+ 'top' : 'other',
+
+ # Stack functions
+ '__ip_conntrack_confirm' : 'stack',
+ '__ip_conntrack_find' : 'stack',
+ '__tcp_ack_snd_check' : 'stack',
+ '__tcp_checksum_complete_user' : 'stack',
+ 'dev_queue_xmit' : 'stack',
+ 'eth_header_cache' : 'stack',
+ 'ether_setup' : 'stack',
+ 'icmp_error' : 'stack',
+ 'ip_call_ra_chain' : 'stack',
+ 'ip_conntrack_alter_reply' : 'stack',
+ 'ip_conntrack_tcp_update' : 'stack',
+ 'ip_ct_find_helper' : 'stack',
+ 'ip_finish_output' : 'stack',
+ 'ip_finish_output2' : 'stack',
+ 'ip_local_deliver_finish' : 'stack',
+ 'ip_nat_setup_info' : 'stack',
+ 'ip_rcv' : 'stack',
+ 'ip_rcv_finish' : 'stack',
+ 'netif_receive_skb' : 'stack',
+ 'nf_log_packet' : 'stack',
+ 'nf_queue' : 'stack',
+ 'tcp_connect' : 'stack',
+ 'tcp_data_queue' : 'stack',
+ 'tcp_packet' : 'stack',
+ 'tcp_read_sock' : 'stack',
+ 'tcp_rcv_established' : 'stack',
+ 'tcp_recvmsg' : 'stack',
+ 'tcp_sendpage' : 'stack',
+ 'tcp_transmit_skb' : 'stack',
+ 'tcp_v4_do_rcv' : 'stack',
+ 'unregister_netdevice' : 'stack',
+
+ # Syscall functions
+ 'entSys' : 'syscall',
+
+ # User functions
+ 'user' : 'user',
+ }
+
+def func_categorize(symbol):
+ from categories import func_categories
+ if symbol in func_categories:
+ return func_categories[symbol]
+ return None
+
+
+pc_categories = {
'CALL_PALrdunique_' : 'interrupt', #
'Call_Pal_Callsys' : 'interrupt', #
'Call_Pal_Rdps' : 'interrupt', #
@@ -37,15 +125,15 @@ categories = {
'Call_Pal_Wrusp' : 'interrupt', #
'SHATransform': 'driver', # drivers/char/random.c,
'TRAP_INTERRUPT_10_' : 'interrupt', #
- 'Trap_Dtbmiss_Single' : 'bufmgt', #
- 'Trap_Dtbmiss_double' : 'bufmgt', #
+ 'Trap_Dtbmiss_Single' : 'buffer', #
+ 'Trap_Dtbmiss_double' : 'buffer', #
'Trap_Interrupt' : 'interrupt', #
- 'Trap_Itbmiss' : 'bufmgt', #
+ 'Trap_Itbmiss' : 'buffer', #
'Trap_Unalign' : 'alignment',
'UNALIGN_NO_DISMISS' : 'alignment',
'UNALIGN_NO_DISMISS_10_' : 'alignment',
- '__alloc_pages' : 'bufmgt', # mm/page_alloc.c,
- '__anon_vma_link': 'bufmgt', # mm/rmap.c, include/linux/rmap.h,
+ '__alloc_pages' : 'buffer', # mm/page_alloc.c,
+ '__anon_vma_link': 'buffer', # mm/rmap.c, include/linux/rmap.h,
'__bio_add_page' : 'other', # fs/bio.c,
'__bitmap_weight' : 'other', # lib/bitmap.c, include/linux/bitmap.h,
'__blk_put_request' : 'other', # drivers/block/ll_rw_blk.c,
@@ -78,17 +166,17 @@ categories = {
'__end_that_request_first' : 'other', # drivers/block/ll_rw_blk.c,
'__exit_sighand': 'other', # kernel/signal.c, include/linux/sched.h,
'__exit_signal': 'other', # kernel/signal.c, include/linux/sched.h,
- '__filemap_copy_from_user_iovec' : 'bufmgt', # mm/filemap.c,
- '__filemap_fdatawrite' : 'bufmgt', # mm/filemap.c,
+ '__filemap_copy_from_user_iovec' : 'buffer', # mm/filemap.c,
+ '__filemap_fdatawrite' : 'buffer', # mm/filemap.c,
'__find_get_block' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
'__find_get_block_slow' : 'other', # fs/buffer.c,
'__fput' : 'other', # fs/file_table.c,
- '__free_pages' : 'bufmgt', # mm/page_alloc.c,
- '__free_pages_ok': 'bufmgt', # mm/page_alloc.c,
- '__generic_file_aio_read': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
+ '__free_pages' : 'buffer', # mm/page_alloc.c,
+ '__free_pages_ok': 'buffer', # mm/page_alloc.c,
+ '__generic_file_aio_read': 'buffer', # mm/filemap.c, include/linux/fs.h,
'__generic_unplug_device' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'__get_free_pages' : 'other', # mm/page_alloc.c, drivers/md/raid6.h,
- '__get_page_state': 'bufmgt', # mm/page_alloc.c,
+ '__get_page_state': 'buffer', # mm/page_alloc.c,
'__get_user_4': 'other', # include/asm-i386/uaccess.h,
'__get_zone_counts': 'other', #
'__getblk' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
@@ -97,17 +185,17 @@ categories = {
'__group_send_sig_info' : 'user', # kernel/signal.c, is kinda syscall
'__iget' : 'other', # fs/inode.c, include/linux/fs.h,
'__insert_inode_hash': 'other', # fs/inode.c, include/linux/fs.h,
- '__insert_vm_struct': 'bufmgt', # mm/mmap.c,
+ '__insert_vm_struct': 'buffer', # mm/mmap.c,
'__ip_conntrack_confirm' : 'stack', # net/ipv4/netfilter/ip_conntrack_core.c, include/linux/netfilter_ipv4/ip_conntrack_core.h,
'__ip_conntrack_find' : 'stack', # net/ipv4/netfilter/ip_conntrack_core.c,
'__ip_ct_find_proto' : 'stack', # net/ipv4/netfilter/ip_conntrack_core.c, include/linux/netfilter_ipv4/ip_conntrack_core.h,
'__ip_route_output_key' : 'stack', # net/ipv4/route.c,
- '__kfree_skb' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
- '__kmalloc' : 'bufmgt', # mm/slab.c, include/linux/slab.h,
- '__load_new_mm_context': 'bufmgt',
+ '__kfree_skb' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
+ '__kmalloc' : 'buffer', # mm/slab.c, include/linux/slab.h,
+ '__load_new_mm_context': 'buffer',
'__lookup': 'other', # lib/radix-tree.c,
'__lookup_hash': 'other', # fs/namei.c,
- '__lookup_tag' : 'bufmgt', # lib/radix-tree.c,
+ '__lookup_tag' : 'buffer', # lib/radix-tree.c,
'__make_request' : 'driver', # drivers/block/ll_rw_blk.c, drivers/block/ll_rw_blk.c,
'__mark_inode_dirty' : 'other', # fs/fs-writeback.c, include/linux/fs.h,
'__memcpy_aligned_up' : 'copy', # arch/alpha/lib/memcpy.c,
@@ -117,31 +205,31 @@ categories = {
'__mod_timer' : 'other', # kernel/timer.c, include/linux/timer.h,
'__modify_IO_APIC_irq': 'interrupt', #
'__net_random': 'other', #
- '__page_cache_release' : 'bufmgt', # mm/swap.c,
- '__pagevec_free': 'bufmgt', # mm/page_alloc.c, include/linux/pagevec.h,
- '__pagevec_lru_add' : 'bufmgt', # mm/swap.c, include/linux/pagevec.h,
- '__pagevec_lru_add_active': 'bufmgt', # mm/swap.c, include/linux/pagevec.h,
- '__pagevec_release' : 'bufmgt', # mm/swap.c, include/linux/pagevec.h,
+ '__page_cache_release' : 'buffer', # mm/swap.c,
+ '__pagevec_free': 'buffer', # mm/page_alloc.c, include/linux/pagevec.h,
+ '__pagevec_lru_add' : 'buffer', # mm/swap.c, include/linux/pagevec.h,
+ '__pagevec_lru_add_active': 'buffer', # mm/swap.c, include/linux/pagevec.h,
+ '__pagevec_release' : 'buffer', # mm/swap.c, include/linux/pagevec.h,
'__pollwait' : 'other', # fs/select.c, fs/select.c,
'__pskb_trim_head': 'stack', # net/ipv4/tcp_output.c,
'__put_task_struct': 'other', # kernel/fork.c, include/linux/sched.h,
'__queue_work': 'other', # kernel/workqueue.c,
- '__rb_erase_color' : 'bufmgt', # lib/rbtree.c,
- '__rb_rotate_left' : 'bufmgt', # lib/rbtree.c,
- '__rb_rotate_right' : 'bufmgt', # lib/rbtree.c,
+ '__rb_erase_color' : 'buffer', # lib/rbtree.c,
+ '__rb_rotate_left' : 'buffer', # lib/rbtree.c,
+ '__rb_rotate_right' : 'buffer', # lib/rbtree.c,
'__rcu_process_callbacks': 'other', #
- '__read_page_state' : 'bufmgt', # mm/page_alloc.c, include/linux/page-flags.h,
+ '__read_page_state' : 'buffer', # mm/page_alloc.c, include/linux/page-flags.h,
'__release_sock' : 'stack', # net/core/sock.c,
'__remlu' : 'other', # arch/alpha/kernel/alpha_ksyms.c,
- '__remove_from_page_cache': 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- '__remove_shared_vm_struct': 'bufmgt', # mm/mmap.c,
+ '__remove_from_page_cache': 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ '__remove_shared_vm_struct': 'buffer', # mm/mmap.c,
'__remqu' : 'other', # arch/alpha/kernel/alpha_ksyms.c,
- '__rmqueue' : 'bufmgt', # mm/page_alloc.c,
+ '__rmqueue' : 'buffer', # mm/page_alloc.c,
'__scsi_done' : 'other', # drivers/scsi/scsi.c, drivers/scsi/scsi_priv.h,
'__scsi_get_command' : 'other', # drivers/scsi/scsi.c,
'__set_page_buffers' : 'other', # fs/buffer.c,
- '__set_page_dirty_nobuffers' : 'bufmgt', # mm/page-writeback.c, include/linux/mm.h,
- '__sk_stream_mem_reclaim' : 'bufmgt', # net/core/stream.c,
+ '__set_page_dirty_nobuffers' : 'buffer', # mm/page-writeback.c, include/linux/mm.h,
+ '__sk_stream_mem_reclaim' : 'buffer', # net/core/stream.c,
'__sock_create': 'stack', # net/socket.c,
'__strncpy_from_user' : 'copy', # include/asm-alpha/uaccess.h,
'__strnlen_user': 'user',
@@ -160,8 +248,8 @@ categories = {
'__up_wakeup' : 'interrupt', # arch/alpha/kernel/semaphore.c, include/asm-alpha/semaphore.h,
'__user_walk' : 'other', # fs/namei.c,
'__vm_stat_account': 'other', #
- '__vma_link': 'bufmgt', # mm/mmap.c,
- '__vma_link_rb': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ '__vma_link': 'buffer', # mm/mmap.c,
+ '__vma_link_rb': 'buffer', # mm/mmap.c, include/linux/mm.h,
'__wait_on_buffer' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
'__wake_up' : 'other', # kernel/sched.c,
'__wake_up_common' : 'other', # kernel/sched.c,
@@ -172,13 +260,13 @@ categories = {
'acct_process': 'other', # kernel/acct.c, include/linux/acct.h, include/linux/acct.h,
'ack_edge_ioapic_irq': 'interrupt', #
'ack_edge_ioapic_vector': 'interrupt', #
- 'activate_page' : 'bufmgt', # mm/swap.c,
+ 'activate_page' : 'buffer', # mm/swap.c,
'activate_task' : 'other', # kernel/sched.c,
'add_disk_randomness' : 'other', # drivers/char/random.c, include/linux/genhd.h,
'add_interrupt_randomness': 'driver', # drivers/char/random.c, include/linux/random.h,
'add_timer_randomness' : 'driver', # drivers/char/random.c,
- 'add_to_page_cache' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'add_to_page_cache_lru' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
+ 'add_to_page_cache' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'add_to_page_cache_lru' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
'add_wait_queue' : 'other', # kernel/fork.c,
'add_wait_queue_exclusive' : 'other', # kernel/fork.c,
'aligned' : 'other', #
@@ -187,16 +275,16 @@ categories = {
'alloc_fd_array': 'other', # fs/file.c, include/linux/file.h,
'alloc_inode' : 'other', # fs/inode.c,
'alloc_pidmap': 'other', # kernel/pid.c, include/linux/pid.h,
- 'alloc_skb' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
- 'alloc_slabmgmt' : 'bufmgt', # mm/slab.c,
+ 'alloc_skb' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
+ 'alloc_slabmgmt' : 'buffer', # mm/slab.c,
'alpha_switch_to' : 'other', # include/asm-alpha/system.h,
- 'anon_vma_link': 'bufmgt', # mm/rmap.c, include/linux/rmap.h, include/linux/rmap.h,
- 'anon_vma_prepare': 'bufmgt', # mm/rmap.c, include/linux/rmap.h, include/linux/rmap.h,
- 'anon_vma_unlink': 'bufmgt', # mm/rmap.c, include/linux/rmap.h,
+ 'anon_vma_link': 'buffer', # mm/rmap.c, include/linux/rmap.h, include/linux/rmap.h,
+ 'anon_vma_prepare': 'buffer', # mm/rmap.c, include/linux/rmap.h, include/linux/rmap.h,
+ 'anon_vma_unlink': 'buffer', # mm/rmap.c, include/linux/rmap.h,
'apache': 'other', #
'apic_timer_interrupt': 'interrupt', # include/asm-i386/hw_irq.h,
- 'arch_get_unmapped_area': 'bufmgt',
- 'arch_get_unmapped_area_1': 'bufmgt',
+ 'arch_get_unmapped_area': 'buffer',
+ 'arch_get_unmapped_area_1': 'buffer',
'arch_get_unmapped_area_topdown': 'other', #
'arch_pick_mmap_layout': 'other', #
'arch_unmap_area_topdown': 'other', #
@@ -241,9 +329,9 @@ categories = {
'auth_domain_drop' : 'other', # net/sunrpc/svcauth.c,
'auth_domain_put' : 'other', # net/sunrpc/svcauth.c, include/linux/sunrpc/svcauth.h,
'autoremove_wake_function' : 'other', # kernel/fork.c, include/linux/wait.h,
- 'bad_range' : 'bufmgt', # mm/page_alloc.c,
- 'balance_dirty_pages' : 'bufmgt', # mm/page-writeback.c,
- 'balance_dirty_pages_ratelimited' : 'bufmgt', # mm/page-writeback.c, include/linux/writeback.h,
+ 'bad_range' : 'buffer', # mm/page_alloc.c,
+ 'balance_dirty_pages' : 'buffer', # mm/page-writeback.c,
+ 'balance_dirty_pages_ratelimited' : 'buffer', # mm/page-writeback.c, include/linux/writeback.h,
'basename': 'other', #
'bash': 'other', #
'batch_entropy_store' : 'interrupt', # drivers/char/random.c, include/linux/random.h,
@@ -264,7 +352,7 @@ categories = {
'blk_hw_contig_segment' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'blk_phys_contig_segment' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'blk_plug_device' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
- 'blk_queue_bounce' : 'bufmgt', # mm/highmem.c, include/linux/blkdev.h,
+ 'blk_queue_bounce' : 'buffer', # mm/highmem.c, include/linux/blkdev.h,
'blk_recount_segments' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'blk_remove_plug' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'blk_rq_map_sg' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
@@ -276,18 +364,18 @@ categories = {
'block_write_full_page': 'other', # fs/buffer.c, include/linux/buffer_head.h,
'bmap': 'other', # fs/jfs/jfs_dmap.h, fs/inode.c, include/linux/fs.h,
'buffer_insert_list' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
- 'buffered_rmqueue' : 'bufmgt', # mm/page_alloc.c,
- 'cache_alloc_refill' : 'bufmgt', # mm/slab.c,
+ 'buffered_rmqueue' : 'buffer', # mm/page_alloc.c,
+ 'cache_alloc_refill' : 'buffer', # mm/slab.c,
'cache_check' : 'other', # net/sunrpc/cache.c, include/linux/sunrpc/cache.h,
- 'cache_flusharray' : 'bufmgt', # mm/slab.c,
- 'cache_grow' : 'bufmgt', # mm/slab.c,
- 'cache_init_objs' : 'bufmgt', # mm/slab.c,
- 'cache_reap': 'bufmgt', # mm/slab.c,
+ 'cache_flusharray' : 'buffer', # mm/slab.c,
+ 'cache_grow' : 'buffer', # mm/slab.c,
+ 'cache_init_objs' : 'buffer', # mm/slab.c,
+ 'cache_reap': 'buffer', # mm/slab.c,
'cached_lookup': 'other', # fs/namei.c,
'call_rcu' : 'other', # kernel/rcupdate.c,
- 'can_share_swap_page': 'bufmgt', # mm/swapfile.c, include/linux/swap.h, include/linux/swap.h,
- 'can_vma_merge_after': 'bufmgt', # mm/mmap.c,
- 'can_vma_merge_before': 'bufmgt', # mm/mmap.c,
+ 'can_share_swap_page': 'buffer', # mm/swapfile.c, include/linux/swap.h, include/linux/swap.h,
+ 'can_vma_merge_after': 'buffer', # mm/mmap.c,
+ 'can_vma_merge_before': 'buffer', # mm/mmap.c,
'capable': 'other',
'cascade' : 'interrupt', # kernel/timer.c,
'cat': 'other', #
@@ -297,9 +385,9 @@ categories = {
'chrdev_open': 'other', # fs/char_dev.c, include/linux/fs.h,
'cleanup_rbuf' : 'stack', # net/ipv4/tcp.c,
'clear_inode' : 'other', # fs/inode.c, include/linux/fs.h,
- 'clear_page' : 'bufmgt', # include/asm-alpha/page.h,
- 'clear_page_dirty_for_io' : 'bufmgt', # mm/page-writeback.c, include/linux/mm.h,
- 'clear_page_tables': 'bufmgt', # mm/memory.c, include/linux/mm.h,
+ 'clear_page' : 'buffer', # include/asm-alpha/page.h,
+ 'clear_page_dirty_for_io' : 'buffer', # mm/page-writeback.c, include/linux/mm.h,
+ 'clear_page_tables': 'buffer', # mm/memory.c, include/linux/mm.h,
'clear_queue_congested' : 'other', # drivers/block/ll_rw_blk.c,
'clear_user': 'other', # include/asm-alpha/uaccess.h, include/asm-i386/uaccess.h,
'clock_panelapplet.so': 'other', #
@@ -317,14 +405,14 @@ categories = {
'copy_mm': 'other', # kernel/fork.c,
'copy_namespace': 'other', # fs/namespace.c, include/linux/namespace.h,
'copy_page': 'copy',
- 'copy_page_range': 'bufmgt', # mm/memory.c, include/linux/mm.h,
+ 'copy_page_range': 'buffer', # mm/memory.c, include/linux/mm.h,
'copy_process': 'other', # kernel/fork.c, include/linux/sched.h,
'copy_semundo': 'other', # ipc/sem.c, include/linux/sem.h,
'copy_strings': 'other', # fs/exec.c, include/linux/binfmts.h,
'copy_strings_kernel': 'other', # fs/exec.c, include/linux/binfmts.h,
'copy_thread': 'syscall', # arch/alpha/kernel/process.c, include/linux/sched.h,
'copy_to_user': 'copy', # include/asm-alpha/uaccess.h, include/asm-i386/uaccess.h,
- 'copy_vma': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'copy_vma': 'buffer', # mm/mmap.c, include/linux/mm.h,
'count': 'driver', # fs/exec.c, init/initramfs.c, drivers/char/serial_tx3912.c, drivers/char/rocket.c, drivers/isdn/hardware/eicon/diva_didd.c, drivers/isdn/hardware/eicon/divasmain.c, drivers/isdn/hardware/eicon/divasmain.c, drivers/isdn/hardware/eicon/capimain.c, drivers/isdn/hardware/eicon/divasi.c, drivers/isdn/hardware/eicon/divasi.c, drivers/isdn/hardware/eicon/divasi.c, drivers/isdn/hardware/eicon/divasi.c, drivers/isdn/hardware/eicon/divasi.c, drivers/isdn/hardware/eicon/divamnt.c, drivers/isdn/hardware/eicon/divamnt.c, drivers/isdn/hardware/eicon/divamnt.c, drivers/isdn/hardware/eicon/divamnt.c, drivers/isdn/hardware/eicon/divamnt.c, drivers/media/video/w9966.c, drivers/media/video/w9966.c,
'count_open_files': 'other', # kernel/fork.c,
'cp_new_stat' : 'other', # fs/stat.c,
@@ -366,7 +454,7 @@ categories = {
'destroy_context': 'interrupt', # include/asm-alpha/mmu_context.h, include/asm-i386/mmu_context.h,
'destroy_inode' : 'other', # fs/inode.c, include/linux/fs.h,
'detach_pid': 'other', # kernel/pid.c,
- 'detach_vmas_to_be_unmapped': 'bufmgt', # mm/mmap.c,
+ 'detach_vmas_to_be_unmapped': 'buffer', # mm/mmap.c,
'dev_queue_xmit' : 'stack', # net/core/dev.c, include/linux/netdevice.h,
'dev_shutdown' : 'stack', # net/sched/sch_generic.c,
'dev_watchdog': 'stack', # net/sched/sch_generic.c,
@@ -376,9 +464,9 @@ categories = {
'dnotify_flush' : 'other', # fs/dnotify.c, include/linux/dnotify.h,
'dnotify_parent' : 'other', # fs/dnotify.c, include/linux/dnotify.h,
'do_IRQ': 'driver', # drivers/s390/cio/cio.c,
- 'do_anonymous_page' : 'bufmgt', # mm/memory.c,
+ 'do_anonymous_page' : 'buffer', # mm/memory.c,
'do_bindings' : 'stack', # net/ipv4/netfilter/ip_nat_core.c, include/linux/netfilter_ipv4/ip_nat_core.h,
- 'do_brk': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'do_brk': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
'do_csum_partial_copy_from_user' : 'copy', # arch/alpha/lib/csum_partial_copy.c,
'do_entInt' : 'interrupt', # arch/alpha/kernel/irq_alpha.c,
'do_entUna': 'alignment',
@@ -387,21 +475,21 @@ categories = {
'do_fcntl' : 'user', # fs/fcntl.c, used to be syscall`
'do_fork': 'other', # kernel/fork.c, include/linux/sched.h,
'do_futex': 'other', # kernel/futex.c, include/linux/futex.h,
- 'do_generic_mapping_read': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
+ 'do_generic_mapping_read': 'buffer', # mm/filemap.c, include/linux/fs.h,
'do_gettimeofday' : 'user', # arch/alpha/kernel/time.c, include/linux/time.h, used to by syscall
'do_group_exit': 'other', # kernel/exit.c, include/linux/sched.h,
- 'do_invalidatepage': 'bufmgt', # mm/truncate.c,
+ 'do_invalidatepage': 'buffer', # mm/truncate.c,
'do_lookup' : 'user', # fs/namei.c, used to by syscall
- 'do_mmap_pgoff': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'do_mmap_pgoff': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
'do_mpage_readpage': 'other', # fs/mpage.c,
- 'do_mremap': 'bufmgt', # mm/mremap.c,
- 'do_munmap': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'do_mremap': 'buffer', # mm/mremap.c,
+ 'do_munmap': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
'do_no_page' : 'user', # mm/memory.c, used to by syscall
'do_nosym': 'other', #
'do_notify_parent': 'other', # kernel/signal.c, include/linux/sched.h,
'do_notify_resume': 'interrupt', # arch/alpha/kernel/signal.c,
'do_osf_sigprocmask' : 'user', # arch/alpha/kernel/signal.c, used to by syscall
- 'do_page_cache_readahead': 'bufmgt', # mm/readahead.c, include/linux/mm.h,
+ 'do_page_cache_readahead': 'buffer', # mm/readahead.c, include/linux/mm.h,
'do_page_fault' : 'user', # arch/alpha/mm/fault.c, used to by syscall
'do_pipe': 'syscall', # fs/pipe.c, arch/alpha/kernel/osf_sys.c, include/linux/fs.h,
'do_poll' : 'user', # fs/select.c, drivers/macintosh/apm_emu.c, used to by syscall
@@ -424,15 +512,15 @@ categories = {
'do_truncate': 'other', # fs/open.c, include/linux/fs.h,
'do_tx_done' : 'driver', # drivers/net/ns83820.c,
'do_wait': 'other', #
- 'do_wp_page': 'bufmgt', # mm/memory.c,
- 'do_writepages' : 'bufmgt', # mm/page-writeback.c, include/linux/writeback.h,
+ 'do_wp_page': 'buffer', # mm/memory.c,
+ 'do_writepages' : 'buffer', # mm/page-writeback.c, include/linux/writeback.h,
'done' : 'other', # drivers/usb/gadget/net2280.c, drivers/usb/gadget/goku_udc.c, drivers/usb/gadget/pxa2xx_udc.c, drivers/scsi/aha152x.c, drivers/scsi/aha152x.c, include/linux/wavefront.h,
'dp264_disable_irq' : 'interrupt', # arch/alpha/kernel/sys_dp264.c,
'dp264_enable_irq' : 'interrupt', # arch/alpha/kernel/sys_dp264.c,
'dp264_end_irq' : 'interrupt', # arch/alpha/kernel/sys_dp264.c,
'dp264_srm_device_interrupt' : 'interrupt', # arch/alpha/kernel/sys_dp264.c,
'dput' : 'other', # fs/dcache.c, include/linux/dcache.h,
- 'drain_array_locked': 'bufmgt', # mm/slab.c, mm/slab.c,
+ 'drain_array_locked': 'buffer', # mm/slab.c, mm/slab.c,
'drive_stat_acct' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'drop_buffers': 'other', # fs/buffer.c,
'drop_key_refs': 'other', # kernel/futex.c,
@@ -493,7 +581,7 @@ categories = {
'end_edge_ioapic_vector': 'other', # include/asm-i386/io_apic.h,
'end_level_ioapic_irq': 'interrupt', #
'end_level_ioapic_vector': 'interrupt', #
- 'end_page_writeback' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
+ 'end_page_writeback' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
'end_that_request_chunk' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'end_that_request_first': 'driver', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'end_that_request_last' : 'other', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
@@ -506,14 +594,14 @@ categories = {
'error_code': 'other', #
'eth_header' : 'stack', # net/ethernet/eth.c, include/linux/etherdevice.h,
'eth_type_trans' : 'stack', # net/ethernet/eth.c, include/linux/etherdevice.h,
- 'ev5_flush_tlb_current_page': 'bufmgt',
+ 'ev5_flush_tlb_current_page': 'buffer',
'ev5_switch_mm' : 'other', # include/asm-alpha/mmu_context.h,
'eventpoll_init_file' : 'other', # fs/eventpoll.c, include/linux/eventpoll.h,
'exec_mmap': 'other', # fs/exec.c,
'exim4': 'other', #
'exit_aio': 'other', # fs/aio.c,
'exit_itimers': 'other', # kernel/posix-timers.c, include/linux/sched.h,
- 'exit_mmap': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'exit_mmap': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
'exit_notify': 'other', # kernel/exit.c,
'exit_sem': 'other', # ipc/sem.c, include/linux/sem.h, include/linux/sem.h,
'exp_find_key' : 'other', # fs/nfsd/export.c, include/linux/nfsd/export.h,
@@ -521,7 +609,7 @@ categories = {
'exp_readunlock' : 'other', # fs/nfsd/export.c, include/linux/nfsd/export.h,
'expand_fd_array': 'other', # fs/file.c, include/linux/file.h,
'expand_files': 'other', # fs/fcntl.c,
- 'expand_stack': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'expand_stack': 'buffer', # mm/mmap.c, include/linux/mm.h,
'expkey_put' : 'other', # fs/nfsd/export.c, include/linux/nfsd/export.h,
'export_decode_fh' : 'other', # fs/exportfs/expfs.c,
'export_iget' : 'other', # fs/exportfs/expfs.c,
@@ -559,11 +647,11 @@ categories = {
'file_ioctl': 'other', # fs/ioctl.c,
'file_kill' : 'other', # fs/file_table.c, include/linux/fs.h,
'file_move': 'other', # fs/file_table.c, include/linux/fs.h,
- 'file_ra_state_init': 'bufmgt', # mm/readahead.c, include/linux/fs.h,
- 'file_read_actor': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'filemap_fdatawait' : 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'filemap_fdatawrite' : 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'filemap_nopage': 'bufmgt', # mm/filemap.c, include/linux/mm.h,
+ 'file_ra_state_init': 'buffer', # mm/readahead.c, include/linux/fs.h,
+ 'file_read_actor': 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'filemap_fdatawait' : 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'filemap_fdatawrite' : 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'filemap_nopage': 'buffer', # mm/filemap.c, include/linux/mm.h,
'filesystems_read_proc': 'other', # fs/proc/proc_misc.c,
'filp_close' : 'other', # fs/open.c, include/linux/fs.h,
'filp_open' : 'other', # fs/open.c, include/linux/fs.h,
@@ -571,24 +659,24 @@ categories = {
'find_busiest_group' : 'other', # kernel/sched.c,
'find_dcookie': 'other', # fs/dcookies.c,
'find_exported_dentry' : 'other', # fs/exportfs/expfs.c, fs/nfsd/export.c,
- 'find_extend_vma': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
- 'find_get_page' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'find_get_pages': 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'find_get_pages_tag' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_extend_vma': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'find_get_page' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_get_pages': 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_get_pages_tag' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
'find_inode_fast' : 'other', # fs/inode.c,
'find_inode_number' : 'other', # fs/dcache.c, include/linux/fs.h,
- 'find_lock_page' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'find_mergeable_anon_vma': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'find_lock_page' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_mergeable_anon_vma': 'buffer', # mm/mmap.c, include/linux/mm.h,
'find_nat_proto' : 'stack', # net/ipv4/netfilter/ip_nat_core.c, include/linux/netfilter_ipv4/ip_nat_protocol.h,
'find_next_zero_bit': 'other', # include/asm-alpha/bitops.h, include/asm-i386/bitops.h,
- 'find_or_create_page' : 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_or_create_page' : 'buffer', # mm/filemap.c, include/linux/pagemap.h,
'find_pid' : 'user', # kernel/pid.c, used to be syscall
'find_snap_client': 'stack', # net/802/psnap.c,
'find_task_by_pid' : 'user', # kernel/pid.c, include/linux/sched.h, used to be syscall
'find_task_by_pid_type': 'other', #
- 'find_vma' : 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h, used to be syscall
- 'find_vma_prepare': 'bufmgt', # mm/mmap.c,
- 'find_vma_prev': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'find_vma' : 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h, used to be syscall
+ 'find_vma_prepare': 'buffer', # mm/mmap.c,
+ 'find_vma_prev': 'buffer', # mm/mmap.c, include/linux/mm.h,
'finish_task_switch' : 'other', # kernel/sched.c, used to be syscall
'finish_wait' : 'other', # kernel/fork.c, used to be syscall
'flush_old_exec': 'other', # fs/exec.c, include/linux/binfmts.h,
@@ -599,15 +687,15 @@ categories = {
'follow_mount' : 'user', # fs/namei.c, used to be syscall
'found' : 'other', # sound/oss/forte.c, scripts/kconfig/gconf.c, drivers/net/fec.c, drivers/scsi/ibmmca.c, drivers/scsi/fd_mcs.c,
'fput' : 'user', # fs/file_table.c, used to be syscall
- 'free_block' : 'bufmgt', # mm/slab.c, drivers/char/drm/radeon_mem.c, mm/slab.c,
+ 'free_block' : 'buffer', # mm/slab.c, drivers/char/drm/radeon_mem.c, mm/slab.c,
'free_buffer_head': 'other', # fs/buffer.c, include/linux/buffer_head.h,
'free_fd_array': 'other', # fs/file.c, include/linux/file.h,
- 'free_hot_cold_page' : 'bufmgt', # mm/page_alloc.c,
- 'free_hot_page' : 'bufmgt', # mm/page_alloc.c,
- 'free_page_and_swap_cache': 'bufmgt', # mm/swap_state.c, include/linux/swap.h, include/linux/swap.h,
- 'free_pages' : 'bufmgt', # mm/page_alloc.c, drivers/char/drm/drm_memory_debug.h, drivers/md/raid6.h, drivers/char/drm/drmP.h,
- 'free_pages_bulk': 'bufmgt', # mm/page_alloc.c,
- 'free_pgtables': 'bufmgt', # mm/mmap.c,
+ 'free_hot_cold_page' : 'buffer', # mm/page_alloc.c,
+ 'free_hot_page' : 'buffer', # mm/page_alloc.c,
+ 'free_page_and_swap_cache': 'buffer', # mm/swap_state.c, include/linux/swap.h, include/linux/swap.h,
+ 'free_pages' : 'buffer', # mm/page_alloc.c, drivers/char/drm/drm_memory_debug.h, drivers/md/raid6.h, drivers/char/drm/drmP.h,
+ 'free_pages_bulk': 'buffer', # mm/page_alloc.c,
+ 'free_pgtables': 'buffer', # mm/mmap.c,
'free_pidmap': 'other', # kernel/pid.c,
'free_task': 'other', # kernel/fork.c,
'free_uid' : 'other', # kernel/user.c, include/linux/sched.h,
@@ -620,12 +708,12 @@ categories = {
'generic_commit_write' : 'user', # fs/buffer.c, include/linux/buffer_head.h, used to be syscall
'generic_delete_inode': 'other', # fs/inode.c, include/linux/fs.h,
'generic_drop_inode' : 'user', # fs/inode.c, used to be syscall
- 'generic_file_aio_read': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'generic_file_aio_write': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
+ 'generic_file_aio_read': 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'generic_file_aio_write': 'buffer', # mm/filemap.c, include/linux/fs.h,
'generic_file_aio_write_nolock' : 'user', # mm/filemap.c, include/linux/fs.h, used to be syscall
'generic_file_buffered_write': 'other', #
'generic_file_llseek': 'other', # fs/read_write.c, include/linux/fs.h,
- 'generic_file_mmap': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
+ 'generic_file_mmap': 'buffer', # mm/filemap.c, include/linux/fs.h,
'generic_file_open' : 'user', # fs/open.c, include/linux/fs.h, used to be syscall
'generic_file_write' : 'user', # mm/filemap.c, include/linux/fs.h, used to be syscall
'generic_file_write_nolock' : 'user', # mm/filemap.c, include/linux/fs.h, used to be syscall
@@ -636,7 +724,7 @@ categories = {
'generic_unplug_device' : 'driver', # drivers/block/ll_rw_blk.c, include/linux/blkdev.h,
'get_conntrack_index' : 'stack', # net/ipv4/netfilter/ip_conntrack_proto_tcp.c,
'get_device' : 'driver', # drivers/base/core.c, include/linux/device.h,
- 'get_dirty_limits' : 'bufmgt', # mm/page-writeback.c,
+ 'get_dirty_limits' : 'buffer', # mm/page-writeback.c,
'get_empty_filp' : 'other', # fs/file_table.c, include/linux/fs.h,
'get_free_idx': 'interrupt', #
'get_futex_key': 'other', # kernel/futex.c,
@@ -645,8 +733,8 @@ categories = {
'get_new_inode_fast': 'other', # fs/inode.c,
'get_object' : 'other', # fs/exportfs/expfs.c,
'get_offset_pmtmr': 'interrupt', #
- 'get_one_pte_map_nested': 'bufmgt', # mm/mremap.c,
- 'get_page_state': 'bufmgt', # mm/page_alloc.c, include/linux/page-flags.h,
+ 'get_one_pte_map_nested': 'buffer', # mm/mremap.c,
+ 'get_page_state': 'buffer', # mm/page_alloc.c, include/linux/page-flags.h,
'get_pipe_inode': 'other', # fs/pipe.c,
'get_request' : 'other', # drivers/block/ll_rw_blk.c,
'get_sample_stats' : 'stack', # net/core/dev.c,
@@ -654,12 +742,12 @@ categories = {
'get_task_mm': 'other', # include/linux/sched.h,
'get_tuple' : 'driver', # net/ipv4/netfilter/ip_conntrack_core.c, drivers/isdn/hisax/elsa_cs.c, drivers/isdn/hisax/teles_cs.c, drivers/isdn/hisax/avma1_cs.c, drivers/isdn/hardware/avm/avm_cs.c, drivers/bluetooth/bt3c_cs.c, drivers/bluetooth/btuart_cs.c, drivers/bluetooth/dtl1_cs.c, include/linux/netfilter_ipv4/ip_conntrack_core.h,
'get_unique_tuple' : 'stack', # net/ipv4/netfilter/ip_nat_core.c,
- 'get_unmapped_area': 'bufmgt', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
+ 'get_unmapped_area': 'buffer', # mm/mmap.c, mm/nommu.c, include/linux/mm.h,
'get_unused_fd' : 'other', # fs/open.c, include/linux/file.h, used to be syscall
'get_vmalloc_info': 'other', # fs/proc/proc_misc.c,
'get_write_access' : 'other', # fs/namei.c, include/linux/fs.h, used to be syscall
'get_writeback_state' : 'other', # mm/page-writeback.c, used to be syscall
- 'get_zone_counts': 'bufmgt', # mm/page_alloc.c, include/linux/mmzone.h,
+ 'get_zone_counts': 'buffer', # mm/page_alloc.c, include/linux/mmzone.h,
'getname' : 'other', # fs/namei.c, include/linux/fs.h, used to be syscall
'getnstimeofday': 'other', #
'getrusage': 'other', # kernel/sys.c, kernel/exit.c,
@@ -715,7 +803,7 @@ categories = {
'inode_sub_bytes' : 'other', # fs/stat.c, include/linux/fs.h,
'inode_times_differ' : 'other', # fs/inode.c,
'inode_update_time' : 'other', # fs/inode.c, include/linux/fs.h,
- 'insert_vm_struct': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'insert_vm_struct': 'buffer', # mm/mmap.c, include/linux/mm.h,
'install_arg_page': 'other', # fs/exec.c, include/linux/mm.h,
'internal_add_timer' : 'other', # kernel/timer.c,
'invalid_dpte_no_dismiss_10_' : 'interrupt', #
@@ -795,19 +883,19 @@ categories = {
'kded_kmilod.so': 'other', #
'kdeinit': 'other', #
'kernel_read': 'other', # fs/exec.c, include/linux/fs.h,
- 'kfree' : 'bufmgt', # mm/slab.c, include/linux/slab.h,
- 'kfree_skbmem' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
+ 'kfree' : 'buffer', # mm/slab.c, include/linux/slab.h,
+ 'kfree_skbmem' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
'kill_fasync': 'other', # fs/fcntl.c, include/linux/fs.h,
'kill_proc_info' : 'other', # kernel/signal.c, include/linux/sched.h,
'kill_something_info' : 'other', # kernel/signal.c,
- 'kmap': 'bufmgt', # include/asm-i386/highmem.h,
- 'kmap_atomic': 'bufmgt', # include/linux/highmem.h, include/asm-i386/highmem.h,
- 'kmap_high': 'bufmgt', # mm/highmem.c,
- 'kmem_cache_alloc' : 'bufmgt', # mm/slab.c, include/linux/slab.h,
- 'kmem_cache_free' : 'bufmgt', # mm/slab.c, include/linux/slab.h,
- 'kmem_flagcheck' : 'bufmgt', # mm/slab.c,
- 'kmem_freepages' : 'bufmgt', # mm/slab.c,
- 'kmem_getpages' : 'bufmgt', # mm/slab.c,
+ 'kmap': 'buffer', # include/asm-i386/highmem.h,
+ 'kmap_atomic': 'buffer', # include/linux/highmem.h, include/asm-i386/highmem.h,
+ 'kmap_high': 'buffer', # mm/highmem.c,
+ 'kmem_cache_alloc' : 'buffer', # mm/slab.c, include/linux/slab.h,
+ 'kmem_cache_free' : 'buffer', # mm/slab.c, include/linux/slab.h,
+ 'kmem_flagcheck' : 'buffer', # mm/slab.c,
+ 'kmem_freepages' : 'buffer', # mm/slab.c,
+ 'kmem_getpages' : 'buffer', # mm/slab.c,
'kobject_get' : 'other', # lib/kobject.c, include/linux/kobject.h,
'kobject_put' : 'other', # lib/kobject.c, include/linux/kobject.h,
'kref_get': 'other', # lib/kref.c, include/linux/kref.h,
@@ -815,9 +903,9 @@ categories = {
'ksoftirqd' : 'interrupt', # kernel/softirq.c,
'ksysguardd': 'other', #
'kthread_should_stop' : 'other', # kernel/kthread.c, include/linux/kthread.h,
- 'kunmap': 'bufmgt', # include/linux/highmem.h, include/asm-i386/highmem.h,
- 'kunmap_atomic': 'bufmgt', # include/linux/highmem.h, include/asm-i386/highmem.h,
- 'kunmap_high': 'bufmgt', # mm/highmem.c,
+ 'kunmap': 'buffer', # include/linux/highmem.h, include/asm-i386/highmem.h,
+ 'kunmap_atomic': 'buffer', # include/linux/highmem.h, include/asm-i386/highmem.h,
+ 'kunmap_high': 'buffer', # mm/highmem.c,
'kwrapper': 'other', #
'ld-2.3.2.so': 'other', #
'lease_get_mtime' : 'other', # fs/locks.c, include/linux/fs.h,
@@ -939,21 +1027,21 @@ categories = {
'lookup_mnt' : 'other', # fs/namespace.c, include/linux/dcache.h,
'loop' : 'interrupt', #
'loopback_xmit': 'driver',
- 'lru_add_drain' : 'bufmgt', # mm/swap.c, include/linux/swap.h,
- 'lru_cache_add' : 'bufmgt', # mm/swap.c,
- 'lru_cache_add_active': 'bufmgt', # mm/swap.c,
+ 'lru_add_drain' : 'buffer', # mm/swap.c, include/linux/swap.h,
+ 'lru_cache_add' : 'buffer', # mm/swap.c,
+ 'lru_cache_add_active': 'buffer', # mm/swap.c,
'lru_put_front' : 'other', # fs/nfsd/nfscache.c,
'ls': 'driver', # drivers/fc4/fc.c,
'mail': 'other', #
- 'mapping_tagged' : 'bufmgt', # mm/page-writeback.c, include/linux/fs.h,
+ 'mapping_tagged' : 'buffer', # mm/page-writeback.c, include/linux/fs.h,
'mark_buffer_dirty' : 'other', # fs/buffer.c,
'mark_buffer_dirty_inode' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
'mark_offset_pmtmr': 'interrupt', #
- 'mark_page_accessed' : 'bufmgt', # mm/swap.c,
+ 'mark_page_accessed' : 'buffer', # mm/swap.c,
'mask_and_ack_level_ioapic_vector': 'interrupt', # include/asm-i386/io_apic.h,
'math_state_restore': 'interrupt', #
'mawk': 'other', #
- 'max_sane_readahead': 'bufmgt', # mm/readahead.c, include/linux/mm.h,
+ 'max_sane_readahead': 'buffer', # mm/readahead.c, include/linux/mm.h,
'max_select_fd': 'other', # fs/select.c,
'may_open': 'other', # fs/namei.c, include/linux/fs.h,
'memcmp' : 'copy', # lib/string.c,
@@ -963,20 +1051,20 @@ categories = {
'memcpy_toiovec' : 'copy', # net/core/iovec.c, include/linux/socket.h,
'meminfo_read_proc': 'other', # fs/proc/proc_misc.c,
'memmove' : 'copy', # lib/string.c, include/asm-alpha/string.h,
- 'mempool_alloc' : 'bufmgt', # mm/mempool.c, include/linux/mempool.h,
- 'mempool_alloc_slab' : 'bufmgt', # mm/mempool.c, include/linux/mempool.h,
- 'mempool_free' : 'bufmgt', # mm/mempool.c, include/linux/mempool.h,
- 'mempool_free_slab' : 'bufmgt', # mm/mempool.c, include/linux/mempool.h,
+ 'mempool_alloc' : 'buffer', # mm/mempool.c, include/linux/mempool.h,
+ 'mempool_alloc_slab' : 'buffer', # mm/mempool.c, include/linux/mempool.h,
+ 'mempool_free' : 'buffer', # mm/mempool.c, include/linux/mempool.h,
+ 'mempool_free_slab' : 'buffer', # mm/mempool.c, include/linux/mempool.h,
'memscan' : 'copy', # lib/string.c,
'mkdir': 'other', #
- 'mm_alloc': 'bufmgt', # kernel/fork.c, include/linux/sched.h,
+ 'mm_alloc': 'buffer', # kernel/fork.c, include/linux/sched.h,
'mm_init': 'driver', # drivers/block/umem.c, kernel/fork.c,
'mm_release': 'other', # kernel/fork.c, include/linux/sched.h,
'mmput': 'other', # kernel/fork.c, include/linux/sched.h,
'mod_timer' : 'other', # kernel/timer.c, include/linux/timer.h,
'move_addr_to_user' : 'copy', # net/socket.c, include/linux/socket.h,
- 'move_one_page': 'bufmgt', # mm/mremap.c,
- 'move_vma': 'bufmgt', # mm/mremap.c,
+ 'move_one_page': 'buffer', # mm/mremap.c,
+ 'move_vma': 'buffer', # mm/mremap.c,
'mpage_alloc' : 'other', # fs/mpage.c,
'mpage_bio_submit' : 'other', # fs/mpage.c,
'mpage_end_io_write' : 'other', # fs/mpage.c,
@@ -1034,7 +1122,7 @@ categories = {
'notifier_call_chain': 'other', # kernel/sys.c, include/linux/notifier.h,
'notify_change': 'other', # fs/attr.c, include/linux/fs.h,
'nr_blockdev_pages': 'other', # fs/block_dev.c, include/linux/blkdev.h,
- 'nr_free_pages': 'bufmgt', # mm/page_alloc.c, include/linux/swap.h,
+ 'nr_free_pages': 'buffer', # mm/page_alloc.c, include/linux/swap.h,
'nr_running': 'other', # kernel/sched.c, include/linux/sched.h,
'ns83820': 'driver',
'ns83820_do_isr' : 'driver',
@@ -1059,17 +1147,17 @@ categories = {
'osf_sigprocmask' : 'other', #
'osync_buffers_list' : 'other', # fs/buffer.c,
'padzero': 'other', # fs/binfmt_elf.c,
- 'page_add_anon_rmap' : 'bufmgt', # mm/rmap.c, include/linux/rmap.h,
- 'page_add_file_rmap': 'bufmgt', # mm/rmap.c, include/linux/rmap.h,
- 'page_address': 'bufmgt', # mm/highmem.c, include/linux/mm.h, include/linux/mm.h, include/linux/mm.h,
- 'page_cache_readahead': 'bufmgt', # mm/readahead.c, include/linux/mm.h,
+ 'page_add_anon_rmap' : 'buffer', # mm/rmap.c, include/linux/rmap.h,
+ 'page_add_file_rmap': 'buffer', # mm/rmap.c, include/linux/rmap.h,
+ 'page_address': 'buffer', # mm/highmem.c, include/linux/mm.h, include/linux/mm.h, include/linux/mm.h,
+ 'page_cache_readahead': 'buffer', # mm/readahead.c, include/linux/mm.h,
'page_fault': 'interrupt', #
- 'page_remove_rmap': 'bufmgt', # mm/rmap.c, include/linux/rmap.h,
- 'page_slot': 'bufmgt', # mm/highmem.c,
+ 'page_remove_rmap': 'buffer', # mm/rmap.c, include/linux/rmap.h,
+ 'page_slot': 'buffer', # mm/highmem.c,
'page_symlink' : 'other', # fs/namei.c, include/linux/fs.h,
- 'page_waitqueue' : 'bufmgt', # mm/filemap.c,
- 'pagevec_lookup': 'bufmgt', # mm/swap.c, include/linux/pagevec.h,
- 'pagevec_lookup_tag' : 'bufmgt', # mm/swap.c, include/linux/pagevec.h,
+ 'page_waitqueue' : 'buffer', # mm/filemap.c,
+ 'pagevec_lookup': 'buffer', # mm/swap.c, include/linux/pagevec.h,
+ 'pagevec_lookup_tag' : 'buffer', # mm/swap.c, include/linux/pagevec.h,
'pal_dtb_ldq' : 'interrupt', #
'pal_itb_ldq' : 'interrupt', #
'pal_post_interrupt' : 'interrupt', #
@@ -1084,14 +1172,14 @@ categories = {
'pci_read': 'driver', #
'pci_unmap_page' : 'driver', # arch/alpha/kernel/pci_iommu.c, include/asm-generic/pci-dma-compat.h, include/asm-alpha/pci.h,
'pci_unmap_single' : 'driver', # arch/alpha/kernel/pci_iommu.c, arch/alpha/kernel/pci-noop.c, include/asm-generic/pci-dma-compat.h, drivers/scsi/aic7xxx/aic79xx_osm.h, drivers/scsi/aic7xxx/aic7xxx_osm.h, include/asm-alpha/pci.h,
- 'percpu_counter_mod' : 'bufmgt', # mm/swap.c, include/linux/percpu_counter.h,
+ 'percpu_counter_mod' : 'buffer', # mm/swap.c, include/linux/percpu_counter.h,
'perl': 'other', #
'permission' : 'user', # fs/namei.c, include/linux/fs.h, used to be syscall
'pfifo_fast_dequeue' : 'stack', # net/sched/sch_generic.c,
'pfifo_fast_enqueue' : 'stack', # net/sched/sch_generic.c,
- 'pgd_alloc': 'bufmgt', # arch/alpha/mm/init.c, include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
- 'pgd_ctor': 'bufmgt', # include/asm-i386/pgtable.h,
- 'pgd_free': 'bufmgt', # include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
+ 'pgd_alloc': 'buffer', # arch/alpha/mm/init.c, include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
+ 'pgd_ctor': 'buffer', # include/asm-i386/pgtable.h,
+ 'pgd_free': 'buffer', # include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
'pipe_ioctl': 'other', # fs/pipe.c,
'pipe_new': 'other', # fs/pipe.c, include/linux/pipe_fs_i.h,
'pipe_poll': 'other', # fs/pipe.c,
@@ -1111,14 +1199,14 @@ categories = {
'poll_initwait' : 'other', # fs/select.c, include/linux/poll.h,
'portmap': 'other', #
'preempt_schedule': 'other', # kernel/sched.c, include/linux/preempt.h,
- 'prep_new_page' : 'bufmgt', # mm/page_alloc.c,
+ 'prep_new_page' : 'buffer', # mm/page_alloc.c,
'prepare_binprm': 'other', # fs/exec.c, include/linux/binfmts.h,
'prepare_to_copy': 'interrupt', # include/asm-alpha/processor.h, include/asm-i386/processor.h,
'prepare_to_wait' : 'other', # kernel/fork.c,
- 'prio_tree_expand': 'bufmgt', # mm/prio_tree.c,
- 'prio_tree_insert': 'bufmgt', # mm/prio_tree.c,
- 'prio_tree_remove': 'bufmgt', # mm/prio_tree.c,
- 'prio_tree_replace': 'bufmgt', # mm/prio_tree.c,
+ 'prio_tree_expand': 'buffer', # mm/prio_tree.c,
+ 'prio_tree_insert': 'buffer', # mm/prio_tree.c,
+ 'prio_tree_remove': 'buffer', # mm/prio_tree.c,
+ 'prio_tree_replace': 'buffer', # mm/prio_tree.c,
'proc_alloc_inode': 'other', # fs/proc/inode.c,
'proc_calc_metrics': 'other', # fs/proc/proc_misc.c,
'proc_delete_inode': 'other', # fs/proc/inode.c,
@@ -1137,8 +1225,8 @@ categories = {
'profile_task_exit': 'other', #
'profile_tick': 'other', #
'pskb_expand_head': 'stack', # net/core/skbuff.c, include/linux/skbuff.h,
- 'pte_alloc_map': 'bufmgt', # mm/memory.c,
- 'pte_alloc_one': 'bufmgt', # include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
+ 'pte_alloc_map': 'buffer', # mm/memory.c,
+ 'pte_alloc_one': 'buffer', # include/asm-alpha/pgalloc.h, include/asm-i386/pgalloc.h,
'ptrace_cancel_bpt' : 'user', # arch/alpha/kernel/ptrace.c, arch/alpha/kernel/proto.h, used to be syscall
'pty_chars_in_buffer': 'driver', # drivers/char/pty.c,
'pty_open': 'driver', # drivers/char/pty.c,
@@ -1165,10 +1253,10 @@ categories = {
'radix_tree_tagged' : 'other', # lib/radix-tree.c, include/linux/radix-tree.h,
'raise_softirq' : 'interrupt', # kernel/softirq.c,
'raise_softirq_irqoff' : 'interrupt', # kernel/softirq.c,
- 'rb_erase' : 'bufmgt', # lib/rbtree.c, include/linux/rbtree.h,
- 'rb_insert_color' : 'bufmgt', # lib/rbtree.c, include/linux/rbtree.h,
- 'rb_next' : 'bufmgt', # lib/rbtree.c, fs/jffs2/nodelist.h, include/linux/rbtree.h,
- 'rb_prev' : 'bufmgt', # lib/rbtree.c, fs/jffs2/nodelist.h, include/linux/rbtree.h,
+ 'rb_erase' : 'buffer', # lib/rbtree.c, include/linux/rbtree.h,
+ 'rb_insert_color' : 'buffer', # lib/rbtree.c, include/linux/rbtree.h,
+ 'rb_next' : 'buffer', # lib/rbtree.c, fs/jffs2/nodelist.h, include/linux/rbtree.h,
+ 'rb_prev' : 'buffer', # lib/rbtree.c, fs/jffs2/nodelist.h, include/linux/rbtree.h,
'rcu_check_callbacks' : 'other', # kernel/rcupdate.c, include/linux/rcupdate.h,
'rcu_check_quiescent_state' : 'other', # kernel/rcupdate.c,
'rcu_do_batch' : 'other', # kernel/rcupdate.c,
@@ -1182,15 +1270,15 @@ categories = {
'recalc_sigpending_tsk' : 'interrupt', # kernel/signal.c,
'recalc_task_prio' : 'other', # kernel/sched.c,
'release_blocks' : 'other', # fs/ext2/balloc.c,
- 'release_pages' : 'bufmgt', # mm/swap.c, include/linux/pagemap.h,
+ 'release_pages' : 'buffer', # mm/swap.c, include/linux/pagemap.h,
'release_sock' : 'stack', # net/core/sock.c,
'release_task': 'other', # kernel/exit.c, include/linux/sched.h,
'release_thread': 'interrupt', # arch/alpha/kernel/process.c, include/asm-um/processor-generic.h, include/asm-alpha/processor.h, include/asm-i386/processor.h,
'release_x86_irqs': 'interrupt', # include/asm-i386/irq.h,
'remove_arg_zero': 'other', # fs/exec.c, include/linux/binfmts.h,
- 'remove_from_page_cache': 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'remove_suid' : 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'remove_vm_struct': 'bufmgt', # mm/mmap.c,
+ 'remove_from_page_cache': 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'remove_suid' : 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'remove_vm_struct': 'buffer', # mm/mmap.c,
'remove_wait_queue' : 'other', # kernel/fork.c,
'resched_task' : 'other', # kernel/sched.c,
'reserve_blocks' : 'other', # fs/ext2/balloc.c,
@@ -1207,7 +1295,7 @@ categories = {
'ret_from_sys_call' : 'user', # arch/alpha/kernel/signal.c, used to be syscall
'rm': 'other', #
'rm_from_queue': 'other', # kernel/signal.c,
- 'rmqueue_bulk' : 'bufmgt', # mm/page_alloc.c,
+ 'rmqueue_bulk' : 'buffer', # mm/page_alloc.c,
'rt_check_expire': 'stack', # net/ipv4/route.c,
'rt_hash_code' : 'stack', # net/ipv4/route.c,
'rt_intern_hash': 'stack', # net/ipv4/route.c, net/ipv4/route.c,
@@ -1268,48 +1356,48 @@ categories = {
'set_binfmt': 'other', # fs/exec.c, include/linux/binfmts.h,
'set_brk': 'user', # fs/binfmt_aout.c, fs/binfmt_elf.c,
'set_current_groups' : 'other', # kernel/sys.c, include/linux/sched.h,
- 'set_page_address': 'bufmgt', # mm/highmem.c, include/linux/mm.h, include/linux/mm.h, include/linux/mm.h,
- 'set_page_dirty': 'bufmgt', # mm/page-writeback.c,
- 'set_slab_attr' : 'bufmgt', # mm/slab.c,
+ 'set_page_address': 'buffer', # mm/highmem.c, include/linux/mm.h, include/linux/mm.h, include/linux/mm.h,
+ 'set_page_dirty': 'buffer', # mm/page-writeback.c,
+ 'set_slab_attr' : 'buffer', # mm/slab.c,
'set_task_comm': 'other', #
'setfl' : 'user', # fs/fcntl.c, used to be syscall
'setup_arg_pages': 'other', # fs/exec.c, include/linux/binfmts.h,
'setup_frame' : 'interrupt', # arch/alpha/kernel/signal.c,
'setup_sigcontext' : 'interrupt', # arch/alpha/kernel/signal.c,
'show_stat': 'other', # fs/proc/proc_misc.c,
- 'si_swapinfo': 'bufmgt', # mm/swapfile.c, include/linux/swap.h, include/linux/swap.h,
+ 'si_swapinfo': 'buffer', # mm/swapfile.c, include/linux/swap.h, include/linux/swap.h,
'sig_ignored' : 'other', # kernel/signal.c,
'signal_wake_up' : 'other', # kernel/signal.c, include/linux/sched.h,
'sigprocmask' : 'other', # kernel/signal.c, include/linux/signal.h,
'single_open': 'other', # fs/seq_file.c, include/linux/seq_file.h,
- 'sk_alloc' : 'bufmgt', # net/core/sock.c,
- 'sk_free' : 'bufmgt', # net/core/sock.c,
- 'sk_reset_timer' : 'bufmgt', # net/core/sock.c,
- 'sk_stop_timer' : 'bufmgt', # net/core/sock.c,
- 'sk_stream_kill_queues' : 'bufmgt', # net/core/stream.c,
- 'sk_stream_mem_schedule' : 'bufmgt', # net/core/stream.c,
- 'sk_stream_rfree' : 'bufmgt', # net/core/stream.c,
- 'sk_stream_wait_close' : 'bufmgt', # net/core/stream.c,
- 'sk_stream_wait_memory' : 'bufmgt', # net/core/stream.c,
- 'sk_stream_write_space' : 'bufmgt', # net/core/stream.c,
- 'sk_wait_data' : 'bufmgt', # net/core/sock.c,
+ 'sk_alloc' : 'buffer', # net/core/sock.c,
+ 'sk_free' : 'buffer', # net/core/sock.c,
+ 'sk_reset_timer' : 'buffer', # net/core/sock.c,
+ 'sk_stop_timer' : 'buffer', # net/core/sock.c,
+ 'sk_stream_kill_queues' : 'buffer', # net/core/stream.c,
+ 'sk_stream_mem_schedule' : 'buffer', # net/core/stream.c,
+ 'sk_stream_rfree' : 'buffer', # net/core/stream.c,
+ 'sk_stream_wait_close' : 'buffer', # net/core/stream.c,
+ 'sk_stream_wait_memory' : 'buffer', # net/core/stream.c,
+ 'sk_stream_write_space' : 'buffer', # net/core/stream.c,
+ 'sk_wait_data' : 'buffer', # net/core/sock.c,
'skb_checksum': 'stack', # net/core/skbuff.c, include/linux/skbuff.h,
'skb_checksum_help': 'stack', # net/core/dev.c, include/linux/netdevice.h,
- 'skb_clone' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
+ 'skb_clone' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
'skb_copy_and_csum_bits' : 'copy', # net/core/skbuff.c, include/linux/skbuff.h,
'skb_copy_and_csum_datagram':'copy',
'skb_copy_bits' : 'copy', # net/core/skbuff.c, include/linux/skbuff.h,
'skb_copy_datagram_iovec' : 'copy', # net/core/datagram.c, include/linux/skbuff.h,
- 'skb_dequeue' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
- 'skb_drop_fraglist' : 'bufmgt', # net/core/skbuff.c,
- 'skb_free_datagram' : 'bufmgt', # net/core/datagram.c, include/linux/skbuff.h,
+ 'skb_dequeue' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
+ 'skb_drop_fraglist' : 'buffer', # net/core/skbuff.c,
+ 'skb_free_datagram' : 'buffer', # net/core/datagram.c, include/linux/skbuff.h,
'skb_queue_head': 'stack', # net/core/skbuff.c, include/linux/skbuff.h,
- 'skb_queue_tail' : 'bufmgt', # net/core/skbuff.c, include/linux/skbuff.h,
- 'skb_read_and_csum_bits' : 'bufmgt', # net/sunrpc/xprt.c,
- 'skb_recv_datagram' : 'bufmgt', # net/core/datagram.c, include/linux/skbuff.h,
- 'skb_release_data' : 'bufmgt', # net/core/skbuff.c, net/core/dev.c,
+ 'skb_queue_tail' : 'buffer', # net/core/skbuff.c, include/linux/skbuff.h,
+ 'skb_read_and_csum_bits' : 'buffer', # net/sunrpc/xprt.c,
+ 'skb_recv_datagram' : 'buffer', # net/core/datagram.c, include/linux/skbuff.h,
+ 'skb_release_data' : 'buffer', # net/core/skbuff.c, net/core/dev.c,
'skip_atoi': 'other', # lib/vsprintf.c,
- 'slab_destroy' : 'bufmgt', # mm/slab.c,
+ 'slab_destroy' : 'buffer', # mm/slab.c,
'smp_apic_timer_interrupt': 'interrupt', #
'smp_percpu_timer_interrupt' : 'interrupt', # arch/alpha/kernel/smp.c, arch/alpha/kernel/proto.h,
'snap_rcv': 'stack', # net/802/psnap.c,
@@ -1342,7 +1430,7 @@ categories = {
'sockfd_lookup' : 'user', # net/socket.c, net/sched/sch_atm.c, include/linux/net.h, used to be syscall
'sockfs_delete_dentry' : 'user', # net/socket.c, used to be syscall
'sort': 'driver', # drivers/scsi/eata.c, drivers/scsi/u14-34f.c,
- 'split_vma': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
+ 'split_vma': 'buffer', # mm/mmap.c, include/linux/mm.h,
'sprintf' : 'other', # lib/vsprintf.c, drivers/isdn/hardware/eicon/platform.h,
'sshd': 'other', #
'steal_locks': 'other', # fs/locks.c, include/linux/fs.h,
@@ -1352,7 +1440,7 @@ categories = {
'strncpy' : 'copy', # lib/string.c, include/asm-alpha/string.h,
'strncpy_from_user': 'copy', # include/asm-alpha/uaccess.h, include/asm-i386/uaccess.h,
'strnlen_user': 'other', # include/asm-alpha/uaccess.h, include/asm-i386/uaccess.h,
- 'submit_bh' : 'bufmgt', # fs/buffer.c, include/linux/buffer_head.h,
+ 'submit_bh' : 'buffer', # fs/buffer.c, include/linux/buffer_head.h,
'submit_bio' : 'other', # drivers/block/ll_rw_blk.c, include/linux/fs.h,
'sunrpc': 'other', #
'svc_authenticate' : 'other', # net/sunrpc/svcauth.c, include/linux/sunrpc/svcauth.h,
@@ -1539,13 +1627,13 @@ categories = {
'tcp_v4_synq_add' : 'stack', # net/ipv4/tcp_ipv4.c,
'tcp_vegas_init' : 'stack', # net/ipv4/tcp_input.c,
'tcp_write_xmit' : 'stack', # net/ipv4/tcp_output.c,
- 'test_clear_page_dirty': 'bufmgt', # mm/page-writeback.c, include/linux/page-flags.h,
- 'test_clear_page_writeback' : 'bufmgt', # mm/page-writeback.c, include/linux/page-flags.h,
- 'test_set_page_writeback' : 'bufmgt', # mm/page-writeback.c, include/linux/page-flags.h,
+ 'test_clear_page_dirty': 'buffer', # mm/page-writeback.c, include/linux/page-flags.h,
+ 'test_clear_page_writeback' : 'buffer', # mm/page-writeback.c, include/linux/page-flags.h,
+ 'test_set_page_writeback' : 'buffer', # mm/page-writeback.c, include/linux/page-flags.h,
'timer_interrupt' : 'interrupt', # arch/alpha/kernel/time.c, arch/alpha/kernel/proto.h,
'tr': 'other', #
- 'truncate_complete_page': 'bufmgt', # mm/truncate.c,
- 'truncate_inode_pages': 'bufmgt', # mm/truncate.c, include/linux/mm.h,
+ 'truncate_complete_page': 'buffer', # mm/truncate.c,
+ 'truncate_inode_pages': 'buffer', # mm/truncate.c, include/linux/mm.h,
'try_to_wake_up' : 'other', # kernel/sched.c,
'tsunami_readb': 'driver',
'tsunami_readl' : 'interrupt', # include/asm-alpha/core_tsunami.h,
@@ -1577,14 +1665,14 @@ categories = {
'unix': 'other', #
'unlock_buffer' : 'other', # fs/buffer.c,
'unlock_new_inode': 'other', # fs/inode.c, include/linux/fs.h,
- 'unlock_page' : 'bufmgt', # mm/filemap.c,
- 'unmap_mapping_range': 'bufmgt', # mm/memory.c, include/linux/mm.h,
- 'unmap_page_range': 'bufmgt', # mm/memory.c,
- 'unmap_region': 'bufmgt', # mm/mmap.c,
+ 'unlock_page' : 'buffer', # mm/filemap.c,
+ 'unmap_mapping_range': 'buffer', # mm/memory.c, include/linux/mm.h,
+ 'unmap_page_range': 'buffer', # mm/memory.c,
+ 'unmap_region': 'buffer', # mm/mmap.c,
'unmap_underlying_metadata' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
- 'unmap_vma': 'bufmgt', # mm/mmap.c,
- 'unmap_vma_list': 'bufmgt', # mm/mmap.c,
- 'unmap_vmas': 'bufmgt', # mm/memory.c, include/linux/mm.h,
+ 'unmap_vma': 'buffer', # mm/mmap.c,
+ 'unmap_vma_list': 'buffer', # mm/mmap.c,
+ 'unmap_vmas': 'buffer', # mm/memory.c, include/linux/mm.h,
'unmask_IO_APIC_irq': 'interrupt', #
'unmask_IO_APIC_vector': 'interrupt', #
'unqueue_me': 'other', # kernel/futex.c,
@@ -1610,28 +1698,28 @@ categories = {
'vfs_unlink': 'other', # fs/namei.c, include/linux/fs.h,
'vfs_write' : 'user', # fs/read_write.c, include/linux/fs.h, used to be syscall
'vfs_writev' : 'user', # fs/read_write.c, include/linux/fs.h, used to be syscall
- 'vma_adjust': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
- 'vma_link': 'bufmgt', # mm/mmap.c,
- 'vma_merge': 'bufmgt', # mm/mmap.c, include/linux/mm.h,
- 'vma_prio_tree_add': 'bufmgt', # mm/prio_tree.c, include/linux/mm.h,
- 'vma_prio_tree_insert': 'bufmgt', # mm/prio_tree.c, include/linux/mm.h,
- 'vma_prio_tree_remove': 'bufmgt', # mm/prio_tree.c, include/linux/mm.h,
+ 'vma_adjust': 'buffer', # mm/mmap.c, include/linux/mm.h,
+ 'vma_link': 'buffer', # mm/mmap.c,
+ 'vma_merge': 'buffer', # mm/mmap.c, include/linux/mm.h,
+ 'vma_prio_tree_add': 'buffer', # mm/prio_tree.c, include/linux/mm.h,
+ 'vma_prio_tree_insert': 'buffer', # mm/prio_tree.c, include/linux/mm.h,
+ 'vma_prio_tree_remove': 'buffer', # mm/prio_tree.c, include/linux/mm.h,
'vmstat_open': 'other', # fs/proc/proc_misc.c,
- 'vmstat_show': 'bufmgt', # mm/page_alloc.c,
- 'vmtruncate': 'bufmgt', # mm/nommu.c, mm/memory.c, include/linux/mm.h,
+ 'vmstat_show': 'buffer', # mm/page_alloc.c,
+ 'vmtruncate': 'buffer', # mm/nommu.c, mm/memory.c, include/linux/mm.h,
'vsnprintf' : 'other', # lib/vsprintf.c, include/linux/kernel.h,
'vsprintf' : 'driver', # lib/vsprintf.c, arch/alpha/boot/main.c, drivers/scsi/aic7xxx_old/aic7xxx_proc.c, include/linux/kernel.h,
'wait_for_completion': 'driver', # drivers/acorn/block/mfmhd.c, kernel/sched.c,
- 'wait_on_page_writeback_range' : 'bufmgt', # mm/filemap.c,
+ 'wait_on_page_writeback_range' : 'buffer', # mm/filemap.c,
'wait_task_zombie': 'other', # kernel/exit.c,
'wake_futex': 'other', # kernel/futex.c,
'wake_up_buffer' : 'other', # fs/buffer.c, include/linux/buffer_head.h,
'wake_up_inode' : 'other', # fs/inode.c, include/linux/writeback.h,
'wake_up_new_task': 'other', #
- 'wake_up_page' : 'bufmgt', # mm/filemap.c,
+ 'wake_up_page' : 'buffer', # mm/filemap.c,
'wake_up_process' : 'other', # kernel/sched.c,
'wake_up_state' : 'other', # kernel/sched.c,
- 'wb_timer_fn': 'bufmgt', # mm/page-writeback.c, mm/page-writeback.c,
+ 'wb_timer_fn': 'buffer', # mm/page-writeback.c, mm/page-writeback.c,
'wc': 'other', #
'work_notifysig': 'other', #
'work_pending' : 'other', #
@@ -1647,9 +1735,9 @@ categories = {
'xdr_partial_copy_from_skb' : 'copy', # net/sunrpc/xdr.c, include/linux/sunrpc/xdr.h,
'xfrm_lookup' : 'stack', # net/xfrm/xfrm_policy.c,
'xmms': 'other', #
- 'zap_pmd_range': 'bufmgt', # mm/memory.c,
- 'zap_pte_range': 'bufmgt', # mm/memory.c,
- 'zone_statistics' : 'bufmgt', # mm/page_alloc.c,
+ 'zap_pmd_range': 'buffer', # mm/memory.c,
+ 'zap_pte_range': 'buffer', # mm/memory.c,
+ 'zone_statistics' : 'buffer', # mm/page_alloc.c,
'libaprutil-0.so.0' : 'user',
'libapr-0.so.0' : 'user',
'httpd' : 'user',
@@ -1660,7 +1748,7 @@ categories = {
'ip_route_output_slow': 'stack',
'tcp_sendpage': 'copy',
'file_send_actor': 'copy',
- 'flush_tlb_page': 'bufmgt',
+ 'flush_tlb_page': 'buffer',
'sock_common_setsockopt': 'stack',
'sock_sendpage': 'copy',
@@ -1668,7 +1756,7 @@ categories = {
# New functions
#
- '__alloc_percpu': 'bufmgt', # mm/slab.c, include/linux/percpu.h,
+ '__alloc_percpu': 'buffer', # mm/slab.c, include/linux/percpu.h,
'__pskb_pull_tail': 'stack', # net/core/skbuff.c, include/linux/skbuff.h,
'__reml': 'other', # arch/alpha/kernel/alpha_ksyms.c,
'__tasklet_hi_schedule': 'interrupt', # kernel/softirq.c,
@@ -1681,13 +1769,13 @@ categories = {
'alcor_disable_irq': 'interrupt', # arch/alpha/kernel/sys_alcor.c,
'alpha_read_fp_reg': 'other', # arch/alpha/lib/fpreg.c, arch/alpha/kernel/proto.h, arch/alpha/math-emu/math.c, include/asm-alpha/fpu.h,
'atkbd_probe': 'other', # drivers/input/keyboard/atkbd.c,
- 'background_writeout': 'bufmgt', # mm/page-writeback.c, mm/page-writeback.c,
- 'bad_page': 'bufmgt', # mm/page_alloc.c,
+ 'background_writeout': 'buffer', # mm/page-writeback.c, mm/page-writeback.c,
+ 'bad_page': 'buffer', # mm/page_alloc.c,
'batch_entropy_process': 'other', # drivers/char/random.c, drivers/char/random.c,
'block_hotplug_filter': 'driver', # drivers/block/genhd.c,
'brioctl_set': 'stack', # net/socket.c, include/linux/if_bridge.h,
'cdev_put': 'fs', # fs/char_dev.c, include/linux/cdev.h,
- 'change_protection': 'bufmgt', # mm/mprotect.c,
+ 'change_protection': 'buffer', # mm/mprotect.c,
'check_timer_failed': 'interrupt', # kernel/timer.c,
'clipper_disable_irq': 'interrupt', # arch/alpha/kernel/sys_dp264.c,
'clipper_enable_irq': 'interrupt', # arch/alpha/kernel/sys_dp264.c,
@@ -1700,8 +1788,8 @@ categories = {
'do_entDbg': 'interrupt', # arch/alpha/kernel/traps.c,
'do_proc_dointvec_jiffies_conv': 'interrupt', # kernel/sysctl.c,
'down_interruptible': 'interrupt', # arch/alpha/kernel/semaphore.c, include/asm-alpha/semaphore.h, include/asm-i386/semaphore.h, include/asm-alpha/semaphore.h, net/ipv4/netfilter/ip_tables.c, net/ipv6/netfilter/ip6_tables.c,
- 'drain_array': 'bufmgt', #
- 'drain_cpu_caches': 'bufmgt', # mm/slab.c,
+ 'drain_array': 'buffer', #
+ 'drain_cpu_caches': 'buffer', # mm/slab.c,
'dummy_file_fcntl': 'other', # security/dummy.c,
'dummy_sem_semop': 'other', # security/dummy.c,
'emit_log_char': 'other', # kernel/printk.c,
@@ -1711,19 +1799,19 @@ categories = {
'eth_header_parse': 'stack', # net/ethernet/eth.c, include/linux/etherdevice.h,
'ethtool_get_settings': 'stack', # net/core/ethtool.c,
'fifo_open': 'fs', # fs/fifo.c,
- 'find_trylock_page': 'bufmgt', # mm/filemap.c, include/linux/pagemap.h,
- 'find_undo': 'bufmgt', # ipc/sem.c,
- 'find_user': 'bufmgt', # kernel/user.c, include/linux/sched.h,
+ 'find_trylock_page': 'buffer', # mm/filemap.c, include/linux/pagemap.h,
+ 'find_undo': 'buffer', # ipc/sem.c,
+ 'find_user': 'buffer', # kernel/user.c, include/linux/sched.h,
'flow_cache_cpu_prepare': 'stack', # net/core/flow.c,
'flow_cache_flush_per_cpu': 'stack', # net/core/flow.c,
'flow_cache_flush_tasklet': 'stack', # net/core/flow.c,
'flow_key_compare': 'stack', # net/core/flow.c,
'flush_icache_user_range': 'interrupt', # arch/alpha/kernel/smp.c, include/asm-alpha/cacheflush.h, include/asm-alpha/cacheflush.h, include/asm-i386/cacheflush.h,
'flush_tlb_mm': 'interrupt', # arch/alpha/kernel/smp.c, include/asm-alpha/tlbflush.h, include/asm-i386/tlbflush.h, include/asm-alpha/tlbflush.h, include/asm-i386/tlbflush.h,
- 'force_page_cache_readahead': 'bufmgt', # mm/readahead.c, include/linux/mm.h,
- 'free_percpu': 'bufmgt', # mm/slab.c, include/linux/percpu.h, include/linux/percpu.h,
- 'generic_file_sendfile': 'bufmgt', # mm/filemap.c, include/linux/fs.h,
- 'get_one_pte_map': 'bufmgt', # mm/mremap.c,
+ 'force_page_cache_readahead': 'buffer', # mm/readahead.c, include/linux/mm.h,
+ 'free_percpu': 'buffer', # mm/slab.c, include/linux/percpu.h, include/linux/percpu.h,
+ 'generic_file_sendfile': 'buffer', # mm/filemap.c, include/linux/fs.h,
+ 'get_one_pte_map': 'buffer', # mm/mremap.c,
'gunzip': 'other', # lib/inflate.c,
'handle_ipi': 'interrupt', # arch/alpha/kernel/smp.c, arch/alpha/kernel/proto.h,
'input_devices_read': 'driver', # drivers/input/input.c,
@@ -1748,8 +1836,8 @@ categories = {
'isp1020_intr_handler': 'other', # drivers/scsi/qlogicisp.c, drivers/scsi/qlogicisp.c,
'isp1020_queuecommand': 'other', # drivers/scsi/qlogicisp.c, drivers/scsi/qlogicisp.h,
'kernel_thread': 'interrupt', # include/asm-um/processor-generic.h, include/asm-alpha/processor.h, include/asm-i386/processor.h,
- 'kmem_find_general_cachep': 'bufmgt', # mm/slab.c,
- 'kmem_ptr_validate': 'bufmgt', # mm/slab.c,
+ 'kmem_find_general_cachep': 'buffer', # mm/slab.c,
+ 'kmem_ptr_validate': 'buffer', # mm/slab.c,
'llc_mac_hdr_init': 'stack', # net/llc/llc_output.c, net/llc/llc_output.h,
'lock_rename': 'fs', # fs/namei.c, include/linux/namei.h,
'lookup_undo': 'stack', # ipc/sem.c,
@@ -1759,7 +1847,7 @@ categories = {
'netlink_release': 'stack', # net/netlink/netlink_dev.c, net/netlink/af_netlink.c,
'nf_log_packet': 'stack', # net/core/netfilter.c, include/linux/netfilter_logging.h, include/linux/netfilter.h,
'nf_queue': 'stack', # net/core/netfilter.c,
- 'nr_free_zone_pages': 'bufmgt', # mm/page_alloc.c,
+ 'nr_free_zone_pages': 'buffer', # mm/page_alloc.c,
'osf_writev': 'driver', # arch/alpha/kernel/osf_sys.c,
'pci_map_sg': 'driver', # arch/alpha/kernel/pci-noop.c, arch/alpha/kernel/pci_iommu.c, include/asm-generic/pci-dma-compat.h, include/asm-alpha/pci.h,
'pci_unmap_sg': 'driver', # arch/alpha/kernel/pci-noop.c, arch/alpha/kernel/pci_iommu.c, include/asm-generic/pci-dma-compat.h, include/asm-alpha/pci.h,
@@ -1770,7 +1858,7 @@ categories = {
'prepare_timeout': 'interrupt', # ipc/mqueue.c,
'printk': 'other', # kernel/printk.c, drivers/md/raid6.h,
'process_mcheck_info': 'interrupt', # arch/alpha/kernel/irq_alpha.c, arch/alpha/kernel/proto.h,
- 'read_cache_pages': 'bufmgt', # mm/readahead.c, include/linux/pagemap.h,
+ 'read_cache_pages': 'buffer', # mm/readahead.c, include/linux/pagemap.h,
'register_gifconf': 'stack', # net/core/dev.c, include/linux/netdevice.h,
'rwsem_down_read_failed': 'interrupt', # lib/rwsem.c, include/asm-alpha/rwsem.h,
'search_exception_tables': 'interrupt', # kernel/extable.c, include/linux/module.h,
@@ -1790,10 +1878,10 @@ categories = {
'sock_wait_for_wmem': 'stack', # net/core/sock.c,
'srm_dispatch': 'other', #
'srm_fixup': 'other', # include/asm-alpha/console.h,
- 'stxcpy_aligned': 'bufmgt', #
+ 'stxcpy_aligned': 'buffer', #
'sys_capset': 'other', # kernel/capability.c, include/linux/syscalls.h,
- 'sys_fadvise64': 'bufmgt', # mm/fadvise.c, include/linux/syscalls.h,
- 'sys_fadvise64_64': 'bufmgt', # mm/fadvise.c, include/linux/syscalls.h,
+ 'sys_fadvise64': 'buffer', # mm/fadvise.c, include/linux/syscalls.h,
+ 'sys_fadvise64_64': 'buffer', # mm/fadvise.c, include/linux/syscalls.h,
'sys_newfstat': 'fs', # fs/stat.c, include/linux/syscalls.h,
'sys_semop': 'stack', # ipc/sem.c, include/linux/syscalls.h,
'sys_semtimedop': 'stack', # ipc/sem.c, include/linux/syscalls.h,
@@ -1825,15 +1913,24 @@ categories = {
'unregister_netdevice': 'stack', # net/core/dev.c, include/linux/netdevice.h,
'update_queue': 'stack', # ipc/sem.c,
'vegas_cong_avoid': 'stack', # net/ipv4/tcp_input.c,
- 'vm_acct_memory': 'bufmgt', # mm/swap.c, include/linux/mman.h,
+ 'vm_acct_memory': 'buffer', # mm/swap.c, include/linux/mman.h,
'vsscanf': 'other', # lib/vsprintf.c, include/linux/kernel.h,
'wait_for_packet': 'stack', # net/core/datagram.c,
'westwood_update_window': 'stack', # net/ipv4/tcp_input.c,
'within_one_quad': 'other', #
}
-categories_re = [
+pc_categories_re = [
# ( re.compile('.*'), 'other' )
]
+def pc_categorize(symbol):
+ from categories import pc_categories, pc_categories_re
+ if symbol in pc_categories:
+ return pc_categories[symbol]
+ for regexp, category in pc_categories_re:
+ if regexp.match(symbol):
+ return category
+
+ return None
diff --git a/util/stats/db.py b/util/stats/db.py
index ab005e67b..1ece6df88 100644
--- a/util/stats/db.py
+++ b/util/stats/db.py
@@ -103,6 +103,20 @@ class Node(object):
def __str__(self):
return self.name
+class Result(object):
+ def __init__(self, x, y):
+ self.data = {}
+ self.x = x
+ self.y = y
+
+ def __contains__(self, run):
+ return run in self.data
+
+ def __getitem__(self, run):
+ if run not in self.data:
+ self.data[run] = [ [ 0.0 ] * self.y for i in xrange(self.x) ]
+ return self.data[run]
+
class Database(object):
def __init__(self):
self.host = 'zizzer.pool'
@@ -135,7 +149,23 @@ class Database(object):
self.runs = None
self.bins = None
self.ticks = None
- self.__dict__['get'] = type(self).sum
+ self.method = 'sum'
+ self._method = type(self).sum
+
+ def get(self, job, stat):
+ run = self.allRunNames.get(job.name, None)
+ if run is None:
+ print 'run "%s" not found' % job
+ return None
+
+ from info import scalar, vector, value, values, total, len
+ stat.system = self[job.system]
+ if scalar(stat):
+ return value(stat, run.run)
+ if vector(stat):
+ return values(stat, run.run)
+
+ return None
def query(self, sql):
self.cursor.execute(sql)
@@ -203,7 +233,7 @@ class Database(object):
self.query('select * from stats')
import info
for result in self.cursor.fetchall():
- stat = info.NewStat(StatData(result))
+ stat = info.NewStat(self, StatData(result))
self.append(stat)
self.allStats.append(stat)
self.allStatIds[stat.stat] = stat
@@ -421,30 +451,17 @@ class Database(object):
def stdev(self, stat, bins, ticks):
return self.outer('stddev', 'sum', stat, bins, ticks)
- def __getattribute__(self, attr):
- if attr != 'get':
- return super(Database, self).__getattribute__(attr)
-
- if self.__dict__['get'] == type(self).sum:
- return 'sum'
- elif self.__dict__['get'] == type(self).avg:
- return 'avg'
- elif self.__dict__['get'] == type(self).stdev:
- return 'stdev'
- else:
- return ''
-
def __setattr__(self, attr, value):
- if attr != 'get':
- super(Database, self).__setattr__(attr, value)
+ super(Database, self).__setattr__(attr, value)
+ if attr != 'method':
return
if value == 'sum':
- self.__dict__['get'] = type(self).sum
+ self._method = self.sum
elif value == 'avg':
- self.__dict__['get'] = type(self).avg
+ self._method = self.avg
elif value == 'stdev':
- self.__dict__['get'] = type(self).stdev
+ self._method = self.stdev
else:
raise AttributeError, "can only set get to: sum | avg | stdev"
@@ -453,10 +470,12 @@ class Database(object):
bins = self.bins
if ticks is None:
ticks = self.ticks
- sql = self.__dict__['get'](self, stat, bins, ticks)
+ sql = self._method(self, stat, bins, ticks)
self.query(sql)
runs = {}
+ xmax = 0
+ ymax = 0
for x in self.cursor.fetchall():
data = Data(x)
if not runs.has_key(data.run):
@@ -464,8 +483,17 @@ class Database(object):
if not runs[data.run].has_key(data.x):
runs[data.run][data.x] = {}
+ xmax = max(xmax, data.x)
+ ymax = max(ymax, data.y)
runs[data.run][data.x][data.y] = data.data
- return runs
+
+ results = Result(xmax + 1, ymax + 1)
+ for run,data in runs.iteritems():
+ result = results[run]
+ for x,ydata in data.iteritems():
+ for y,data in ydata.iteritems():
+ result[x][y] = data
+ return results
def __getitem__(self, key):
return self.stattop[key]
diff --git a/util/stats/display.py b/util/stats/display.py
index 629684ca4..fbcff5c70 100644
--- a/util/stats/display.py
+++ b/util/stats/display.py
@@ -26,7 +26,7 @@
class Value:
def __init__(self, value, precision, percent = False):
- self.value = value
+ self.value = float(value)
self.precision = precision
self.percent = percent
def __str__(self):
@@ -90,61 +90,60 @@ class Print:
class VectorDisplay:
def display(self):
+ if not self.value:
+ return
+
p = Print()
p.flags = self.flags
p.precision = self.precision
- if isinstance(self.value, (list, tuple)):
- if not len(self.value):
- return
-
- mytotal = reduce(lambda x,y: float(x) + float(y), self.value)
- mycdf = 0.0
+ if not isinstance(self.value, (list, tuple)):
+ p.name = self.name
+ p.desc = self.desc
+ p.value = self.value
+ p.display()
+ return
- value = self.value
+ mytotal = reduce(lambda x,y: float(x) + float(y), self.value)
+ mycdf = 0.0
- if display_all:
- subnames = [ '[%d]' % i for i in range(len(value)) ]
- else:
- subnames = [''] * len(value)
-
- if self.__dict__.has_key('subnames'):
- for i,each in enumerate(self.subnames):
- if len(each) > 0:
- subnames[i] = '.%s' % each
-
- subdescs = [self.desc]*len(value)
- if self.__dict__.has_key('subdescs'):
- for i in xrange(min(len(value), len(self.subdescs))):
- subdescs[i] = self.subdescs[i]
-
- for val,sname,sdesc in map(None, value, subnames, subdescs):
- if mytotal > 0.0:
- mypdf = float(val) / float(mytotal)
- mycdf += mypdf
- if (self.flags & flags_pdf):
- p.pdf = mypdf
- p.cdf = mycdf
-
- if len(sname) == 0:
- continue
-
- p.name = self.name + sname
- p.desc = sdesc
- p.value = val
- p.display()
-
- if (self.flags & flags_total):
- if (p.__dict__.has_key('pdf')): del p.__dict__['pdf']
- if (p.__dict__.has_key('cdf')): del p.__dict__['cdf']
- p.name = self.name + '.total'
- p.desc = self.desc
- p.value = mytotal
- p.display()
+ value = self.value
+ if display_all:
+ subnames = [ '[%d]' % i for i in range(len(value)) ]
else:
- p.name = self.name
- p.desc = self.desc
- p.value = self.value
+ subnames = [''] * len(value)
+
+ if self.__dict__.has_key('subnames'):
+ for i,each in enumerate(self.subnames):
+ if len(each) > 0:
+ subnames[i] = '.%s' % each
+
+ subdescs = [self.desc]*len(value)
+ if self.__dict__.has_key('subdescs'):
+ for i in xrange(min(len(value), len(self.subdescs))):
+ subdescs[i] = self.subdescs[i]
+
+ for val,sname,sdesc in map(None, value, subnames, subdescs):
+ if mytotal > 0.0:
+ mypdf = float(val) / float(mytotal)
+ mycdf += mypdf
+ if (self.flags & flags_pdf):
+ p.pdf = mypdf
+ p.cdf = mycdf
+
+ if len(sname) == 0:
+ continue
+
+ p.name = self.name + sname
+ p.desc = sdesc
+ p.value = val
p.display()
+ if (self.flags & flags_total):
+ if (p.__dict__.has_key('pdf')): del p.__dict__['pdf']
+ if (p.__dict__.has_key('cdf')): del p.__dict__['cdf']
+ p.name = self.name + '.total'
+ p.desc = self.desc
+ p.value = mytotal
+ p.display()
diff --git a/util/stats/info.py b/util/stats/info.py
index ae5d3211f..889af6d53 100644
--- a/util/stats/info.py
+++ b/util/stats/info.py
@@ -27,391 +27,347 @@
from __future__ import division
import operator, re, types
-source = None
-display_run = 0
-global globalTicks
-globalTicks = None
-
-def total(f):
- if isinstance(f, FormulaStat):
- v = f.value
- else:
- v = f
-
- f = FormulaStat()
- if isinstance(v, (list, tuple)):
- f.value = reduce(operator.add, v)
- else:
- f.value = v
-
- return f
-
-def unaryop(op, f):
- if isinstance(f, FormulaStat):
- v = f.value
- else:
- v = f
-
- if isinstance(v, (list, tuple)):
- return map(op, v)
- else:
- return op(v)
-
-def zerodiv(lv, rv):
- if rv == 0.0:
- return 0.0
- else:
- return operator.truediv(lv, rv)
-
-def wrapop(op, lv, rv):
- if isinstance(lv, str):
- return lv
-
- if isinstance(rv, str):
- return rv
-
- return op(lv, rv)
-
-def same(lrun, rrun):
- for lx,rx in zip(lrun.keys(),rrun.keys()):
- if lx != rx:
- print 'lx != rx'
- print lx, rx
- print lrun.keys()
- print rrun.keys()
- return False
- for ly,ry in zip(lrun[lx].keys(),rrun[rx].keys()):
- if ly != ry:
- print 'ly != ry'
- print ly, ry
- print lrun[lx].keys()
- print rrun[rx].keys()
- return False
- return True
-
-
-def binaryop(op, lf, rf):
- result = {}
-
- if isinstance(lf, FormulaStat) and isinstance(rf, FormulaStat):
- lv = lf.value
- rv = rf.value
-
- theruns = []
- for r in lv.keys():
- if rv.has_key(r):
- if same(lv[r], rv[r]):
- theruns.append(r)
- else:
- raise AttributeError
-
- for run in theruns:
- result[run] = {}
- for x in lv[run].keys():
- result[run][x] = {}
- for y in lv[run][x].keys():
- result[run][x][y] = wrapop(op, lv[run][x][y],
- rv[run][x][y])
- elif isinstance(lf, FormulaStat):
- lv = lf.value
- for run in lv.keys():
- result[run] = {}
- for x in lv[run].keys():
- result[run][x] = {}
- for y in lv[run][x].keys():
- result[run][x][y] = wrapop(op, lv[run][x][y], rf)
- elif isinstance(rf, FormulaStat):
- rv = rf.value
- for run in rv.keys():
- result[run] = {}
- for x in rv[run].keys():
- result[run][x] = {}
- for y in rv[run][x].keys():
- result[run][x][y] = wrapop(op, lf, rv[run][x][y])
-
+def unproxy(proxy):
+ if hasattr(proxy, '__unproxy__'):
+ return proxy.__unproxy__()
+
+ return proxy
+
+def scalar(stat):
+ stat = unproxy(stat)
+ assert(stat.__scalar__() != stat.__vector__())
+ return stat.__scalar__()
+
+def vector(stat):
+ stat = unproxy(stat)
+ assert(stat.__scalar__() != stat.__vector__())
+ return stat.__vector__()
+
+def value(stat, *args):
+ stat = unproxy(stat)
+ return stat.__value__(*args)
+
+def values(stat, run):
+ stat = unproxy(stat)
+ result = []
+ for i in xrange(len(stat)):
+ val = value(stat, run, i)
+ if val is None:
+ return None
+ result.append(val)
return result
-def sums(x, y):
- if isinstance(x, (list, tuple)):
- return map(lambda x, y: x + y, x, y)
- else:
- return x + y
-
-def alltrue(seq):
- return reduce(lambda x, y: x and y, seq)
-
-def allfalse(seq):
- return not reduce(lambda x, y: x or y, seq)
-
-def enumerate(seq):
- return map(None, range(len(seq)), seq)
-
-def cmp(a, b):
- if a < b:
- return -1
- elif a == b:
- return 0
- else:
- return 1
-
-class Statistic(object):
-
- def __init__(self, data):
- self.__dict__.update(data.__dict__)
- if not self.__dict__.has_key('value'):
- self.__dict__['value'] = None
- if not self.__dict__.has_key('bins'):
- self.__dict__['bins'] = None
- if not self.__dict__.has_key('ticks'):
- self.__dict__['ticks'] = None
- if 'vc' not in self.__dict__:
- self.vc = {}
-
- def __getattribute__(self, attr):
- if attr == 'ticks':
- if self.__dict__['ticks'] != globalTicks:
- self.__dict__['value'] = None
- self.__dict__['ticks'] = globalTicks
- return self.__dict__['ticks']
- if attr == 'value':
- if self.__dict__['ticks'] != globalTicks:
- if self.__dict__['ticks'] != None and \
- len(self.__dict__['ticks']) == 1:
- self.vc[self.__dict__['ticks'][0]] = self.__dict__['value']
- self.__dict__['ticks'] = globalTicks
- if len(globalTicks) == 1 and self.vc.has_key(globalTicks[0]):
- self.__dict__['value'] = self.vc[globalTicks[0]]
- else:
- self.__dict__['value'] = None
- if self.__dict__['value'] == None:
- self.__dict__['value'] = self.getValue()
- return self.__dict__['value']
- else:
- return super(Statistic, self).__getattribute__(attr)
-
- def __setattr__(self, attr, value):
- if attr == 'bins' or attr == 'ticks':
- if attr == 'bins':
- if value is not None:
- value = source.getBin(value)
- #elif attr == 'ticks' and type(value) is str:
- # value = [ int(x) for x in value.split() ]
-
- self.__dict__[attr] = value
- self.__dict__['value'] = None
- self.vc = {}
- else:
- super(Statistic, self).__setattr__(attr, value)
+def total(stat, run):
+ return sum(values(stat, run))
- def getValue(self):
- raise AttributeError, 'getValue() must be defined'
-
- def zero(self):
- return False
+def len(stat):
+ stat = unproxy(stat)
+ return stat.__len__()
- def __ne__(self, other):
- return not (self == other)
+class Value(object):
+ def __scalar__(self):
+ raise AttributeError, "must define __scalar__ for %s" % (type (self))
+ def __vector__(self):
+ raise AttributeError, "must define __vector__ for %s" % (type (self))
- def __str__(self):
- return '%f' % (float(self))
-
-class FormulaStat(object):
def __add__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.add, self, other)
- return f
+ return BinaryProxy(operator.__add__, self, other)
def __sub__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.sub, self, other)
- return f
+ return BinaryProxy(operator.__sub__, self, other)
def __mul__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.mul, self, other)
- return f
+ return BinaryProxy(operator.__mul__, self, other)
+ def __div__(self, other):
+ return BinaryProxy(operator.__div__, self, other)
def __truediv__(self, other):
- f = FormulaStat()
- f.value = binaryop(zerodiv, self, other)
- return f
- def __mod__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.mod, self, other)
- return f
+ return BinaryProxy(operator.__truediv__, self, other)
+ def __floordiv__(self, other):
+ return BinaryProxy(operator.__floordiv__, self, other)
+
def __radd__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.add, other, self)
- return f
+ return BinaryProxy(operator.__add__, other, self)
def __rsub__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.sub, other, self)
- return f
+ return BinaryProxy(operator.__sub__, other, self)
def __rmul__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.mul, other, self)
- return f
+ return BinaryProxy(operator.__mul__, other, self)
+ def __rdiv__(self, other):
+ return BinaryProxy(operator.__div__, other, self)
def __rtruediv__(self, other):
- f = FormulaStat()
- f.value = binaryop(zerodiv, other, self)
- return f
- def __rmod__(self, other):
- f = FormulaStat()
- f.value = binaryop(operator.mod, other, self)
- return f
+ return BinaryProxy(operator.__truediv__, other, self)
+ def __rfloordiv__(self, other):
+ return BinaryProxy(operator.__floordiv__, other, self)
+
def __neg__(self):
- f = FormulaStat()
- f.value = unaryop(operator.neg, self)
- return f
- def __getitem__(self, idx):
- f = FormulaStat()
- f.value = {}
- for key in self.value.keys():
- f.value[key] = {}
- f.value[key][0] = {}
- f.value[key][0][0] = self.value[key][idx][0]
- return f
-
- def __float__(self):
- if isinstance(self.value, FormulaStat):
- return float(self.value)
- if not self.value.has_key(display_run):
- return (1e300*1e300)
- if len(self.value[display_run]) == 1:
- return self.value[display_run][0][0]
- else:
- #print self.value[display_run]
- return self.value[display_run][4][0]
- #raise ValueError
+ return UnaryProxy(operator.__neg__, self)
+ def __pos__(self):
+ return UnaryProxy(operator.__pos__, self)
+ def __abs__(self):
+ return UnaryProxy(operator.__abs__, self)
+
+class Scalar(Value):
+ def __scalar__(self):
+ return True
- def display(self):
- import display
- d = display.VectorDisplay()
- d.flags = 0
- d.precision = 1
- d.name = 'formula'
- d.desc = 'formula'
- val = self.value[display_run]
- d.value = [ val[x][0] for x in val.keys() ]
- d.display()
+ def __vector__(self):
+ return False
+ def __value__(self, run):
+ raise AttributeError, '__value__ must be defined'
-class Scalar(Statistic,FormulaStat):
- def getValue(self):
- return source.data(self, self.bins, self.ticks)
+class VectorItemProxy(Value):
+ def __init__(self, proxy, index):
+ self.proxy = proxy
+ self.index = index
- def display(self):
- import display
- p = display.Print()
- p.name = self.name
- p.desc = self.desc
- p.value = float(self)
- p.flags = self.flags
- p.precision = self.precision
- if display.all or (self.flags & flags.printable):
- p.display()
+ def __scalar__(self):
+ return True
- def comparable(self, other):
- return self.name == other.name
+ def __vector__(self):
+ return False
- def __eq__(self, other):
- return self.value == other.value
+ def __value__(self, run):
+ return value(self.proxy, run, self.index)
- def __isub__(self, other):
- self.value -= other.value
- return self
+class Vector(Value):
+ def __scalar__(self):
+ return False
- def __iadd__(self, other):
- self.value += other.value
- return self
+ def __vector__(self):
+ return True
- def __itruediv__(self, other):
- if not other:
- return self
- self.value /= other
- return self
+ def __value__(self, run, index):
+ raise AttributeError, '__value__ must be defined'
-class Vector(Statistic,FormulaStat):
- def getValue(self):
- return source.data(self, self.bins, self.ticks);
+ def __getitem__(self, index):
+ return VectorItemProxy(self, index)
- def display(self):
- import display
- if not display.all and not (self.flags & flags.printable):
- return
+class ScalarConstant(Scalar):
+ def __init__(self, constant):
+ self.constant = constant
+ def __value__(self, run):
+ return self.constant
- d = display.VectorDisplay()
- d.__dict__.update(self.__dict__)
- d.display()
+class VectorConstant(Vector):
+ def __init__(self, constant):
+ self.constant = constant
+ def __value__(self, run, index):
+ return self.constant[index]
+ def __len__(self):
+ return len(self.constant)
- def comparable(self, other):
- return self.name == other.name and \
- len(self.value) == len(other.value)
+def WrapValue(value):
+ if isinstance(value, (int, long, float)):
+ return ScalarConstant(value)
+ if isinstance(value, (list, tuple)):
+ return VectorConstant(value)
+ if isinstance(value, Value):
+ return value
- def __eq__(self, other):
- if isinstance(self.value, (list, tuple)) != \
- isinstance(other.value, (list, tuple)):
- return False
+ raise AttributeError, 'Only values can be wrapped'
- if isinstance(self.value, (list, tuple)):
- if len(self.value) != len(other.value):
- return False
- else:
- for v1,v2 in zip(self.value, other.value):
- if v1 != v2:
- return False
- return True
- else:
- return self.value == other.value
+class Statistic(object):
+ def __getattr__(self, attr):
+ if attr in ('data', 'x', 'y'):
+ result = self.source.data(self, self.bins, self.ticks)
+ self.data = result.data
+ self.x = result.x
+ self.y = result.y
+ return super(Statistic, self).__getattribute__(attr)
- def __isub__(self, other):
- self.value = binaryop(operator.sub, self.value, other.value)
- return self
+ def __setattr__(self, attr, value):
+ if attr == 'stat':
+ raise AttributeError, '%s is read only' % stat
+ if attr in ('source', 'bins', 'ticks'):
+ if getattr(self, attr) != value:
+ if hasattr(self, 'data'):
+ delattr(self, 'data')
+
+ super(Statistic, self).__setattr__(attr, value)
+
+class ValueProxy(Value):
+ def __getattr__(self, attr):
+ if attr == '__value__':
+ if scalar(self):
+ return self.__scalarvalue__
+ if vector(self):
+ return self.__vectorvalue__
+ if attr == '__len__':
+ if vector(self):
+ return self.__vectorlen__
+ return super(ValueProxy, self).__getattribute__(attr)
+
+class UnaryProxy(ValueProxy):
+ def __init__(self, op, arg):
+ self.op = op
+ self.arg = WrapValue(arg)
+
+ def __scalar__(self):
+ return scalar(self.arg)
+
+ def __vector__(self):
+ return vector(self.arg)
+
+ def __scalarvalue__(self, run):
+ val = value(self.arg, run)
+ if val is None:
+ return None
+ return self.op(val)
+
+ def __vectorvalue__(self, run, index):
+ val = value(self.arg, run, index)
+ if val is None:
+ return None
+ return self.op(val)
+
+ def __vectorlen__(self):
+ return len(unproxy(self.arg))
+
+class BinaryProxy(ValueProxy):
+ def __init__(self, op, arg0, arg1):
+ super(BinaryProxy, self).__init__()
+ self.op = op
+ self.arg0 = WrapValue(arg0)
+ self.arg1 = WrapValue(arg1)
+
+ def __scalar__(self):
+ return scalar(self.arg0) and scalar(self.arg1)
+
+ def __vector__(self):
+ return vector(self.arg0) or vector(self.arg1)
+
+ def __scalarvalue__(self, run):
+ val0 = value(self.arg0, run)
+ val1 = value(self.arg1, run)
+ if val0 is None or val1 is None:
+ return None
+ return self.op(val0, val1)
+
+ def __vectorvalue__(self, run, index):
+ if scalar(self.arg0):
+ val0 = value(self.arg0, run)
+ if vector(self.arg0):
+ val0 = value(self.arg0, run, index)
+ if scalar(self.arg1):
+ val1 = value(self.arg1, run)
+ if vector(self.arg1):
+ val1 = value(self.arg1, run, index)
+
+ if val0 is None or val1 is None:
+ return None
+
+ return self.op(val0, val1)
+
+ def __vectorlen__(self):
+ if vector(self.arg0) and scalar(self.arg1):
+ return len(self.arg0)
+ if scalar(self.arg0) and vector(self.arg1):
+ return len(self.arg1)
+
+ len0 = len(self.arg0)
+ len1 = len(self.arg1)
+
+ if len0 != len1:
+ raise AttributeError, \
+ "vectors of different lengths %d != %d" % (len0, len1)
+
+ return len0
+
+class Proxy(Value):
+ def __init__(self, name, dict):
+ self.name = name
+ self.dict = dict
+
+ def __unproxy__(self):
+ return unproxy(self.dict[self.name])
+
+ def __getitem__(self, index):
+ return ItemProxy(self, index)
+
+ def __getattr__(self, attr):
+ return AttrProxy(self, attr)
+
+class ItemProxy(Proxy):
+ def __init__(self, proxy, index):
+ self.proxy = proxy
+ self.index = index
+
+ def __unproxy__(self):
+ return unproxy(unproxy(self.proxy)[self.index])
- def __iadd__(self, other):
- self.value = binaryop(operator.add, self.value, other.value)
- return self
+class AttrProxy(Proxy):
+ def __init__(self, proxy, attr):
+ self.proxy = proxy
+ self.attr = attr
- def __itruediv__(self, other):
- if not other:
- return self
- if isinstance(self.value, (list, tuple)):
- for i in xrange(len(self.value)):
- self.value[i] /= other
- else:
- self.value /= other
- return self
+ def __unproxy__(self):
+ return unproxy(getattr(unproxy(self.proxy), self.attr))
-class Formula(Vector):
- def getValue(self):
- formula = re.sub(':', '__', self.formula)
- x = eval(formula, source.stattop)
- return x.value
+class ProxyGroup(object):
+ def __init__(self, dict=None, **kwargs):
+ self.__dict__['dict'] = {}
- def comparable(self, other):
- return self.name == other.name and \
- compare(self.dist, other.dist)
+ if dict is not None:
+ self.dict.update(dict)
- def __eq__(self, other):
- return self.value == other.value
+ if kwargs:
+ self.dict.update(kwargs)
- def __isub__(self, other):
- return self
+ def __getattr__(self, name):
+ return Proxy(name, self.dict)
- def __iadd__(self, other):
- return self
+ def __setattr__(self, attr, value):
+ self.dict[attr] = value
- def __itruediv__(self, other):
- if not other:
- return self
- return self
+class ScalarStat(Statistic,Scalar):
+ def __value__(self, run):
+ if run not in self.data:
+ return None
+ return self.data[run][0][0]
+
+ def display(self, run=None):
+ import display
+ p = display.Print()
+ p.name = self.name
+ p.desc = self.desc
+ p.value = value(self, run)
+ p.flags = self.flags
+ p.precision = self.precision
+ if display.all or (self.flags & flags.printable):
+ p.display()
+
+class VectorStat(Statistic,Vector):
+ def __value__(self, run, item):
+ if run not in self.data:
+ return None
+ return self.data[run][item][0]
+
+ def __len__(self):
+ return self.x
-class SimpleDist(object):
+ def display(self, run=None):
+ import display
+ d = display.VectorDisplay()
+ d.name = self.name
+ d.desc = self.desc
+ d.value = [ value(self, run, i) for i in xrange(len(self)) ]
+ d.flags = self.flags
+ d.precision = self.precision
+ d.display()
+
+class Formula(Value):
+ def __getattribute__(self, attr):
+ if attr not in ( '__scalar__', '__vector__', '__value__', '__len__' ):
+ return super(Formula, self).__getattribute__(attr)
+
+ formula = re.sub(':', '__', self.formula)
+ value = eval(formula, self.source.stattop)
+ return getattr(value, attr)
+
+class SimpleDist(Statistic):
def __init__(self, sums, squares, samples):
self.sums = sums
self.squares = squares
self.samples = samples
- def getValue(self):
- return 0.0
-
def display(self, name, desc, flags, precision):
import display
p = display.Print()
@@ -482,9 +438,6 @@ class FullDist(SimpleDist):
self.bsize = bsize
self.size = size
- def getValue(self):
- return 0.0
-
def display(self, name, desc, flags, precision):
import display
p = display.Print()
@@ -574,9 +527,6 @@ class FullDist(SimpleDist):
return self
class Dist(Statistic):
- def getValue(self):
- return 0.0
-
def display(self):
import display
if not display.all and not (self.flags & flags.printable):
@@ -606,9 +556,6 @@ class Dist(Statistic):
return self
class VectorDist(Statistic):
- def getValue(self):
- return 0.0
-
def display(self):
import display
if not display.all and not (self.flags & flags.printable):
@@ -694,9 +641,6 @@ class VectorDist(Statistic):
return self
class Vector2d(Statistic):
- def getValue(self):
- return 0.0
-
def display(self):
import display
if not display.all and not (self.flags & flags.printable):
@@ -748,20 +692,25 @@ class Vector2d(Statistic):
return self
return self
-def NewStat(data):
+def NewStat(source, data):
stat = None
if data.type == 'SCALAR':
- stat = Scalar(data)
+ stat = ScalarStat()
elif data.type == 'VECTOR':
- stat = Vector(data)
+ stat = VectorStat()
elif data.type == 'DIST':
- stat = Dist(data)
+ stat = Dist()
elif data.type == 'VECTORDIST':
- stat = VectorDist(data)
+ stat = VectorDist()
elif data.type == 'VECTOR2D':
- stat = Vector2d(data)
+ stat = Vector2d()
elif data.type == 'FORMULA':
- stat = Formula(data)
+ stat = Formula()
+
+ stat.__dict__['source'] = source
+ stat.__dict__['bins'] = None
+ stat.__dict__['ticks'] = None
+ stat.__dict__.update(data.__dict__)
return stat
diff --git a/util/stats/output.py b/util/stats/output.py
index 44dba5d15..cf76f291e 100644
--- a/util/stats/output.py
+++ b/util/stats/output.py
@@ -26,24 +26,8 @@
#
# Authors: Nathan Binkert
-class dbinfo(object):
- def get(self, job, stat):
- import info
-
- run = info.source.allRunNames.get(job.name, None)
- if run is None:
- print 'run "%s" not found' % job
- return None
-
- stat.system = info.source[job.system]
- info.display_run = run.run;
- val = float(stat)
- if val == 1e300*1e300:
- return None
- return val
-
class StatOutput(object):
- def __init__(self, name, jobfile, stat=None, info=dbinfo(), binstats=None):
+ def __init__(self, name, jobfile, info, stat=None, binstats=None):
self.name = name
self.jobfile = jobfile
self.stat = stat
@@ -96,10 +80,10 @@ class StatOutput(object):
self.printdata(printmode=printmode)
def graph(self, graphdir):
- from os.path import expanduser, join as joinpath
+ from os.path import expanduser, isdir, join as joinpath
from barchart import BarChart
- from matplotlib.numerix import Float, zeros
- import re
+ from matplotlib.numerix import Float, array, zeros
+ import os, re
confgroups = self.jobfile.groups()
ngroups = len(confgroups)
@@ -130,6 +114,8 @@ class StatOutput(object):
raise AttributeError, 'No group selected for graph bars'
directory = expanduser(graphdir)
+ if not isdir(directory):
+ os.mkdir(directory)
html = file(joinpath(directory, '%s.html' % self.name), 'w')
print >>html, '<html>'
print >>html, '<title>Graphs for %s</title>' % self.name
@@ -139,27 +125,47 @@ class StatOutput(object):
data = zeros((len(groupopts), len(baropts)), Float)
data = [ [ None ] * len(baropts) for i in xrange(len(groupopts)) ]
enabled = False
- stacked = None
+ stacked = 0
for g,gopt in enumerate(groupopts):
for b,bopt in enumerate(baropts):
job = self.jobfile.job(options + [ gopt, bopt ])
+ if not job:
+ continue
val = self.info.get(job, self.stat)
- if val is None:
- val = 0.0
- curstacked = isinstance(val, (list, tuple))
- if stacked is None:
- stacked = curstacked
- else:
- if stacked != curstacked:
- raise ValueError, "some stats stacked, some not"
+ if isinstance(val, (list, tuple)):
+ if len(val) == 1:
+ val = val[0]
+ else:
+ stacked = len(val)
data[g][b] = val
+ if stacked == 0:
+ for i in xrange(len(groupopts)):
+ for j in xrange(len(baropts)):
+ if data[i][j] is None:
+ data[i][j] = 0.0
+ else:
+ for i in xrange(len(groupopts)):
+ for j in xrange(len(baropts)):
+ val = data[i][j]
+ if val is None:
+ data[i][j] = [] * stacked
+ elif len(val) != stacked:
+ raise ValueError, "some stats stacked, some not"
+
+ data = array(data)
+ if data.sum() == 0:
+ continue
+
bar_descs = [ opt.desc for opt in baropts ]
group_descs = [ opt.desc for opt in groupopts ]
if stacked:
- legend = self.info.rcategories
+ try:
+ legend = self.info.rcategories
+ except:
+ legend = [ str(i) for i in xrange(stacked) ]
else:
legend = bar_descs
diff --git a/util/stats/profile.py b/util/stats/profile.py
index 65a03e9aa..57b854a30 100644
--- a/util/stats/profile.py
+++ b/util/stats/profile.py
@@ -27,103 +27,227 @@
from orderdict import orderdict
import output
-class ProfileData(object):
- def __init__(self):
- self.data = {}
- self.total = {}
- self.runs = orderdict()
- self.runlist = []
+class RunData(dict):
+ def __init__(self, filename=None):
+ self.filename = filename
- def addvalue(self, run, cpu, symbol, value):
- value = float(value)
- self.data[run, cpu, symbol] = self.getvalue(run, cpu, symbol) + value
- self.total[run, cpu] = self.gettotal(run, cpu) + value
- if run not in self.runs:
- self.runs[run] = orderdict()
+ def __getattr__(self, attr):
+ if attr == 'total':
+ total = 0.0
+ for value in self.itervalues():
+ total += value
+ return total
+ if attr == 'maxsymlen':
+ return max([ len(sym) for sym in self.iterkeys() ])
- if cpu not in self.runs[run]:
- self.runs[run][cpu] = {}
+ def display(self, output=None, limit=None, maxsymlen=None):
+ if not output:
+ import sys
+ output = sys.stdout
+ elif isinstance(output, str):
+ output = file(output, 'w')
- if symbol not in self.runs[run][cpu]:
- self.runs[run][cpu][symbol] = 0
+ total = float(self.total)
- self.runs[run][cpu][symbol] += value
+ # swap (string,count) order so we can sort on count
+ symbols = [ (count,name) for name,count in self.iteritems() ]
+ symbols.sort(reverse=True)
+ if limit is not None:
+ symbols = symbols[:limit]
- def getvalue(self, run, cpu, symbol):
- return self.data.get((run, cpu, symbol), 0)
+ if not maxsymlen:
+ maxsymlen = self.maxsymlen
- def gettotal(self, run, cpu):
- return self.total.get((run, cpu), 0)
+ symbolf = "%-" + str(maxsymlen + 1) + "s %.2f%%"
+ for number,name in symbols:
+ print >>output, symbolf % (name, 100.0 * (float(number) / total))
-class Profile(object):
- default_order = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp']
- # This list controls the order of values in stacked bar data output
- default_categories = [ 'interrupt',
- 'driver',
- 'stack',
- 'bufmgt',
- 'copy',
- 'user',
- 'other',
- 'idle']
- def __init__(self, run_order=[], categories=[], stacknames=[]):
- if not run_order:
- run_order = Profile.default_order
- if not categories:
- categories = Profile.default_categories
+class PCData(RunData):
+ def __init__(self, filename=None, categorize=None, showidle=True):
+ super(PCData, self).__init__(self, filename)
+ if filename is None:
+ return
- self.run_order = run_order
- self.categories = categories
- self.rcategories = []
- self.rcategories.extend(categories)
- self.rcategories.reverse()
- self.stacknames = stacknames
- self.prof = ProfileData()
- self.categorize = True
- self.showidle = True
- self.maxsymlen = 0
-
- def category(self, symbol):
- from categories import categories, categories_re
- if categories.has_key(symbol):
- return categories[symbol]
- for regexp, cat in categories_re:
- if regexp.match(symbol):
- return cat
- return 'other'
-
- # Parse input file and put the results in the given run and cpu
- def parsefile(self, run, cpu, filename):
fd = file(filename)
for line in fd:
+ if line.strip() == '>>>PC data':
+ break
+
+ for line in fd:
+ if line.startswith('>>>'):
+ break
+
(symbol, count) = line.split()
if symbol == "0x0":
continue
count = int(count)
- if self.categorize:
- symbol = self.category(symbol)
- if symbol == 'idle' and not self.showidle:
+ if categorize is not None:
+ category = categorize(symbol)
+ if category is None:
+ category = 'other'
+ elif category == 'idle' and not showidle:
continue
- if symbol not in self.categories:
- symbol = 'other'
-
- self.maxsymlen = max(self.maxsymlen, len(symbol))
- self.prof.addvalue(run, cpu, symbol, count)
+ self[category] = count
fd.close()
+class FuncNode(object):
+ def __new__(cls, filename = None):
+ if filename is None:
+ return super(FuncNode, cls).__new__(cls)
+
+ fd = file(filename, 'r')
+ fditer = iter(fd)
+ nodes = {}
+ for line in fditer:
+ if line.strip() == '>>>function data':
+ break
+
+ for line in fditer:
+ if line.startswith('>>>'):
+ break
+
+ data = line.split()
+ node_id = int(data[0], 16)
+ node = FuncNode()
+ node.symbol = data[1]
+ node.count = int(data[2])
+ node.children = [ int(child, 16) for child in data[3:] ]
+ nodes[node_id] = node
+
+ for node in nodes.itervalues():
+ children = []
+ for cid in node.children:
+ child = nodes[cid]
+ children.append(child)
+ child.parent = node
+ node.children = tuple(children)
+ if not nodes:
+ print filename
+ print nodes
+ return nodes[0]
+
+ def __init__(self, filename=None):
+ pass
+
+ def total(self):
+ total = self.count
+ for child in self.children:
+ total += child.total()
+
+ return total
+
+ def aggregate(self, dict, categorize, incategory):
+ category = None
+ if categorize:
+ category = categorize(self.symbol)
+
+ total = self.count
+ for child in self.children:
+ total += child.aggregate(dict, categorize, category or incategory)
+
+ if category:
+ dict[category] = dict.get(category, 0) + total
+ return 0
+ elif not incategory:
+ dict[self.symbol] = dict.get(self.symbol, 0) + total
+
+ return total
+
+ def dump(self):
+ kids = [ child.symbol for child in self.children]
+ print '%s %d <%s>' % (self.symbol, self.count, ', '.join(kids))
+ for child in self.children:
+ child.dump()
+
+ def _dot(self, dot, threshold, categorize, total):
+ from pydot import Dot, Edge, Node
+ self.dot_node = None
+
+ value = self.total() * 100.0 / total
+ if value < threshold:
+ return
+ if categorize:
+ category = categorize(self.symbol)
+ if category and category != 'other':
+ return
+ label = '%s %.2f%%' % (self.symbol, value)
+ self.dot_node = Node(self, label=label)
+ dot.add_node(self.dot_node)
+
+ for child in self.children:
+ child._dot(dot, threshold, categorize, total)
+ if child.dot_node is not None:
+ dot.add_edge(Edge(self, child))
+
+ def _cleandot(self):
+ for child in self.children:
+ child._cleandot()
+ self.dot_node = None
+ del self.__dict__['dot_node']
+
+ def dot(self, dot, threshold=0.1, categorize=None):
+ self._dot(dot, threshold, categorize, self.total())
+ self._cleandot()
+
+class FuncData(RunData):
+ def __init__(self, filename, categorize=None):
+ super(FuncData, self).__init__(filename)
+ self.tree = FuncNode(filename)
+ self.tree.aggregate(self, categorize, incategory=False)
+ self.total = self.tree.total()
+
+ def displayx(self, output=None, maxcount=None):
+ if output is None:
+ import sys
+ output = sys.stdout
+
+ items = [ (val,key) for key,val in self.iteritems() ]
+ items.sort(reverse=True)
+ for val,key in items:
+ if maxcount is not None:
+ if maxcount == 0:
+ return
+ maxcount -= 1
+
+ percent = val * 100.0 / self.total
+ print >>output, '%-30s %8s' % (key, '%3.2f%%' % percent)
+
+class Profile(object):
+ # This list controls the order of values in stacked bar data output
+ default_categories = [ 'interrupt',
+ 'driver',
+ 'stack',
+ 'buffer',
+ 'copy',
+ 'syscall',
+ 'user',
+ 'other',
+ 'idle']
+
+ def __init__(self, datatype, categorize=None):
+ categories = Profile.default_categories
+
+ self.datatype = datatype
+ self.categorize = categorize
+ self.data = {}
+ self.categories = categories[:]
+ self.rcategories = categories[:]
+ self.rcategories.reverse()
+ self.cpu = 0
+
# Read in files
def inputdir(self, directory):
import os, os.path, re
from os.path import expanduser, join as joinpath
directory = expanduser(directory)
- label_ex = re.compile(r'm5prof\.(.*)')
+ label_ex = re.compile(r'profile\.(.*).dat')
for root,dirs,files in os.walk(directory):
for name in files:
match = label_ex.match(name)
@@ -133,14 +257,229 @@ class Profile(object):
filename = joinpath(root, name)
prefix = os.path.commonprefix([root, directory])
dirname = root[len(prefix)+1:]
- self.parsefile(dirname, match.group(1), filename)
+ data = self.datatype(filename, self.categorize)
+ self.setdata(dirname, match.group(1), data)
+
+ def setdata(self, run, cpu, data):
+ if run not in self.data:
+ self.data[run] = {}
+
+ if cpu in self.data[run]:
+ raise AttributeError, \
+ 'data already stored for run %s and cpu %s' % (run, cpu)
+
+ self.data[run][cpu] = data
+
+ def getdata(self, run, cpu):
+ try:
+ return self.data[run][cpu]
+ except KeyError:
+ return None
+
+ def alldata(self):
+ for run,cpus in self.data.iteritems():
+ for cpu,data in cpus.iteritems():
+ yield run,cpu,data
def get(self, job, stat):
if job.system is None:
raise AttributeError, 'The job must have a system set'
- cpu = '%s.full0' % job.system
+ data = self.getdata(job.name, '%s.full%d' % (job.system, self.cpu))
+ if not data:
+ return [ 0.0 for c in self.categories ]
+
values = []
- for cat in self.categories:
- values.append(self.prof.getvalue(job.name, cpu, cat))
+ for category in self.categories:
+ values.append(data.get(category, 0.0))
return values
+
+ def dump(self):
+ for run,cpu,data in self.alldata():
+ print 'run %s, cpu %s' % (run, cpu)
+ data.dump()
+ print
+
+ def write_dot(self, threshold, jobfile=None, jobs=None):
+ import pydot
+
+ if jobs is None:
+ jobs = [ job for job in jobfile.jobs() ]
+
+ for job in jobs:
+ cpu = '%s.full%d' % (job.system, self.cpu)
+ symbols = self.getdata(job.name, cpu)
+ if not symbols:
+ continue
+
+ dot = pydot.Dot()
+ symbols.tree.dot(dot, threshold=threshold)
+ dot.write(symbols.filename[:-3] + 'dot')
+
+ def write_txt(self, jobfile=None, jobs=None, limit=None):
+ if jobs is None:
+ jobs = [ job for job in jobfile.jobs() ]
+
+ for job in jobs:
+ cpu = '%s.full%d' % (job.system, self.cpu)
+ symbols = self.getdata(job.name, cpu)
+ if not symbols:
+ continue
+
+ output = file(symbols.filename[:-3] + 'txt', 'w')
+ symbols.display(output, limit)
+
+ def display(self, jobfile=None, jobs=None, limit=None):
+ if jobs is None:
+ jobs = [ job for job in jobfile.jobs() ]
+
+ maxsymlen = 0
+
+ thejobs = []
+ for job in jobs:
+ cpu = '%s.full%d' % (job.system, self.cpu)
+ symbols = self.getdata(job.name, cpu)
+ if symbols:
+ thejobs.append(job)
+ maxsymlen = max(maxsymlen, symbols.maxsymlen)
+
+ for job in thejobs:
+ cpu = '%s.full%d' % (job.system, self.cpu)
+ symbols = self.getdata(job.name, cpu)
+ print job.name
+ symbols.display(limit=limit, maxsymlen=maxsymlen)
+ print
+
+
+from categories import func_categorize, pc_categorize
+class PCProfile(Profile):
+ def __init__(self, categorize=pc_categorize):
+ super(PCProfile, self).__init__(PCData, categorize)
+
+
+class FuncProfile(Profile):
+ def __init__(self, categorize=func_categorize):
+ super(FuncProfile, self).__init__(FuncData, categorize)
+
+def usage(exitcode = None):
+ print '''\
+Usage: %s [-bc] [-g <dir>] [-j <jobfile>] [-n <num>]
+
+ -c groups symbols into categories
+ -b dumps data for bar charts
+ -d generate dot output
+ -g <d> draw graphs and send output to <d>
+ -j <jobfile> specify a different jobfile (default is Test.py)
+ -n <n> selects number of top symbols to print (default 5)
+''' % sys.argv[0]
+
+ if exitcode is not None:
+ sys.exit(exitcode)
+
+if __name__ == '__main__':
+ import getopt, re, sys
+ from os.path import expanduser
+ from output import StatOutput
+ from jobfile import JobFile
+
+ # default option values
+ numsyms = 10
+ graph = None
+ cpus = [ 0 ]
+ categorize = False
+ showidle = True
+ funcdata = True
+ jobfilename = 'Test.py'
+ dodot = False
+ dotformat = 'raw'
+ textout = False
+ threshold = 0.01
+ inputfile = None
+
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], 'C:cdD:f:g:ij:n:pT:t')
+ except getopt.GetoptError:
+ usage(2)
+
+ for o,a in opts:
+ if o == '-C':
+ cpus = [ int(x) for x in a.split(',') ]
+ elif o == '-c':
+ categorize = True
+ elif o == '-D':
+ dotformat = a
+ elif o == '-d':
+ dodot = True
+ elif o == '-f':
+ inputfile = expanduser(a)
+ elif o == '-g':
+ graph = a
+ elif o == '-i':
+ showidle = False
+ elif o == '-j':
+ jobfilename = a
+ elif o == '-n':
+ numsyms = int(a)
+ elif o == '-p':
+ funcdata = False
+ elif o == '-T':
+ threshold = float(a)
+ elif o == '-t':
+ textout = True
+
+ if args:
+ print "'%s'" % args, len(args)
+ usage(1)
+
+ if inputfile:
+ data = FuncData(inputfile)
+
+ if dodot:
+ import pydot
+ dot = pydot.Dot()
+ data.dot(dot, threshold=threshold)
+ #dot.orientation = 'landscape'
+ #dot.ranksep='equally'
+ #dot.rank='samerank'
+ dot.write(dotfile, format=dotformat)
+ else:
+ data.display(limit=numsyms)
+
+ else:
+ jobfile = JobFile(jobfilename)
+
+ if funcdata:
+ profile = FuncProfile()
+ else:
+ profile = PCProfile()
+
+ if not categorize:
+ profile.categorize = None
+ profile.inputdir(jobfile.rootdir)
+
+ if graph:
+ for cpu in cpus:
+ profile.cpu = cpu
+ if funcdata:
+ name = 'funcstacks%d' % cpu
+ else:
+ name = 'stacks%d' % cpu
+ output = StatOutput(name, jobfile, info=profile)
+ output.graph(graph)
+
+ if dodot:
+ for cpu in cpus:
+ profile.cpu = cpu
+ profile.write_dot(jobfile=jobfile, threshold=threshold)
+
+ if textout:
+ for cpu in cpus:
+ profile.cpu = cpu
+ profile.write_txt(jobfile=jobfile)
+
+ if not graph and not textout and not dodot:
+ for cpu in cpus:
+ if not categorize:
+ profile.categorize = None
+ profile.cpu = cpu
+ profile.display(jobfile=jobfile, limit=numsyms)
diff --git a/util/stats/stats.py b/util/stats/stats.py
index c53d77d54..e481a794c 100755
--- a/util/stats/stats.py
+++ b/util/stats/stats.py
@@ -98,29 +98,27 @@ def commands(options, command, args):
raise CommandException
- import db, info
- info.source = db.Database()
- info.source.host = options.host
- info.source.db = options.db
- info.source.passwd = options.passwd
- info.source.user = options.user
- info.source.connect()
- #info.source.update_dict(globals())
-
- if type(options.get) is str:
- info.source.get = options.get
+ import db
+ source = db.Database()
+ source.host = options.host
+ source.db = options.db
+ source.passwd = options.passwd
+ source.user = options.user
+ source.connect()
+ #source.update_dict(globals())
+
+ if type(options.method) is str:
+ source.method = options.method
if options.runs is None:
- runs = info.source.allRuns
+ runs = source.allRuns
else:
rx = re.compile(options.runs)
runs = []
- for run in info.source.allRuns:
+ for run in source.allRuns:
if rx.match(run.name):
runs.append(run)
- info.display_run = runs[0].run
-
if command == 'runs':
user = None
opts, args = getopts(args, '-u')
@@ -129,14 +127,14 @@ def commands(options, command, args):
for o,a in opts:
if o == '-u':
user = a
- info.source.listRuns(user)
+ source.listRuns(user)
return
if command == 'stats':
if len(args) == 0:
- info.source.listStats()
+ source.listStats()
elif len(args) == 1:
- info.source.listStats(args[0])
+ source.listStats(args[0])
else:
raise CommandException
@@ -144,9 +142,9 @@ def commands(options, command, args):
if command == 'bins':
if len(args) == 0:
- info.source.listBins()
+ source.listBins()
elif len(args) == 1:
- info.source.listBins(args[0])
+ source.listBins(args[0])
else:
raise CommandException
@@ -154,9 +152,9 @@ def commands(options, command, args):
if command == 'formulas':
if len(args) == 0:
- info.source.listFormulas()
+ source.listFormulas()
elif len(args) == 1:
- info.source.listFormulas(args[0])
+ source.listFormulas(args[0])
else:
raise CommandException
@@ -166,7 +164,7 @@ def commands(options, command, args):
if len(args):
raise CommandException
- info.source.listTicks(runs)
+ source.listTicks(runs)
return
if command == 'stability':
@@ -177,8 +175,8 @@ def commands(options, command, args):
merge = int(args[0])
except ValueError:
usage()
- stats = info.source.getStat(args[1])
- info.source.get = "sum"
+ stats = source.getStat(args[1])
+ source.method = 'sum'
def disp(*args):
print "%-20s %12s %12s %4s %5s %5s %5s %10s" % args
@@ -195,18 +193,17 @@ def commands(options, command, args):
#loop through all the selected runs
for run in runs:
- info.display_run = run.run;
- runTicks = info.source.retTicks([ run ])
+ runTicks = source.retTicks([ run ])
#throw away the first one, it's 0
runTicks.pop(0)
- info.globalTicks = runTicks
+ source.ticks = runTicks
avg = 0
stdev = 0
numoutsideavg = 0
numoutside1std = 0
numoutside2std = 0
pairRunTicks = []
- if float(stat) == 1e300*1e300:
+ if value(stat, run.run) == 1e300*1e300:
continue
for t in range(0, len(runTicks)-(merge-1), merge):
tempPair = []
@@ -215,17 +212,17 @@ def commands(options, command, args):
pairRunTicks.append(tempPair)
#loop through all the various ticks for each run
for tick in pairRunTicks:
- info.globalTicks = tick
- avg += float(stat)
+ source.ticks = tick
+ avg += value(stat, run.run)
avg /= len(pairRunTicks)
for tick in pairRunTicks:
- info.globalTicks = tick
- val = float(stat)
+ source.ticks = tick
+ val = value(stat, run.run)
stdev += pow((val-avg),2)
stdev = math.sqrt(stdev / len(pairRunTicks))
for tick in pairRunTicks:
- info.globalTicks = tick
- val = float(stat)
+ source.ticks = tick
+ val = value(stat, run.run)
if (val < (avg * .9)) or (val > (avg * 1.1)):
numoutsideavg += 1
if (val < (avg - stdev)) or (val > (avg + stdev)):
@@ -264,9 +261,9 @@ def commands(options, command, args):
if options.ticks:
if not options.graph:
print 'only displaying sample %s' % options.ticks
- info.globalTicks = [ int(x) for x in options.ticks.split() ]
+ source.ticks = [ int(x) for x in options.ticks.split() ]
- from output import StatOutput
+ import output
def display():
if options.graph:
@@ -280,12 +277,12 @@ def commands(options, command, args):
raise CommandException
if command == 'stat':
- stats = info.source.getStat(args[0])
+ stats = source.getStat(args[0])
if command == 'formula':
stats = eval(args[0])
for stat in stats:
- output = StatOutput(stat.name, options.jobfile)
+ output = output.StatOutput(stat.name, options.jobfile, source)
output.stat = stat
output.label = stat.name
display()
@@ -295,12 +292,11 @@ def commands(options, command, args):
if len(args):
raise CommandException
- system = info.source.__dict__[options.system]
-
- from proxy import ProxyGroup
- sim_ticks = info.source['sim_ticks']
- sim_seconds = info.source['sim_seconds']
- proxy = ProxyGroup(system = info.source[options.system])
+ system = source.__dict__[options.system]
+ from info import ProxyGroup
+ sim_ticks = source['sim_ticks']
+ sim_seconds = source['sim_seconds']
+ proxy = ProxyGroup(system = source[options.system])
system = proxy.system
etherdev = system.tsunami.etherdev0
@@ -309,7 +305,7 @@ def commands(options, command, args):
packets = etherdev.rxPackets + etherdev.txPackets
bps = etherdev.rxBandwidth + etherdev.txBandwidth
- output = StatOutput(command, options.jobfile)
+ output = output.StatOutput(command, options.jobfile, source)
if command == 'usertime':
import copy
@@ -460,15 +456,16 @@ if __name__ == '__main__':
options.user = getpass.getuser()
options.runs = None
options.system = 'client'
- options.get = None
+ options.method = None
options.binned = False
options.graph = False
options.ticks = False
options.printmode = 'G'
+ jobfilename = 'Test.py'
options.jobfile = None
options.all = False
- opts, args = getopts(sys.argv[1:], '-BEFG:ad:g:h:j:pr:s:u:T:')
+ opts, args = getopts(sys.argv[1:], '-BEFJad:g:h:j:m:pr:s:u:T:')
for o,a in opts:
if o == '-B':
options.binned = True
@@ -476,8 +473,6 @@ if __name__ == '__main__':
options.printmode = 'E'
if o == '-F':
options.printmode = 'F'
- if o == '-G':
- options.get = a
if o == '-a':
options.all = True
if o == '-d':
@@ -487,8 +482,12 @@ if __name__ == '__main__':
options.graphdir = a
if o == '-h':
options.host = a
+ if o == '-J':
+ jobfilename = None
if o == '-j':
- options.jobfile = JobFile(a)
+ jobfilename = a
+ if o == '-m':
+ options.method = a
if o == '-p':
options.passwd = getpass.getpass()
if o == '-r':
@@ -500,7 +499,8 @@ if __name__ == '__main__':
if o == '-T':
options.ticks = a
- if options.jobfile:
+ if jobfilename:
+ options.jobfile = JobFile(jobfilename)
if not options.host:
options.host = options.jobfile.dbhost
if not options.db: