Remove TRAPZ
This commit is contained in:
@@ -367,13 +367,6 @@ LINUXINCLUDE := \
|
||||
-Iinclude \
|
||||
$(USERINCLUDE)
|
||||
|
||||
# ACOS_MOD_BEGIN
|
||||
ifeq ($(USE_TRAPZ), true)
|
||||
CFLAGS_KERNEL += -DENABLE_TRAPZ
|
||||
CFLAGS_MODULE += -DENABLE_TRAPZ
|
||||
endif
|
||||
# ACOS_MOD_END
|
||||
|
||||
KBUILD_CPPFLAGS := -D__KERNEL__
|
||||
|
||||
KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
CONFIG_TRAPZ=y
|
||||
CONFIG_TRAPZ_TP=y
|
||||
CONFIG_TRAPZ_TRIGGER=y
|
||||
CONFIG_TRAPZ_PVA=n
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#include <trace/events/power.h>
|
||||
#include <linux/trapz.h> /* ACOS_MOD_ONELINE */
|
||||
|
||||
/**
|
||||
* The "cpufreq driver" - the arch- or hardware-dependent low
|
||||
@@ -337,11 +336,6 @@ void __cpufreq_notify_transition(struct cpufreq_policy *policy,
|
||||
pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
|
||||
(unsigned long)freqs->cpu);
|
||||
trace_cpu_frequency(freqs->new, freqs->cpu);
|
||||
|
||||
TRAPZ_DESCRIBE(TRAPZ_KERN_CPU, CPUFreq, "CPU Frequency Change");
|
||||
TRAPZ_LOG_PRINTF(TRAPZ_LOG_DEBUG, 0, TRAPZ_KERN_CPU, CPUFreq,
|
||||
"cpu freq=%d", freqs->new, 0, 0, 0);
|
||||
|
||||
srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
|
||||
CPUFREQ_POSTCHANGE, freqs);
|
||||
if (likely(policy) && likely(policy->cpu == freqs->cpu))
|
||||
|
||||
@@ -22,11 +22,6 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include "mtkfb_info.h"
|
||||
#include <linux/dma-mapping.h>
|
||||
/* ACOS_MOD_BEGIN */
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/amz_atrace.h>
|
||||
/* ACOS_MOD_END */
|
||||
#include <linux/trapz.h> /* ACOS_MOD_ONELINE */
|
||||
#if defined(MTK_OVERLAY_ENGINE_SUPPORT)
|
||||
#include "disp_ovl_engine_api.h"
|
||||
#include "disp_ovl_engine_core.h"
|
||||
@@ -1404,16 +1399,8 @@ static void _DISP_HWDoneCallback(void* pParam)
|
||||
|
||||
static void _DISP_VSyncCallback(void* pParam)
|
||||
{
|
||||
static volatile int atrace_toggle; /* ACOS_MOD_ONELINE */
|
||||
MMProfileLog(MTKFB_MMP_Events.VSync, MMProfileFlagPulse);
|
||||
vsync_wq_flag = 1;
|
||||
/* ACOS_MOD_BEGIN */
|
||||
TRAPZ_DESCRIBE(TRAPZ_KERN_DISP, Vsyncirq,
|
||||
"Primary VSYNC interrupt");
|
||||
TRAPZ_LOG(TRAPZ_LOG_DEBUG, TRAPZ_CAT_KERNEL, TRAPZ_KERN_DISP,
|
||||
Vsyncirq, 0, 0, 0, 0);
|
||||
ATRACE_COUNTER("Vsyncirq", atrace_toggle ^= 1);
|
||||
/* ACOS_MOD_END */
|
||||
wake_up_interruptible(&vsync_wq);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +142,4 @@ source "drivers/staging/dwc2/Kconfig"
|
||||
|
||||
source "drivers/staging/amazon/Kconfig"
|
||||
|
||||
source "drivers/staging/trapz/Kconfig"
|
||||
|
||||
endif # STAGING
|
||||
|
||||
@@ -63,4 +63,3 @@ obj-$(CONFIG_ZCACHE) += zcache/
|
||||
obj-$(CONFIG_GOLDFISH) += goldfish/
|
||||
obj-$(CONFIG_USB_DWC2) += dwc2/
|
||||
obj-$(CONFIG_AMAZON) += amazon/
|
||||
obj-$(CONFIG_TRAPZ) += trapz/
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
config TRAPZ
|
||||
bool "Tracing and Profiling for Zpeed"
|
||||
default n
|
||||
help
|
||||
enable
|
||||
TRAPZ tool
|
||||
- Tracing and Profilling
|
||||
for Zpeed
|
||||
|
||||
|
||||
|
||||
config TRAPZ_TP
|
||||
bool "Globally enable trapz trace points in kernel"
|
||||
default n
|
||||
depends on TRAPZ
|
||||
help
|
||||
This enables trapz tracepoints.
|
||||
If this is disabled,
|
||||
and CONFIG_TRAPZ is enabled,
|
||||
userspace trapz tracing is still functional.
|
||||
|
||||
config TRAPZ_TRIGGER
|
||||
bool "Include ability to trigger events based on latency"
|
||||
default n
|
||||
depends on TRAPZ
|
||||
help
|
||||
This feature issues uevents if a trigger is fired. The uevents can then
|
||||
be trapped in user space to react
|
||||
@@ -1,5 +0,0 @@
|
||||
ifneq ($(CONFIG_TRAPZ_TRIGGER),)
|
||||
obj-$(CONFIG_TRAPZ) := trapz.o trapz_trigger.o
|
||||
else
|
||||
obj-$(CONFIG_TRAPZ) := trapz.o
|
||||
endif
|
||||
@@ -1,971 +0,0 @@
|
||||
/*
|
||||
* trapz.c
|
||||
*
|
||||
* TRAPZ (TRAcing and Profiling for Zpeed) Log Driver
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Andy Prunicki (prunicki@lab126.com)
|
||||
* Martin Unsal (munsal@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/trapz.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "trapz_device.h"
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
#include "trapz_trigger.h"
|
||||
#endif
|
||||
|
||||
#define TRAPZ_VERSION "0.2"
|
||||
/* The buffer size is the number of components * 2 bits, giving 3 values
|
||||
for each component. */
|
||||
#define TRAPZ_LOG_LEVEL_BUFF_SIZE ((TRAPZ_MAX_COMP_ID + 1) >> 2)
|
||||
#define TRAPZ_DEFAULT_BUFFER_SIZE 10000
|
||||
|
||||
#define MAX_INT_DIGIT 10
|
||||
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
/* The trigger implementation is admittedly not performant for very many
|
||||
triggers. We have weak requirements around triggers, and thus a simple,
|
||||
small linked list is our current implementation until we have more
|
||||
concrete requirements. */
|
||||
LIST_HEAD(trigger_head);
|
||||
static int g_trigger_count;
|
||||
#endif
|
||||
|
||||
static struct _trapz_device_info {
|
||||
struct miscdevice trapz_device;
|
||||
struct device_attribute version_attr;
|
||||
struct device_attribute enabled_attr;
|
||||
struct device_attribute buff_size_attr;
|
||||
struct device_attribute count_attr;
|
||||
struct device_attribute total_attr;
|
||||
struct device_attribute clear_buff_attr;
|
||||
struct device_attribute reset_attr;
|
||||
/* spin lock for SMP */
|
||||
spinlock_t lock;
|
||||
atomic_t blocked;
|
||||
/* indicates if device is enabled */
|
||||
atomic_t enabled;
|
||||
/* indicates if there is a pending buffer resize */
|
||||
int pending_buffsize_change;
|
||||
wait_queue_head_t wq;
|
||||
} trapz_device_info = {
|
||||
.enabled = ATOMIC_INIT(0),
|
||||
.blocked = ATOMIC_INIT(0),
|
||||
.pending_buffsize_change = 0
|
||||
};
|
||||
|
||||
static struct trapz_data {
|
||||
/* base address of internal entry buffer */
|
||||
trapz_entry_t *pBuffer;
|
||||
/* first entry address past the end of the buffer */
|
||||
trapz_entry_t *pLimit;
|
||||
/* entries are added at the head */
|
||||
trapz_entry_t *pHead;
|
||||
/* entries are removed from the tail */
|
||||
trapz_entry_t *pTail;
|
||||
/* the buffer will hold this many entries */
|
||||
int bufferSize;
|
||||
/* the buffer contains this many entries */
|
||||
int count;
|
||||
/* count of entries added since the last reset */
|
||||
int total;
|
||||
/* the rolling data counter (1 thru 255) */
|
||||
u8 counter;
|
||||
/* log levels for OS components */
|
||||
char *os_comp_loglevels;
|
||||
/* log levels for app components */
|
||||
char *app_comp_loglevels;
|
||||
} g_data = {
|
||||
.counter = 1
|
||||
};
|
||||
|
||||
static int trapz_open(struct inode *, struct file *);
|
||||
static int trapz_release(struct inode *, struct file *);
|
||||
static ssize_t trapz_read(struct file *, char *, size_t, loff_t *);
|
||||
static ssize_t trapz_write(struct file *, const char *, size_t, loff_t *);
|
||||
static loff_t trapz_llseek(struct file *filp, loff_t off, int whence);
|
||||
static long trapz_ioctl(struct file *, unsigned int, unsigned long);
|
||||
static ssize_t attr_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
static ssize_t attr_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count);
|
||||
|
||||
|
||||
#define TRAPZ_CREATE_RO_ATTR(_dev_info, _name) \
|
||||
_dev_info._name##_attr.attr.name = __stringify(_name); \
|
||||
_dev_info._name##_attr.attr.mode = (S_IRUSR|S_IRGRP|S_IROTH); \
|
||||
_dev_info._name##_attr.show = attr_show
|
||||
|
||||
#define TRAPZ_CREATE_RW_ATTR(_dev_info, _name) \
|
||||
_dev_info._name##_attr.attr.name = __stringify(_name); \
|
||||
_dev_info._name##_attr.attr.mode = (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); \
|
||||
_dev_info._name##_attr.show = attr_show; \
|
||||
_dev_info._name##_attr.store = attr_store
|
||||
|
||||
const struct file_operations fops = {
|
||||
.llseek = trapz_llseek,
|
||||
.read = trapz_read,
|
||||
.write = trapz_write,
|
||||
.open = trapz_open,
|
||||
.release = trapz_release,
|
||||
.unlocked_ioctl = trapz_ioctl,
|
||||
};
|
||||
|
||||
/*============================================================================*/
|
||||
|
||||
/**
|
||||
* Kernel API used to log trapz trace points.
|
||||
*/
|
||||
SYSCALL_DEFINE6(trapz, unsigned int, ctrl, unsigned int, extra1, unsigned int,
|
||||
extra2, unsigned int, extra3, unsigned int,
|
||||
extra4, struct trapz_info __user *, ti)
|
||||
{
|
||||
return systrapz(ctrl, extra1, extra2, extra3, extra4, ti);
|
||||
}
|
||||
|
||||
static inline trapz_entry_t *get_entry(void)
|
||||
{
|
||||
trapz_entry_t *entry;
|
||||
|
||||
if (g_data.count >= g_data.bufferSize) {
|
||||
/* We've wrapped the circular buffer.
|
||||
Move the tail accordingly. */
|
||||
g_data.pTail++;
|
||||
if (g_data.pTail >= g_data.pLimit)
|
||||
g_data.pTail = g_data.pBuffer;
|
||||
g_data.count--;
|
||||
}
|
||||
|
||||
entry = g_data.pHead++;
|
||||
if (g_data.pHead >= g_data.pLimit)
|
||||
g_data.pHead = g_data.pBuffer;
|
||||
g_data.count++;
|
||||
g_data.total++;
|
||||
memset(entry, 0, sizeof(trapz_entry_t));
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal kernel API used to log trapz trace points.
|
||||
*/
|
||||
long systrapz(unsigned int ctrl, unsigned int extra1, unsigned int extra2,
|
||||
unsigned int extra3, unsigned int extra4, struct trapz_info __user *ti)
|
||||
{
|
||||
unsigned long flags;
|
||||
int filtered = 1, cpu = 0;
|
||||
int level, cat_id, comp_id, trace_id;
|
||||
trapz_entry_t *pEntry1 = NULL, *pEntry2 = NULL;
|
||||
trapz_info_t kti;
|
||||
struct timespec ts;
|
||||
u8 counter, extra_count = 0;
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
trapz_trigger_event_t trigger_event;
|
||||
#endif
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) == 0)
|
||||
return -EBUSY;
|
||||
|
||||
level = TRAPZ_LEVEL_OUT(ctrl);
|
||||
cat_id = TRAPZ_CAT_ID_OUT(ctrl);
|
||||
comp_id = TRAPZ_COMP_ID_OUT(ctrl);
|
||||
trace_id = TRAPZ_TRACE_ID_OUT(ctrl);
|
||||
|
||||
/* Filter out events based on log level */
|
||||
if (trapz_check_loglevel(level, cat_id, comp_id)) {
|
||||
/* Not filtered by log level */
|
||||
getnstimeofday(&ts);
|
||||
filtered = 0;
|
||||
/*Determine if we need an additional
|
||||
record to hold the extras */
|
||||
if (extra3 != 0 || extra4 != 0
|
||||
|| extra1 > 0xff || extra2 > 0xff) {
|
||||
/* Need extra record */
|
||||
extra_count = 1;
|
||||
}
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
trigger_event.trigger.start_trace_point = 0;
|
||||
process_trigger(ctrl, &trigger_event, &trigger_head,
|
||||
&g_trigger_count, &ts);
|
||||
#endif
|
||||
|
||||
pEntry1 = get_entry();
|
||||
if (extra_count > 0)
|
||||
pEntry2 = get_entry();
|
||||
counter = g_data.counter++;
|
||||
if (counter == 0) {
|
||||
/* 0 is invalid */
|
||||
counter = g_data.counter++;
|
||||
}
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
}
|
||||
if (filtered) {
|
||||
/* Trapz call filtered out, return time if requested */
|
||||
if (ti != NULL) {
|
||||
getnstimeofday(&ts);
|
||||
kti.ts = ts;
|
||||
kti.counter = -1;
|
||||
|
||||
if (copy_to_user(ti, &kti, sizeof(kti)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
cpu = raw_smp_processor_id();
|
||||
|
||||
if (!in_interrupt()) {
|
||||
pEntry1->pid = current->tgid;
|
||||
pEntry1->tid = current->pid;
|
||||
}
|
||||
|
||||
pEntry1->ctrl = TRAPZ_BUFF_REC_TYPE_MASK | (cat_id & 0x3) << 4
|
||||
| (extra_count & TRAPZ_BUFF_EXTRA_COUNT_MASK);
|
||||
pEntry1->counter = counter;
|
||||
if (extra_count == 0) {
|
||||
pEntry1->extra_1 = extra1;
|
||||
pEntry1->extra_2 = extra2;
|
||||
} else {
|
||||
pEntry1->extra_1 = 0;
|
||||
pEntry1->extra_2 = 0;
|
||||
}
|
||||
pEntry1->cpu = cpu;
|
||||
pEntry1->comp_trace_id[0] = comp_id >> 4;
|
||||
pEntry1->comp_trace_id[1] =
|
||||
((comp_id & 0x0f) << 4) | ((trace_id & 0xf00) >> 8);
|
||||
pEntry1->comp_trace_id[2] = (trace_id & 0xff);
|
||||
pEntry1->ts = ts;
|
||||
pEntry1->ctrl |= TRAPZ_BUFF_COMPLETE_MASK;
|
||||
if (pEntry2 != NULL) {
|
||||
pEntry2->counter = counter;
|
||||
pEntry2->format = TRAPZ_EXTRA_FORMAT_INT;
|
||||
pEntry2->extras[0] = extra1;
|
||||
pEntry2->extras[1] = extra2;
|
||||
pEntry2->extras[2] = extra3;
|
||||
pEntry2->extras[3] = extra4;
|
||||
pEntry2->ctrl = TRAPZ_BUFF_COMPLETE_MASK;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
if (trigger_event.trigger.start_trace_point != 0) {
|
||||
send_trigger_uevent(&trigger_event,
|
||||
&(trapz_device_info.trapz_device.this_device->kobj));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Return time and sequence info if requested */
|
||||
if (ti != NULL) {
|
||||
trapz_info_t kti;
|
||||
kti.ts = ts;
|
||||
kti.counter = counter;
|
||||
|
||||
if (copy_to_user(ti, &kti, sizeof(kti)))
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* unblock if needed */
|
||||
if (atomic_read(&trapz_device_info.blocked) != 0) {
|
||||
atomic_set(&trapz_device_info.blocked, 0);
|
||||
wake_up_interruptible(&(trapz_device_info.wq));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(systrapz);
|
||||
|
||||
static int clear_buffer(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) == 0)
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
g_data.total = g_data.count = g_data.counter = 0;
|
||||
g_data.pHead = g_data.pTail = g_data.pBuffer;
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trapz_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
unsigned long flags;
|
||||
/* set offset to be the current lowest sequence */
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
file->f_pos = g_data.total - g_data.count;
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trapz_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static loff_t trapz_llseek(struct file *filp, loff_t off, int whence)
|
||||
{
|
||||
loff_t newpos;
|
||||
switch (whence) {
|
||||
case 0: /* SEEK_SET */
|
||||
newpos = off;
|
||||
break;
|
||||
|
||||
case 1: /* SEEK_CUR */
|
||||
newpos = filp->f_pos + off;
|
||||
break;
|
||||
|
||||
case 2: /* SEEK_END */
|
||||
newpos = g_data.total + off;
|
||||
break;
|
||||
|
||||
default: /* can't happen */
|
||||
return -EINVAL;
|
||||
}
|
||||
if (newpos < 0)
|
||||
return -EINVAL;
|
||||
filp->f_pos = newpos;
|
||||
return newpos;
|
||||
}
|
||||
|
||||
/*
|
||||
* reads out trapz entries from store
|
||||
*/
|
||||
static ssize_t trapz_read(struct file *filp, char *buffer,
|
||||
size_t length, loff_t *offset)
|
||||
{
|
||||
for (;;) {
|
||||
int base = g_data.total - g_data.count;
|
||||
int index;
|
||||
trapz_entry_t *pEnd, *pStart;
|
||||
int objcnt, objlim;
|
||||
int size;
|
||||
|
||||
objlim = length / sizeof(trapz_entry_t);
|
||||
|
||||
if (*offset < base)
|
||||
*offset = base;
|
||||
if (*offset >= g_data.total) {
|
||||
if (filp->f_flags & O_NONBLOCK)
|
||||
return 0;
|
||||
else {
|
||||
atomic_set(&trapz_device_info.blocked, 1);
|
||||
if (wait_event_interruptible(
|
||||
trapz_device_info.wq,
|
||||
atomic_read(
|
||||
&trapz_device_info.blocked) == 0)
|
||||
== -ERESTARTSYS)
|
||||
return 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
index = *offset - g_data.total + g_data.count;
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
pEnd = g_data.pHead;
|
||||
pStart = g_data.pTail + index;
|
||||
if (pStart >= g_data.pLimit)
|
||||
pStart -= g_data.bufferSize;
|
||||
if (pStart < pEnd) {
|
||||
/* We intentionally do not copy in the current entry as
|
||||
* it is racy.
|
||||
*/
|
||||
objcnt = pEnd - pStart;
|
||||
} else {
|
||||
/* We slop up to the end of the buffer in the case that
|
||||
* our entry point is before our tail, keeps it as one
|
||||
* copy, ie simpler.
|
||||
*/
|
||||
objcnt = g_data.pLimit - pStart;
|
||||
}
|
||||
if (objcnt > objlim)
|
||||
objcnt = objlim;
|
||||
size = objcnt * sizeof(trapz_entry_t);
|
||||
if (copy_to_user(buffer, pStart, size))
|
||||
return -EFAULT;
|
||||
/* Now we figure out if we wrapped. */
|
||||
if (g_data.total - *offset > g_data.bufferSize) {
|
||||
/* Wrapped, start over :( */
|
||||
*offset = g_data.total - g_data.count;
|
||||
continue;
|
||||
}
|
||||
*offset += objcnt;
|
||||
return size;
|
||||
}
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
static ssize_t trapz_write(struct file *filp, const char *buffer,
|
||||
size_t length, loff_t *offset)
|
||||
{
|
||||
/* writes are not allowed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void init_logbuffers(const int os_val, const int app_val)
|
||||
{
|
||||
memset(g_data.os_comp_loglevels, os_val, TRAPZ_LOG_LEVEL_BUFF_SIZE);
|
||||
memset(g_data.app_comp_loglevels, app_val, TRAPZ_LOG_LEVEL_BUFF_SIZE);
|
||||
}
|
||||
|
||||
int trapz_check_loglevel(const int level, const int cat_id,
|
||||
const int component_id)
|
||||
{
|
||||
int rc = 0;
|
||||
int byteIdx, bitIdx, bufflevel;
|
||||
char *buffer;
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) != 0 && component_id >= 0) {
|
||||
if (level >= TRAPZ_LOG_VERBOSE && level <= TRAPZ_LOG_OFF) {
|
||||
if (cat_id == TRAPZ_CAT_APPS)
|
||||
buffer = g_data.app_comp_loglevels;
|
||||
else
|
||||
buffer = g_data.os_comp_loglevels;
|
||||
|
||||
if (component_id <= TRAPZ_MAX_COMP_ID) {
|
||||
byteIdx = component_id >> 2;
|
||||
bitIdx = (component_id % 4) << 1;
|
||||
bufflevel
|
||||
= ((buffer[byteIdx]
|
||||
& (TRAPZ_LOG_OFF << bitIdx))
|
||||
>> bitIdx);
|
||||
if (bufflevel <= level)
|
||||
rc = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(trapz_check_loglevel);
|
||||
|
||||
static void set_comp_loglevel(char *buffer, const int level,
|
||||
const int component_id)
|
||||
{
|
||||
int byteIdx, bitIdx, bufflevel;
|
||||
|
||||
if (level >= TRAPZ_LOG_VERBOSE && level <= TRAPZ_LOG_OFF
|
||||
&& component_id >= 0
|
||||
&& component_id <= TRAPZ_MAX_COMP_ID) {
|
||||
byteIdx = component_id >> 2;
|
||||
bitIdx = (component_id % 4) << 1;
|
||||
bufflevel = level << bitIdx;
|
||||
buffer[byteIdx]
|
||||
= (buffer[byteIdx]
|
||||
& ((TRAPZ_LOG_OFF << bitIdx) ^ 0xFF))
|
||||
| bufflevel;
|
||||
}
|
||||
}
|
||||
|
||||
static void set_loglevel(const int level, const int cat_id,
|
||||
const int component_id)
|
||||
{
|
||||
int buffval = 0;
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) == 0)
|
||||
return;
|
||||
|
||||
if (component_id >= 0) {
|
||||
/* Setting the log level of just a component */
|
||||
if (cat_id == TRAPZ_CAT_APPS) {
|
||||
set_comp_loglevel(g_data.app_comp_loglevels,
|
||||
level, component_id);
|
||||
} else {
|
||||
set_comp_loglevel(g_data.os_comp_loglevels,
|
||||
level, component_id);
|
||||
}
|
||||
} else {
|
||||
switch (level) {
|
||||
case TRAPZ_LOG_OFF:
|
||||
buffval = 0xFF;
|
||||
break;
|
||||
case TRAPZ_LOG_INFO:
|
||||
buffval = 0xAA;
|
||||
break;
|
||||
case TRAPZ_LOG_DEBUG:
|
||||
buffval = 0x55;
|
||||
break;
|
||||
case TRAPZ_LOG_VERBOSE:
|
||||
buffval = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
if (cat_id >= 0) {
|
||||
/* Setting the log level of entire category */
|
||||
if (cat_id == TRAPZ_CAT_APPS) {
|
||||
memset(g_data.app_comp_loglevels, buffval,
|
||||
TRAPZ_LOG_LEVEL_BUFF_SIZE);
|
||||
} else {
|
||||
memset(g_data.os_comp_loglevels, buffval,
|
||||
TRAPZ_LOG_LEVEL_BUFF_SIZE);
|
||||
}
|
||||
} else {
|
||||
/* Setting the log level of the entire device */
|
||||
init_logbuffers(buffval, buffval);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void trapz_get_g_data(struct trapz_data *pData)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
*pData = g_data;
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
}
|
||||
|
||||
static int allocate_mem(int init_flags)
|
||||
{
|
||||
int ok = 1;
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) != 0)
|
||||
printk(KERN_ERR "trapz: attempted to allocate memory when enabled!\n");
|
||||
|
||||
if (((init_flags & 1) != 0) && g_data.bufferSize > 0) {
|
||||
if (g_data.pBuffer) {
|
||||
|
||||
kfree(g_data.pBuffer);
|
||||
g_data.pLimit
|
||||
= g_data.pHead
|
||||
= g_data.pTail
|
||||
= g_data.pBuffer
|
||||
= 0;
|
||||
}
|
||||
|
||||
g_data.pLimit = g_data.pHead = g_data.pTail = g_data.pBuffer =
|
||||
(trapz_entry_t *)
|
||||
kmalloc(sizeof(trapz_entry_t) * g_data.bufferSize,
|
||||
GFP_KERNEL);
|
||||
|
||||
if (g_data.pBuffer)
|
||||
g_data.pLimit += g_data.bufferSize;
|
||||
else
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
if (ok && ((init_flags & 2) != 0)) {
|
||||
if (g_data.os_comp_loglevels) {
|
||||
|
||||
kfree(g_data.os_comp_loglevels);
|
||||
g_data.os_comp_loglevels = 0;
|
||||
}
|
||||
if (g_data.app_comp_loglevels) {
|
||||
|
||||
kfree(g_data.app_comp_loglevels);
|
||||
g_data.app_comp_loglevels = 0;
|
||||
}
|
||||
|
||||
g_data.os_comp_loglevels
|
||||
= kmalloc(TRAPZ_LOG_LEVEL_BUFF_SIZE, GFP_KERNEL);
|
||||
g_data.app_comp_loglevels
|
||||
= kmalloc(TRAPZ_LOG_LEVEL_BUFF_SIZE, GFP_KERNEL);
|
||||
|
||||
if (!g_data.os_comp_loglevels || !g_data.app_comp_loglevels)
|
||||
ok = 0;
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
printk(KERN_ERR "trapz: cannot allocate kernel memory\n");
|
||||
|
||||
if (g_data.pBuffer) {
|
||||
|
||||
kfree(g_data.pBuffer);
|
||||
g_data.pLimit
|
||||
= g_data.pHead
|
||||
= g_data.pTail
|
||||
= g_data.pBuffer
|
||||
= 0;
|
||||
}
|
||||
if (g_data.os_comp_loglevels) {
|
||||
|
||||
kfree(g_data.os_comp_loglevels);
|
||||
g_data.os_comp_loglevels = 0;
|
||||
}
|
||||
if (g_data.app_comp_loglevels) {
|
||||
|
||||
kfree(g_data.app_comp_loglevels);
|
||||
g_data.app_comp_loglevels = 0;
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int enable_driver(int enable)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (enable) {
|
||||
/* Enabling device.
|
||||
Check to see if there is a pending buffer size
|
||||
change. If so, we need to re-allocate memory. */
|
||||
if (trapz_device_info.pending_buffsize_change) {
|
||||
trapz_device_info.pending_buffsize_change = 0;
|
||||
rc = allocate_mem(1);
|
||||
if (rc == 0)
|
||||
atomic_set(&trapz_device_info.enabled, 1);
|
||||
else {
|
||||
printk(KERN_ERR
|
||||
"trapz: could not enable trapz - out of memory\n");
|
||||
g_data.bufferSize = 0;
|
||||
}
|
||||
} else {
|
||||
/* No need to re-allocate, just enable */
|
||||
atomic_set(&trapz_device_info.enabled, 1);
|
||||
}
|
||||
} else
|
||||
atomic_set(&trapz_device_info.enabled, 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int set_buff_size(int new_buff_size)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (atomic_read(&trapz_device_info.enabled) == 0) {
|
||||
if (new_buff_size > 0 && new_buff_size <= 1000000) {
|
||||
g_data.bufferSize = new_buff_size;
|
||||
trapz_device_info.pending_buffsize_change = 1;
|
||||
} else {
|
||||
printk(KERN_INFO
|
||||
"trapz: attempted to set attribute buffer size to %d "
|
||||
"value must be between 0 an 1000000\n",
|
||||
new_buff_size);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_INFO
|
||||
"trapz: attempted to set buffer size when driver is active!\n");
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void reset_defaults(void)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
init_logbuffers(0xFF, 0xFF);
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
clear_triggers(&trigger_head, &g_trigger_count);
|
||||
#endif
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
}
|
||||
|
||||
static long trapz_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
long rc = -EINVAL;
|
||||
int level, cat_id, component_id;
|
||||
trapz_config config;
|
||||
struct trapz_data data;
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
unsigned long flags;
|
||||
trapz_trigger_t trigger;
|
||||
#endif
|
||||
|
||||
switch (cmd) {
|
||||
case TRAPZ_ENABLE_DRIVER:
|
||||
enable_driver(arg);
|
||||
break;
|
||||
case TRAPZ_GET_CONFIG:
|
||||
trapz_get_g_data(&data);
|
||||
config.bufferSize = data.bufferSize;
|
||||
config.count = data.count;
|
||||
config.total = data.total;
|
||||
rc = 0;
|
||||
if (copy_to_user((void __user *) arg, &config,
|
||||
sizeof(trapz_config))) {
|
||||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
case TRAPZ_SET_BUFFER_SIZE:
|
||||
rc = set_buff_size(arg);
|
||||
break;
|
||||
case TRAPZ_RESET_DEFAULTS:
|
||||
rc = 0;
|
||||
reset_defaults();
|
||||
break;
|
||||
case TRAPZ_CLEAR_BUFFER:
|
||||
rc = clear_buffer();
|
||||
break;
|
||||
case TRAPZ_GET_VERSION:
|
||||
/* copy entire string with terminating null */
|
||||
rc = 0;
|
||||
if (copy_to_user((void __user *)arg, TRAPZ_VERSION,
|
||||
strlen(TRAPZ_VERSION)+1)) {
|
||||
rc = -EFAULT;
|
||||
}
|
||||
break;
|
||||
case TRAPZ_SET_LOG_LEVEL:
|
||||
rc = 0;
|
||||
level
|
||||
= (arg &
|
||||
(TRAPZ_LEVEL_MASK <<
|
||||
(TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 2)))
|
||||
>> (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 2);
|
||||
cat_id = -1;
|
||||
component_id = -1;
|
||||
if (arg &
|
||||
(1 << (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 1))) {
|
||||
cat_id
|
||||
= (arg & (TRAPZ_CAT_ID_MASK << TRAPZ_COMP_ID_SIZE))
|
||||
>> TRAPZ_COMP_ID_SIZE;
|
||||
}
|
||||
if (arg & (1 << (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE)))
|
||||
component_id = arg & TRAPZ_COMP_ID_MASK;
|
||||
set_loglevel(level, cat_id, component_id);
|
||||
break;
|
||||
case TRAPZ_CHK_LOG_LEVEL:
|
||||
rc = 0;
|
||||
level
|
||||
= (arg &
|
||||
(TRAPZ_LEVEL_MASK <<
|
||||
(TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 2)))
|
||||
>> (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 2);
|
||||
cat_id = -1;
|
||||
component_id = -1;
|
||||
if (arg & (1 << (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE + 1))) {
|
||||
cat_id
|
||||
= (arg & (TRAPZ_CAT_ID_MASK << TRAPZ_COMP_ID_SIZE))
|
||||
>> TRAPZ_COMP_ID_SIZE;
|
||||
}
|
||||
if (arg & (1 << (TRAPZ_CAT_ID_SIZE + TRAPZ_COMP_ID_SIZE)))
|
||||
component_id = arg & TRAPZ_COMP_ID_MASK;
|
||||
if (cat_id >= 0 && component_id >= 0) {
|
||||
/* We only check for actual
|
||||
component ids - not general */
|
||||
rc = trapz_check_loglevel(level, cat_id, component_id);
|
||||
}
|
||||
break;
|
||||
#ifdef CONFIG_TRAPZ_TRIGGER
|
||||
case TRAPZ_ADD_TRIGGER:
|
||||
if (copy_from_user(&trigger,
|
||||
(void __user *) arg, sizeof(trigger)))
|
||||
rc = -EFAULT;
|
||||
else {
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
rc
|
||||
= add_trigger(&trigger,
|
||||
&trigger_head, &g_trigger_count);
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
}
|
||||
break;
|
||||
case TRAPZ_DEL_TRIGGER:
|
||||
if (copy_from_user(&trigger,
|
||||
(void __user *) arg, sizeof(trigger)))
|
||||
rc = -EFAULT;
|
||||
else {
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
rc = delete_trigger(&trigger,
|
||||
&trigger_head, &g_trigger_count);
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
}
|
||||
break;
|
||||
case TRAPZ_CLR_TRIGGERS:
|
||||
spin_lock_irqsave(&trapz_device_info.lock, flags);
|
||||
{
|
||||
clear_triggers(&trigger_head, &g_trigger_count);
|
||||
}
|
||||
spin_unlock_irqrestore(&trapz_device_info.lock, flags);
|
||||
rc = 0;
|
||||
break;
|
||||
case TRAPZ_CNT_TRIGGERS:
|
||||
rc = g_trigger_count;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static ssize_t attr_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf) {
|
||||
if (strcmp(attr->attr.name, "version") == 0)
|
||||
return snprintf(buf, MAX_INT_DIGIT, "%s", TRAPZ_VERSION);
|
||||
else if (strcmp(attr->attr.name, "enabled") == 0) {
|
||||
return snprintf(buf, MAX_INT_DIGIT, "%d",
|
||||
atomic_read(&trapz_device_info.enabled));
|
||||
} else if (strcmp(attr->attr.name, "buff_size") == 0)
|
||||
return snprintf(buf, MAX_INT_DIGIT, "%d", g_data.bufferSize);
|
||||
else if (strcmp(attr->attr.name, "count") == 0)
|
||||
return snprintf(buf, MAX_INT_DIGIT, "%d", g_data.count);
|
||||
else if (strcmp(attr->attr.name, "total") == 0)
|
||||
return snprintf(buf, MAX_INT_DIGIT, "%d", g_data.total);
|
||||
|
||||
return snprintf(buf, MAX_INT_DIGIT, "0");
|
||||
}
|
||||
|
||||
static ssize_t attr_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
unsigned long size_of_buff;
|
||||
if (strcmp(attr->attr.name, "enabled") == 0) {
|
||||
if (strncmp(buf, "0", 1) == 0)
|
||||
enable_driver(0);
|
||||
else
|
||||
enable_driver(1);
|
||||
} else if (strcmp(attr->attr.name, "buff_size") == 0) {
|
||||
ret = kstrtoul(buf, 0, &size_of_buff);
|
||||
if (ret == 0)
|
||||
set_buff_size(size_of_buff);
|
||||
} else if (strcmp(attr->attr.name, "clear_buff") == 0) {
|
||||
if (strncmp(buf, "1", 1) == 0)
|
||||
clear_buffer();
|
||||
} else if (strcmp(attr->attr.name, "reset") == 0) {
|
||||
if (strncmp(buf, "1", 1) == 0)
|
||||
reset_defaults();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup device sysfs attributes
|
||||
*/
|
||||
static int __init trapz_sysfs_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
TRAPZ_CREATE_RO_ATTR(trapz_device_info, version);
|
||||
TRAPZ_CREATE_RW_ATTR(trapz_device_info, enabled);
|
||||
TRAPZ_CREATE_RW_ATTR(trapz_device_info, buff_size);
|
||||
TRAPZ_CREATE_RO_ATTR(trapz_device_info, count);
|
||||
TRAPZ_CREATE_RO_ATTR(trapz_device_info, total);
|
||||
TRAPZ_CREATE_RW_ATTR(trapz_device_info, clear_buff);
|
||||
TRAPZ_CREATE_RW_ATTR(trapz_device_info, reset);
|
||||
rc = sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.version_attr.attr));
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.buff_size_attr.attr));
|
||||
}
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.count_attr.attr));
|
||||
}
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.total_attr.attr));
|
||||
}
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.clear_buff_attr.attr));
|
||||
}
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.reset_attr.attr));
|
||||
}
|
||||
if (!rc) {
|
||||
rc
|
||||
= sysfs_create_file(
|
||||
&(trapz_device_info.trapz_device.this_device->kobj),
|
||||
&(trapz_device_info.enabled_attr.attr));
|
||||
}
|
||||
|
||||
if (rc)
|
||||
printk(KERN_ERR "trapz: cannot create attributes(%d).\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the TRAPZ device.
|
||||
*/
|
||||
static int __init device_init(void)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
trapz_device_info.trapz_device.minor = MISC_DYNAMIC_MINOR;
|
||||
trapz_device_info.trapz_device.name = TRAPZ_DEV_NAME;
|
||||
trapz_device_info.trapz_device.fops = &fops;
|
||||
trapz_device_info.trapz_device.parent = NULL;
|
||||
|
||||
rc = misc_register(&trapz_device_info.trapz_device);
|
||||
|
||||
if (rc)
|
||||
printk(KERN_ERR "trapz: cannot register device (%d).\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int __init trapz_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Set global info to defaults */
|
||||
g_data.bufferSize = TRAPZ_DEFAULT_BUFFER_SIZE;
|
||||
g_data.pLimit = g_data.pHead = g_data.pTail = g_data.pBuffer = 0;
|
||||
g_data.os_comp_loglevels = g_data.app_comp_loglevels = 0;
|
||||
g_data.total = g_data.count = 0;
|
||||
|
||||
init_waitqueue_head(&trapz_device_info.wq);
|
||||
spin_lock_init(&trapz_device_info.lock);
|
||||
|
||||
rc = allocate_mem(3);
|
||||
if (!rc) {
|
||||
init_logbuffers(0xFF, 0xFF);
|
||||
if (!device_init() && !trapz_sysfs_init()) {
|
||||
atomic_set(&trapz_device_info.enabled, 1);
|
||||
printk(KERN_INFO "trapz: initialized. trapz enabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!rc)
|
||||
printk(KERN_INFO "trapz: initialization problem. trapz disabled\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
device_initcall(trapz_init);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
||||
#undef TRAPZ_CREATE_RO_ATTR
|
||||
#undef TRAPZ_CREATE_RW_ATTR
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* trapz_device.h
|
||||
*
|
||||
* TRAPZ (TRAcing and Profiling for Zpeed) Device header file
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Andy Prunicki (prunicki@lab126.com)
|
||||
* Martin Unsal (munsal@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* Copy this header file into any app that needs to read from the trapz
|
||||
* device file or make an ioctl call.
|
||||
*/
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
|
||||
#ifndef _LINUX_TRAPZ_DEVICE_H
|
||||
#define _LINUX_TRAPZ_DEVICE_H
|
||||
|
||||
#define TRAPZ_DEV_NAME "trapz"
|
||||
|
||||
typedef struct {
|
||||
int bufferSize; /* the buffer will hold this many entries */
|
||||
int count; /* the buffer contains this many entries */
|
||||
int total; /* count of entries added since the last reset */
|
||||
} trapz_config;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
struct {
|
||||
unsigned char ctrl;
|
||||
unsigned char counter;
|
||||
unsigned char extra_1;
|
||||
unsigned char extra_2;
|
||||
unsigned char cpu;
|
||||
unsigned char comp_trace_id[3];
|
||||
unsigned short pid;
|
||||
unsigned short tid;
|
||||
struct timespec ts; /* time stamp */
|
||||
};
|
||||
struct {
|
||||
unsigned char ctrl_e;
|
||||
unsigned char counter_e;
|
||||
unsigned char format;
|
||||
unsigned char unused;
|
||||
unsigned int extras[4];
|
||||
};
|
||||
};
|
||||
} trapz_entry_t;
|
||||
|
||||
/* ======================================== */
|
||||
/* ============== Triggers ================ */
|
||||
/* = Only available on configured kernels = */
|
||||
/* ======================================== */
|
||||
typedef struct {
|
||||
int start_trace_point;
|
||||
int end_trace_point;
|
||||
int trigger_id;
|
||||
int single_shot;
|
||||
} trapz_trigger_t;
|
||||
|
||||
typedef struct {
|
||||
trapz_trigger_t trigger;
|
||||
struct timespec start_ts;
|
||||
struct timespec end_ts;
|
||||
int trigger_active;
|
||||
} trapz_trigger_event_t;
|
||||
/* ======================================== */
|
||||
|
||||
/* ctrl field output masks */
|
||||
#define TRAPZ_LEVEL_MASK_OUT (TRAPZ_LEVEL_MASK << TRAPZ_LEVEL_OFFSET)
|
||||
#define TRAPZ_FLAGS_MASK_OUT (TRAPZ_FLAGS_MASK << TRAPZ_FLAGS_OFFSET)
|
||||
#define TRAPZ_CAT_ID_MASK_OUT (TRAPZ_CAT_ID_MASK << TRAPZ_CAT_ID_OFFSET)
|
||||
#define TRAPZ_COMP_ID_MASK_OUT (TRAPZ_COMP_ID_MASK << TRAPZ_COMP_ID_OFFSET)
|
||||
#define TRAPZ_TRACE_ID_MASK_OUT (TRAPZ_TRACE_ID_MASK << TRAPZ_TRACE_ID_OFFSET)
|
||||
|
||||
/* ctrl field shift out */
|
||||
#define TRAPZ_LEVEL_OUT(x) ((x & TRAPZ_LEVEL_MASK_OUT) >> TRAPZ_LEVEL_OFFSET)
|
||||
#define TRAPZ_FLAGS_OUT(x) ((x & TRAPZ_FLAGS_MASK_OUT) >> TRAPZ_FLAGS_OFFSET)
|
||||
#define TRAPZ_CAT_ID_OUT(x) ((x & TRAPZ_CAT_ID_MASK_OUT) >> TRAPZ_CAT_ID_OFFSET)
|
||||
#define TRAPZ_COMP_ID_OUT(x) \
|
||||
((x & TRAPZ_COMP_ID_MASK_OUT) >> TRAPZ_COMP_ID_OFFSET)
|
||||
#define TRAPZ_TRACE_ID_OUT(x) \
|
||||
((x & TRAPZ_TRACE_ID_MASK_OUT) >> TRAPZ_TRACE_ID_OFFSET)
|
||||
|
||||
/* buffer masks */
|
||||
#define TRAPZ_BUFF_REC_TYPE_MASK 0x80
|
||||
#define TRAPZ_BUFF_COMPLETE_MASK 0x40
|
||||
#define TRAPZ_BUFF_CAT_ID_MASK 0x30
|
||||
#define TRAPZ_BUFF_EXTRA_COUNT_MASK 0x0f
|
||||
|
||||
/* trigger masks */
|
||||
#define TRAPZ_TRIGGER_MASK \
|
||||
((TRAPZ_CAT_ID_MASK << TRAPZ_CAT_ID_OFFSET) | \
|
||||
(TRAPZ_COMP_ID_MASK << TRAPZ_COMP_ID_OFFSET) | \
|
||||
(TRAPZ_TRACE_ID_MASK << TRAPZ_TRACE_ID_OFFSET))
|
||||
|
||||
/* Circular buffer mask 'n shifters */
|
||||
#define TRAPZ_BUFF_REC_TYPE(x) (x & TRAPZ_BUFF_REC_TYPE_MASK)
|
||||
#define TRAPZ_BUFF_REC_COMPLETE(x) (x & TRAPZ_BUFF_COMPLETE_MASK)
|
||||
#define TRAPZ_BUFF_CAT_ID(x) ((x & TRAPZ_BUFF_CAT_ID_MASK) >> 4)
|
||||
#define TRAPZ_BUFF_EXTRA_COUNT(x) (x & TRAPZ_BUFF_EXTRA_COUNT_MASK)
|
||||
#define TRAPZ_BUFF_COMP_ID(x, y) (x << 4 | ((y & 0xf0) >> 4))
|
||||
#define TRAPZ_BUFF_TRACE_ID(x, y) (((x & 0x0f) << 4) | y)
|
||||
|
||||
#define TRAPZ_EXTRA_FORMAT_INT 1
|
||||
#define TRAPZ_EXTRA_FORMAT_STRING 2
|
||||
|
||||
/* IOCTL codes */
|
||||
#define __TRAPZIO 0xAF
|
||||
/* enable/disable the trapzdriver */
|
||||
#define TRAPZ_ENABLE_DRIVER _IO(__TRAPZIO, 1)
|
||||
/* get buffer capacity and fill size */
|
||||
#define TRAPZ_GET_CONFIG _IO(__TRAPZIO, 2)
|
||||
/* resize the buffer */
|
||||
#define TRAPZ_SET_BUFFER_SIZE _IO(__TRAPZIO, 3)
|
||||
/* reset to defaults - log level, filters, and triggers */
|
||||
#define TRAPZ_RESET_DEFAULTS _IO(__TRAPZIO, 4)
|
||||
#define TRAPZ_CLEAR_BUFFER _IO(__TRAPZIO, 5) /* clear buffer */
|
||||
#define TRAPZ_GET_VERSION _IO(__TRAPZIO, 6) /* get TRAPZ version */
|
||||
#define TRAPZ_SET_LOG_LEVEL _IO(__TRAPZIO, 7) /* set minimum log level */
|
||||
#define TRAPZ_CHK_LOG_LEVEL _IO(__TRAPZIO, 8) /* check log level */
|
||||
#define TRAPZ_ADD_TRIGGER _IO(__TRAPZIO, 9) /* add trigger */
|
||||
#define TRAPZ_DEL_TRIGGER _IO(__TRAPZIO, 10) /* delete trigger */
|
||||
#define TRAPZ_CLR_TRIGGERS _IO(__TRAPZIO, 11) /* clear all triggers */
|
||||
#define TRAPZ_CNT_TRIGGERS _IO(__TRAPZIO, 12) /* count triggers */
|
||||
|
||||
#endif /* _LINUX_TRAPZ_DEVICE_H */
|
||||
@@ -1,215 +0,0 @@
|
||||
/*
|
||||
* trapz_device.c
|
||||
*
|
||||
* TRAPZ (TRAcing and Profiling for Zpeed) Log Driver
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Andy Prunicki (prunicki@lab126.com)
|
||||
* Martin Unsal (munsal@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/trapz.h>
|
||||
|
||||
#include "trapz_trigger.h"
|
||||
|
||||
static void copy_timespec(const struct timespec *src, struct timespec *dest)
|
||||
{
|
||||
dest->tv_sec = src->tv_sec;
|
||||
dest->tv_nsec = src->tv_nsec;
|
||||
}
|
||||
|
||||
static void copy_trigger(const trapz_trigger_t *src, trapz_trigger_t *dest)
|
||||
{
|
||||
dest->start_trace_point = src->start_trace_point;
|
||||
dest->end_trace_point = src->end_trace_point;
|
||||
dest->trigger_id = src->trigger_id;
|
||||
dest->single_shot = src->single_shot;
|
||||
}
|
||||
|
||||
static int compare_triggers(const trapz_trigger_t *trig1,
|
||||
const trapz_trigger_t *trig2)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (trig1->start_trace_point == trig2->start_trace_point &&
|
||||
trig1->end_trace_point == trig2->end_trace_point) {
|
||||
rc = 1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int compare_trigger(const trapz_trigger_t *trig, const int trace_pt)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (trig->start_trace_point == trace_pt)
|
||||
rc = 1;
|
||||
else if (trig->end_trace_point == trace_pt)
|
||||
rc = 2;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static struct trigger_list *find_trigger(const trapz_trigger_t *trigger,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct list_head *iter;
|
||||
struct trigger_list *curr_trig_list;
|
||||
|
||||
list_for_each(iter, head) {
|
||||
curr_trig_list = list_entry(iter, struct trigger_list, list);
|
||||
if (compare_triggers(&curr_trig_list->trigger, trigger))
|
||||
return curr_trig_list;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int find_trace_pt(const int trace_pt, struct trigger_list **trigger,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct list_head *iter;
|
||||
struct trigger_list *curr_trig_list;
|
||||
int rc = 0;
|
||||
|
||||
list_for_each(iter, head) {
|
||||
curr_trig_list = list_entry(iter, struct trigger_list, list);
|
||||
rc = compare_trigger(&curr_trig_list->trigger, trace_pt);
|
||||
if (rc) {
|
||||
*trigger = curr_trig_list;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int add_trigger(const trapz_trigger_t *trigger, struct list_head *head,
|
||||
int *trigger_count)
|
||||
{
|
||||
int rc = 0;
|
||||
struct trigger_list *trigger_list_ptr;
|
||||
|
||||
if (*trigger_count < MAX_TRIGGERS) {
|
||||
/* Still more room for triggers */
|
||||
if (find_trigger(trigger, head) == NULL) {
|
||||
/* Trigger does not exist */
|
||||
trigger_list_ptr =
|
||||
(struct trigger_list *)
|
||||
kzalloc(sizeof(struct trigger_list), GFP_KERNEL);
|
||||
if (trigger_list_ptr == NULL) {
|
||||
rc = -ENOMEM;
|
||||
} else {
|
||||
copy_trigger(trigger,
|
||||
&trigger_list_ptr->trigger);
|
||||
INIT_LIST_HEAD(&trigger_list_ptr->list);
|
||||
list_add(&trigger_list_ptr->list, head);
|
||||
*trigger_count += 1;
|
||||
}
|
||||
} else {
|
||||
/* Trigger already exists */
|
||||
rc = -EEXIST;
|
||||
}
|
||||
} else {
|
||||
rc = -ENOMEM;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int delete_trigger(const trapz_trigger_t *trigger, struct list_head *head,
|
||||
int *trigger_count)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct trigger_list *trig_list = find_trigger(trigger, head);
|
||||
|
||||
|
||||
if (trig_list != NULL) {
|
||||
list_del(&trig_list->list);
|
||||
kfree(trig_list);
|
||||
*trigger_count -= 1;
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void clear_triggers(struct list_head *head, int *trigger_count)
|
||||
{
|
||||
struct trigger_list *curr_trig_list;
|
||||
|
||||
while (!list_empty(head)) {
|
||||
curr_trig_list = list_entry(head->next,
|
||||
struct trigger_list, list);
|
||||
list_del(head->next);
|
||||
kfree(curr_trig_list);
|
||||
}
|
||||
*trigger_count = 0;
|
||||
}
|
||||
|
||||
void send_trigger_uevent(const trapz_trigger_event_t *trigger_event,
|
||||
struct kobject *kobj)
|
||||
{
|
||||
char *envp[8];
|
||||
int i = 0;
|
||||
|
||||
for (i = 1; i < 6; i++)
|
||||
envp[i] = kmalloc(sizeof(char) * 24, GFP_KERNEL);
|
||||
|
||||
envp[0] = "EVENT=TRIGGER";
|
||||
snprintf(envp[1], 24, "ID=%d", trigger_event->trigger.trigger_id);
|
||||
snprintf(envp[2], 24, "START_S=%ld", trigger_event->start_ts.tv_sec);
|
||||
snprintf(envp[3], 24, "START_NS=%ld", trigger_event->start_ts.tv_nsec);
|
||||
snprintf(envp[4], 24, "END_S=%ld", trigger_event->end_ts.tv_sec);
|
||||
snprintf(envp[5], 24, "END_NS=%ld", trigger_event->end_ts.tv_nsec);
|
||||
if (trigger_event->trigger_active)
|
||||
envp[6] = "ACTIVE=TRUE";
|
||||
else
|
||||
envp[6] = "ACTIVE=FALSE";
|
||||
envp[7] = NULL;
|
||||
|
||||
kobject_uevent_env(kobj, KOBJ_CHANGE, envp);
|
||||
for (i = 1; i < 6; i++)
|
||||
kfree(envp[i]);
|
||||
}
|
||||
|
||||
void process_trigger(const int ctrl, trapz_trigger_event_t *trigger_event,
|
||||
struct list_head *head,
|
||||
int *trigger_count, struct timespec *ts)
|
||||
{
|
||||
int trigger_rc;
|
||||
struct trigger_list *found_trig;
|
||||
|
||||
trigger_rc = find_trace_pt(
|
||||
ctrl & TRAPZ_TRIGGER_MASK, &found_trig, head);
|
||||
if (trigger_rc == 1) {
|
||||
found_trig->start_ts.tv_sec = ts->tv_sec;
|
||||
found_trig->start_ts.tv_nsec = ts->tv_nsec;
|
||||
} else if (trigger_rc == 2 && found_trig->start_ts.tv_sec != 0) {
|
||||
/* TODO Load a local struct with the event info
|
||||
and send it out of crit. section. Also, delete
|
||||
the trigger if it is a one-shot. This is not
|
||||
a high-priority to fix, as we have not even
|
||||
utilized the trigger mechanism yet.
|
||||
Don't over-invest !! */
|
||||
copy_trigger(&found_trig->trigger, &trigger_event->trigger);
|
||||
copy_timespec(&found_trig->start_ts, &trigger_event->start_ts);
|
||||
copy_timespec(ts, &trigger_event->end_ts);
|
||||
if (found_trig->trigger.single_shot) {
|
||||
if (delete_trigger(
|
||||
&found_trig->trigger, head, trigger_count) != 0)
|
||||
printk(KERN_ERR "Trapz delete trigger failed.\n");
|
||||
trigger_event->trigger_active = 0;
|
||||
} else {
|
||||
trigger_event->trigger_active = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
#include <linux/kobject.h>
|
||||
#include "trapz_device.h"
|
||||
|
||||
#ifndef _LINUX_TRAPZ_TRIGGER_H
|
||||
#define _LINUX_TRAPZ_TRIGGER_H
|
||||
|
||||
#define MAX_TRIGGERS 3
|
||||
|
||||
struct trigger_list {
|
||||
struct list_head list;
|
||||
trapz_trigger_t trigger;
|
||||
struct timespec start_ts;
|
||||
};
|
||||
|
||||
int add_trigger(const trapz_trigger_t *trigger, struct list_head *head,
|
||||
int *trigger_count);
|
||||
int delete_trigger(const trapz_trigger_t *trigger, struct list_head *head,
|
||||
int *trigger_count);
|
||||
void clear_triggers(struct list_head *head, int *trigger_count);
|
||||
void send_trigger_uevent(const trapz_trigger_event_t *trigger_event,
|
||||
struct kobject *kobj);
|
||||
void process_trigger(const int ctrl, trapz_trigger_event_t *trigger_event,
|
||||
struct list_head *head, int *trigger_count, struct timespec *ts);
|
||||
|
||||
#endif /* _LINUX_TRAPZ_TRIGGER_H */
|
||||
@@ -55,7 +55,6 @@
|
||||
#include <linux/pipe_fs_i.h>
|
||||
#include <linux/oom.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/trapz.h> /* ACOS_MOD_ONELINE */
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/mmu_context.h>
|
||||
@@ -1044,20 +1043,6 @@ void set_task_comm(struct task_struct *tsk, char *buf)
|
||||
strlcpy(tsk->comm, buf, sizeof(tsk->comm));
|
||||
task_unlock(tsk);
|
||||
perf_event_comm(tsk);
|
||||
/* ACOS_MOD_BEGIN */
|
||||
#ifdef CONFIG_TRAPZ_TP
|
||||
if (TASK_COMM_LEN >= 8) {
|
||||
int tc0 = ((int *)tsk->comm)[0];
|
||||
int tc1 = ((int *)tsk->comm)[1];
|
||||
int tc2 = ((int *)tsk->comm)[2];
|
||||
int tc3 = ((int *)tsk->comm)[3];
|
||||
TRAPZ_DESCRIBE(TRAPZ_KERN_SCHED, TaskComm,
|
||||
"bytes 0..15 of tsk->comm");
|
||||
TRAPZ_LOG(TRAPZ_LOG_DEBUG, 0, TRAPZ_KERN_SCHED, TaskComm,
|
||||
tc0, tc1, tc2, tc3);
|
||||
}
|
||||
#endif
|
||||
/* ACOS_MOD_END */
|
||||
}
|
||||
|
||||
static void filename_to_taskname(char *tcomm, const char *fn, unsigned int len)
|
||||
|
||||
@@ -1,264 +0,0 @@
|
||||
/*
|
||||
* trapz.h
|
||||
*
|
||||
* TRAPZ (TRAcing and Profiling for Zpeed) Log Driver header file
|
||||
*
|
||||
* Copyright (C) Amazon Technologies Inc. All rights reserved.
|
||||
* Andy Prunicki (prunicki@lab126.com)
|
||||
* Martin Unsal (munsal@lab126.com)
|
||||
* TODO: Add additional contributor's names.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file must be #included anywhere that TRAPZ tracing calls are made from C
|
||||
* or C++ code. Currently that includes the Linux kernel build and the Android
|
||||
* build.
|
||||
*
|
||||
* You must also make sure that your source code is scanned by the TRAPZ tool
|
||||
* chain. This is accomplished by editing labscripts/trapz/trapz.xml and adding
|
||||
* a <component> tag for your project with a <scan> tag pointing at your source
|
||||
* code.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_TRAPZ_H
|
||||
#define _LINUX_TRAPZ_H
|
||||
|
||||
/**
|
||||
* CONFIG_TRAPZ is used to enable the compilation of the TRAPZ kernel driver.
|
||||
* CONFIG_TRAPZ_TP is used to turn TRAPZ logging on and off.
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/time.h>
|
||||
#ifndef __KERNEL__
|
||||
#include <sys/syscall.h>
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRAPZ_TP
|
||||
#ifdef __KERNEL__
|
||||
#include <generated/trapz_generated_kernel.h>
|
||||
#else
|
||||
#include <linux/trapz_generated.h>
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* CONFIG_TRAPZ_TP */
|
||||
|
||||
#ifdef CONFIG_TRAPZ_PVA
|
||||
#define TRAPZ_PVA
|
||||
#endif
|
||||
|
||||
typedef struct trapz_info {
|
||||
struct timespec ts;
|
||||
int counter;
|
||||
} trapz_info_t;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* Internal kernel API to register events */
|
||||
long systrapz(unsigned int ctrl, unsigned int extra1, unsigned int extra2,
|
||||
unsigned int extra3, unsigned int extra4, trapz_info_t __user *ti);
|
||||
/* Checks if a trapz component is enabled for a given loglevel */
|
||||
int trapz_check_loglevel(const int level, const int cat_id,
|
||||
const int component_id);
|
||||
/* actual system call interface (see kernel/sys_ni.c) */
|
||||
long sys_trapz(unsigned int ctrl, unsigned int extra1, unsigned int extra2,
|
||||
unsigned int extra3, unsigned int extra4, struct trapz_info __user *ti);
|
||||
#else /* __KERNEL */
|
||||
#define __NR_trapz 98
|
||||
inline int systrapz(unsigned int ctrl, unsigned int extra1, unsigned int extra2,
|
||||
unsigned int extra3, unsigned int extra4, trapz_info_t *ti)
|
||||
{
|
||||
return syscall(__NR_trapz, ctrl, extra1, extra2, extra3, extra4, ti);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ctrl field masks */
|
||||
#define TRAPZ_LEVEL_MASK 0x3
|
||||
#define TRAPZ_FLAGS_MASK 0x7
|
||||
#define TRAPZ_CAT_ID_MASK 0x3
|
||||
#define TRAPZ_COMP_ID_MASK 0xFFF
|
||||
#define TRAPZ_TRACE_ID_MASK 0xFFF
|
||||
|
||||
/* ctrl field sizes in bits */
|
||||
#define TRAPZ_LEVEL_SIZE 2
|
||||
#define TRAPZ_FLAGS_SIZE 3
|
||||
#define TRAPZ_CAT_ID_SIZE 2
|
||||
#define TRAPZ_COMP_ID_SIZE 12
|
||||
#define TRAPZ_TRACE_ID_SIZE 12
|
||||
|
||||
/* ctrl field offsets (from low order bit) */
|
||||
#define TRAPZ_TRACE_ID_OFFSET 0
|
||||
#define TRAPZ_COMP_ID_OFFSET (TRAPZ_TRACE_ID_OFFSET + TRAPZ_TRACE_ID_SIZE)
|
||||
#define TRAPZ_CAT_ID_OFFSET (TRAPZ_COMP_ID_OFFSET + TRAPZ_COMP_ID_SIZE)
|
||||
#define TRAPZ_FLAGS_OFFSET (TRAPZ_CAT_ID_OFFSET + TRAPZ_CAT_ID_SIZE)
|
||||
#define TRAPZ_LEVEL_OFFSET (TRAPZ_FLAGS_OFFSET + TRAPZ_FLAGS_SIZE)
|
||||
|
||||
/* ctrl field shift in */
|
||||
#define TRAPZ_LEVEL_IN(x) ((x & TRAPZ_LEVEL_MASK) << TRAPZ_LEVEL_OFFSET)
|
||||
#define TRAPZ_FLAGS_IN(x) ((x & TRAPZ_FLAGS_MASK) << TRAPZ_FLAGS_OFFSET)
|
||||
#define TRAPZ_CAT_ID_IN(x) ((x & TRAPZ_CAT_ID_MASK) << TRAPZ_CAT_ID_OFFSET)
|
||||
#define TRAPZ_COMP_ID_IN(x) ((x & TRAPZ_COMP_ID_MASK) << TRAPZ_COMP_ID_OFFSET)
|
||||
#define TRAPZ_TRACE_ID_IN(x) \
|
||||
((x & TRAPZ_TRACE_ID_MASK) << TRAPZ_TRACE_ID_OFFSET)
|
||||
|
||||
/* Log Macro definitions
|
||||
*/
|
||||
/* A simplified macro which uses the component category defined in
|
||||
trapz_generated.h */
|
||||
#define TRAPZ_ILOG(level, flags, component, trace_id, extra1, extra2, extra3, \
|
||||
extra4) \
|
||||
trapz_ilog(level, flags, component##__CAT, component##__ID, trace_id, \
|
||||
extra1, extra2, extra3, extra4)
|
||||
|
||||
/* The following macros depend on a pre-compilation step to generate
|
||||
* numeric trace IDs from human-readable identifiers.
|
||||
*
|
||||
* Each macro takes an argument "trace" which is an identifier that
|
||||
* describes the purpose of the log. This identifier doesn't need to
|
||||
* be valid in the current scope. For example:
|
||||
*
|
||||
* TRAPZ_LOG(TRAPZ_LOG_INFO, 0, TRAPZ_KERN, descriptive_phrase_here, 0, 0)
|
||||
*
|
||||
* After adding any new log statement, you must run 'make trapz' at
|
||||
* top level before building your code. The toolchain will parse your
|
||||
* TRAPZ_LOG call and #define the symbol you have used to an
|
||||
* autogenerated unique ID. In this case it would generate something
|
||||
* like this:
|
||||
*
|
||||
* #define TRAPZ_KERN___descriptive_phrase_here 3517
|
||||
*
|
||||
* XXXmunsal Be aware the parser is for the moment extremely crude and
|
||||
* not aware of C syntax. For example, if you have a TRAPZ_LOG
|
||||
* call that has been commented out, trapztool will still try to parse
|
||||
* it. Also the parser will be confused by extra commas contained
|
||||
* within nested expressions, such as here:
|
||||
*
|
||||
* TRAPZ_LOG(calculateLogLevel(foo,bar,baz), 0, TRAPZ_KERN, whatever, 0, 0)
|
||||
*
|
||||
* As far as my shitty parser is concerned, the first argument to
|
||||
* TRAPZ_LOG is 'calculateLogLevel(foo'. Epic fail.
|
||||
*
|
||||
* XXXmunsal Be aware that 'trace' must currently be a valid identifier string
|
||||
* in both C and Verilog (it ends up going in VCD file). I need to investigate
|
||||
* whether there are valid C identifiers that aren't valid Verilog identifiers
|
||||
* and either document that or convert them in toolchain.
|
||||
*/
|
||||
#define TRAPZ_LOG(level, flags, component, trace, extra1, extra2, extra3, \
|
||||
extra4) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##trace, \
|
||||
extra1, extra2, extra3, extra4)
|
||||
|
||||
/* Macro for logging with a printf string. The string is ignored in
|
||||
* compilation. It is used by code analysis tools to make the TRAPZ
|
||||
* log more readable.
|
||||
*
|
||||
* TRAPZ_LOG_PRINTF(TRAPZ_LOG_INFO, 0, TRAPZ_KERN_TOUCH, touch,
|
||||
* "Touch event in function Foo at %d %d", x, y)
|
||||
*
|
||||
* XXXmunsal I will warn again... due to my shitty parser you MUST
|
||||
* NOT have any commas or parentheses in your format string!
|
||||
*
|
||||
* XXXmunsal Be aware that format string will actually be formatted
|
||||
* by Python % operator, not C printf(). They are broadly compatible
|
||||
* but you're best off keeping it simple. I need to investigate
|
||||
* differences and document them here.
|
||||
*/
|
||||
#define TRAPZ_LOG_PRINTF(level, flags, component, trace, format, extra1, \
|
||||
extra2, extra3, extra4) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##trace, extra1, \
|
||||
extra2, extra3, extra4)
|
||||
|
||||
/* Macros for logging an interval. Similar to TRAPZ_LOG but will
|
||||
* be handled intelligently by postprocessing tools.
|
||||
*/
|
||||
#define TRAPZ_LOG_BEGIN(level, flags, component, trace) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##trace, 0, 1, 0, 0)
|
||||
#define TRAPZ_LOG_END(level, flags, component, trace) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##trace, 0, 0, 0, 0)
|
||||
|
||||
/* Macros for logging function scope. These are slightly different, in
|
||||
* that the identifier used to generate trace IDs MUST be a valid C
|
||||
* identifier; it should be the name of the enclosing function. This
|
||||
* is used to embed the function pointer in the log. Example:
|
||||
*
|
||||
* void myFunction(void) {
|
||||
* TRAPZ_LOG_ENTER(TRAPZ_LOG_INFO, 0, TRAPZ_KERN, myFunction);
|
||||
* do_stuff();
|
||||
* if (stuff_failed()) {
|
||||
* TRAPZ_LOG_FAIL(TRAPZ_LOG_INFO, 0, TRAPZ_KERN, myFunction);
|
||||
* return;
|
||||
* }
|
||||
* TRAPZ_LOG_EXIT(TRAPZ_LOG_INFO, 0, TRAPZ_KERN, myFunction);
|
||||
* }
|
||||
*
|
||||
* XXXmunsal The utility of these macros is unclear. Unless we have
|
||||
* postprocessing tools that use symbol tables, the function pointr is pretty
|
||||
* useless to us. I expect these will eventually move into TRAPZ_LOG_BEGIN/END.
|
||||
*/
|
||||
#define TRAPZ_LOG_ENTER(level, flags, component, fn_ptr) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##fn_ptr, \
|
||||
(int)fn_ptr, 1, 0, 0)
|
||||
#define TRAPZ_LOG_EXIT(level, flags, component, fn_ptr) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##fn_ptr, \
|
||||
(int)fn_ptr, 0, 0, 0)
|
||||
#define TRAPZ_LOG_FAIL(level, flags, component, fn_ptr) \
|
||||
TRAPZ_ILOG(level, flags, component, component##___##fn_ptr, \
|
||||
(int)fn_ptr, -1, 0, 0)
|
||||
|
||||
/* Macro for generating documentation of a Trapz trace
|
||||
*
|
||||
* E.g.:
|
||||
*
|
||||
* TRAPZ_DESCRIBE(TRAPZ_KERN, my_log,
|
||||
* "Here is a multi line string literal talking about"
|
||||
* "just what this log point means."
|
||||
* "You can even use <strong>HTML TAGS!</strong>")
|
||||
* TRAPZ_LOG(TRAPZ_LOG_INFO, 0, TRAPZ_KERN, my_log, 0, 0)
|
||||
*/
|
||||
#define TRAPZ_DESCRIBE(component, trace_or_fn_ptr, description)
|
||||
|
||||
/* Lowest level macros. This is where CONFIG_TRAPZ_TP takes effect. */
|
||||
#ifdef CONFIG_TRAPZ_TP
|
||||
|
||||
#define trapz_ilog(level, flags, cat_id, comp_id, trace_id, extra1, extra2, \
|
||||
extra3, extra4) \
|
||||
trapz_ilog_info(level, flags, cat_id, comp_id, trace_id, \
|
||||
extra1, extra2, extra3, extra4, NULL)
|
||||
|
||||
#define trapz_ilog_info(level, flags, cat_id, comp_id, trace_id, extra1, \
|
||||
extra2, extra3, extra4, trapzinfo) \
|
||||
systrapz( \
|
||||
TRAPZ_LEVEL_IN(level) | \
|
||||
TRAPZ_FLAGS_IN(flags) | \
|
||||
TRAPZ_CAT_ID_IN(cat_id) | \
|
||||
TRAPZ_COMP_ID_IN(comp_id) | \
|
||||
TRAPZ_TRACE_ID_IN(trace_id), \
|
||||
extra1, extra2, extra3, extra4, trapzinfo)
|
||||
|
||||
#else /* CONFIG_TRAPZ_TP */
|
||||
|
||||
#define trapz_ilog(level, flags, cat_id, comp_id, trace_id, extra1, extra2, \
|
||||
extra3, extra4)
|
||||
#define trapz_ilog_info(level, flags, cat_id, comp_id, trace_id, extra1, \
|
||||
extra2, extra3, extra4, trapzinfo)
|
||||
|
||||
#endif /* CONFIG_TRAPZ_TP */
|
||||
|
||||
/* Category definitions
|
||||
*/
|
||||
#define TRAPZ_CAT_KERNEL 0
|
||||
#define TRAPZ_CAT_PLATFORM 1
|
||||
#define TRAPZ_CAT_APPS 2
|
||||
|
||||
/* Level definitions
|
||||
*/
|
||||
#define TRAPZ_LOG_OFF 3
|
||||
#define TRAPZ_LOG_INFO 2
|
||||
#define TRAPZ_LOG_DEBUG 1
|
||||
#define TRAPZ_LOG_VERBOSE 0
|
||||
|
||||
#define TRAPZ_MAX_COMP_ID 0xfff /* 4095 */
|
||||
|
||||
#endif /* _LINUX_TRAPZ_H */
|
||||
@@ -94,7 +94,6 @@
|
||||
#include <linux/mt_sched_mon.h>
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/sched.h>
|
||||
#include <linux/trapz.h> /* ACOS_MOD_ONELINE */
|
||||
|
||||
#include <mtlbprof/mtlbprof.h>
|
||||
#include <mtlbprof/mtlbprof_stat.h>
|
||||
@@ -2144,21 +2143,6 @@ context_switch(struct rq *rq, struct task_struct *prev,
|
||||
struct task_struct *next)
|
||||
{
|
||||
struct mm_struct *mm, *oldmm;
|
||||
/* ACOS_MOD_BEGIN */
|
||||
#ifdef CONFIG_TRAPZ_TP
|
||||
/* The context switch is very chatty. By stuffing the info into the
|
||||
* lower 8 bits of extra 1 and 2, only one trapz record is used This
|
||||
* is because values <= 255 only use the 'mini' extras built into
|
||||
* the main record.
|
||||
*/
|
||||
int trapz_e1 = next->pid & 0xff;
|
||||
int trapz_e2 = (next->pid >> 8) & 0xff;
|
||||
TRAPZ_DESCRIBE(TRAPZ_KERN_SCHED, CtxSw,
|
||||
"Logs prev and next pids on a context switch.");
|
||||
TRAPZ_LOG(TRAPZ_LOG_VERBOSE, 0, TRAPZ_KERN_SCHED, CtxSw,
|
||||
trapz_e1, trapz_e2, 0, 0);
|
||||
#endif /* CONFIG_TRAPZ_TP */
|
||||
/* ACOS_MOD_END */
|
||||
|
||||
prepare_task_switch(rq, prev, next);
|
||||
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
|
||||
|
||||
#ifndef _TRAPZ_GENERATED_H
|
||||
#define _TRAPZ_GENERATED_H 1
|
||||
|
||||
#define TRAPZ__ID 0
|
||||
#define TRAPZ__NAME "Trapz"
|
||||
#define TRAPZ__CAT 4
|
||||
#define TRAPZ_KERN__ID 1
|
||||
#define TRAPZ_KERN__NAME "Kernel"
|
||||
#define TRAPZ_KERN__CAT 0
|
||||
#define TRAPZ_KERN_SCHED__ID 2
|
||||
#define TRAPZ_KERN_SCHED__NAME "Scheduler"
|
||||
#define TRAPZ_KERN_SCHED__CAT 0
|
||||
#define TRAPZ_KERN_SCHED___CtxSw 0
|
||||
#define TRAPZ_KERN_SCHED___TaskComm 1
|
||||
#define TRAPZ_KERN_SCHED_IDLE__ID 3
|
||||
#define TRAPZ_KERN_SCHED_IDLE__NAME "Idle"
|
||||
#define TRAPZ_KERN_SCHED_IDLE__CAT 0
|
||||
#define TRAPZ_KERN_FS__ID 4
|
||||
#define TRAPZ_KERN_FS__NAME "Filesystem"
|
||||
#define TRAPZ_KERN_FS__CAT 0
|
||||
#define TRAPZ_KERN_FS_FIO__ID 5
|
||||
#define TRAPZ_KERN_FS_FIO__NAME "FileIO"
|
||||
#define TRAPZ_KERN_FS_FIO__CAT 0
|
||||
#define TRAPZ_KERN_SND__ID 6
|
||||
#define TRAPZ_KERN_SND__NAME "Sound"
|
||||
#define TRAPZ_KERN_SND__CAT 0
|
||||
#define TRAPZ_KERN_SND___PcmWrite 0
|
||||
#define TRAPZ_KERN_INP__ID 7
|
||||
#define TRAPZ_KERN_INP__NAME "Input"
|
||||
#define TRAPZ_KERN_INP__CAT 0
|
||||
#define TRAPZ_KERN_INP_TOUCH__ID 8
|
||||
#define TRAPZ_KERN_INP_TOUCH__NAME "Touch"
|
||||
#define TRAPZ_KERN_INP_TOUCH__CAT 0
|
||||
#define TRAPZ_KERN_DISP__ID 9
|
||||
#define TRAPZ_KERN_DISP__NAME "Display"
|
||||
#define TRAPZ_KERN_DISP__CAT 0
|
||||
#define TRAPZ_KERN_DISP___Vsyncirq 0
|
||||
#define TRAPZ_KERN_DISP_DSS__ID 10
|
||||
#define TRAPZ_KERN_DISP_DSS__NAME "DssDriver"
|
||||
#define TRAPZ_KERN_DISP_DSS__CAT 0
|
||||
#define TRAPZ_KERN_DISP_PVR__ID 11
|
||||
#define TRAPZ_KERN_DISP_PVR__NAME "PvrDriver"
|
||||
#define TRAPZ_KERN_DISP_PVR__CAT 0
|
||||
#define TRAPZ_KERN_DISP_PVR_TUNE__ID 12
|
||||
#define TRAPZ_KERN_DISP_PVR_TUNE__NAME "PvrTune"
|
||||
#define TRAPZ_KERN_DISP_PVR_TUNE__CAT 0
|
||||
#define TRAPZ_KERN_ABE__ID 13
|
||||
#define TRAPZ_KERN_ABE__NAME "AudioABE"
|
||||
#define TRAPZ_KERN_ABE__CAT 0
|
||||
#define TRAPZ_KERN_PCM__ID 14
|
||||
#define TRAPZ_KERN_PCM__NAME "Pcm"
|
||||
#define TRAPZ_KERN_PCM__CAT 0
|
||||
#define TRAPZ_KERN_DVFS__ID 15
|
||||
#define TRAPZ_KERN_DVFS__NAME "DVFS"
|
||||
#define TRAPZ_KERN_DVFS__CAT 0
|
||||
#define TRAPZ_KERN_CPU__ID 16
|
||||
#define TRAPZ_KERN_CPU__NAME "CPU"
|
||||
#define TRAPZ_KERN_CPU__CAT 0
|
||||
#define TRAPZ_KERN_CPU___CPUFreq 0
|
||||
#define TRAPZ_KERN_CPUFREQ__ID 17
|
||||
#define TRAPZ_KERN_CPUFREQ__NAME "CpuFreq"
|
||||
#define TRAPZ_KERN_CPUFREQ__CAT 0
|
||||
#define TRAPZ_KERN_CPUIDLE__ID 18
|
||||
#define TRAPZ_KERN_CPUIDLE__NAME "CpuIdle"
|
||||
#define TRAPZ_KERN_CPUIDLE__CAT 0
|
||||
#define TRAPZ_KERN_RPMSG__ID 19
|
||||
#define TRAPZ_KERN_RPMSG__NAME "Rpmsg"
|
||||
#define TRAPZ_KERN_RPMSG__CAT 0
|
||||
#define TRAPZ_KERN_MMC__ID 20
|
||||
#define TRAPZ_KERN_MMC__NAME "eMMC"
|
||||
#define TRAPZ_KERN_MMC__CAT 0
|
||||
#define TRAPZ_KERN_NET__ID 21
|
||||
#define TRAPZ_KERN_NET__NAME "Net"
|
||||
#define TRAPZ_KERN_NET__CAT 0
|
||||
#define TRAPZ_KERN_NET_WIFI__ID 22
|
||||
#define TRAPZ_KERN_NET_WIFI__NAME "Wifi"
|
||||
#define TRAPZ_KERN_NET_WIFI__CAT 0
|
||||
#define TRAPZ_KERN_NET_SOCK__ID 23
|
||||
#define TRAPZ_KERN_NET_SOCK__NAME "Socket"
|
||||
#define TRAPZ_KERN_NET_SOCK__CAT 0
|
||||
#define TRAPZ_KERN_MEM__ID 24
|
||||
#define TRAPZ_KERN_MEM__NAME "Memory"
|
||||
#define TRAPZ_KERN_MEM__CAT 0
|
||||
#define TRAPZ_KERN_TEST__ID 25
|
||||
#define TRAPZ_KERN_TEST__NAME "KTest"
|
||||
#define TRAPZ_KERN_TEST__CAT 0
|
||||
#define TRAPZ_KERN_TEST_1__ID 26
|
||||
#define TRAPZ_KERN_TEST_1__NAME "KTest1"
|
||||
#define TRAPZ_KERN_TEST_1__CAT 0
|
||||
#define TRAPZ_KERN_TEST_2__ID 27
|
||||
#define TRAPZ_KERN_TEST_2__NAME "KTest2"
|
||||
#define TRAPZ_KERN_TEST_2__CAT 0
|
||||
#define TRAPZ_KERN_TEST_3__ID 28
|
||||
#define TRAPZ_KERN_TEST_3__NAME "KTest3"
|
||||
#define TRAPZ_KERN_TEST_3__CAT 0
|
||||
#define TRAPZ_KERN_TEST_4__ID 29
|
||||
#define TRAPZ_KERN_TEST_4__NAME "KTest4"
|
||||
#define TRAPZ_KERN_TEST_4__CAT 0
|
||||
|
||||
#endif
|
||||
@@ -4,7 +4,6 @@ config SND_TIMER
|
||||
|
||||
config SND_PCM
|
||||
tristate
|
||||
depends on TRAPZ
|
||||
select SND_TIMER
|
||||
|
||||
config SND_HWDEP
|
||||
|
||||
@@ -39,10 +39,6 @@
|
||||
#include <dma-coherence.h>
|
||||
#endif
|
||||
|
||||
/* ACOS_MOD_BEGIN */
|
||||
#include <trace/events/amz_atrace.h>
|
||||
/* ACOS_MOD_END */
|
||||
#include <linux/trapz.h> /* ACOS_MOD_ONELINE */
|
||||
/*
|
||||
* Compatibility
|
||||
*/
|
||||
@@ -2648,11 +2644,6 @@ static int snd_pcm_playback_ioctl1(struct file *file,
|
||||
return -EFAULT;
|
||||
result = snd_pcm_lib_write(substream, xferi.buf, xferi.frames);
|
||||
__put_user(result, &_xferi->result);
|
||||
|
||||
TRAPZ_DESCRIBE(TRAPZ_KERN_SND, PcmWrite, "Logs ioctl writes to PCM sound device");
|
||||
TRAPZ_LOG(TRAPZ_LOG_VERBOSE, 0, TRAPZ_KERN_SND, PcmWrite, cmd, 0, 0, 0);
|
||||
ATRACE_COUNTER("PcmWriteCmd", cmd); /* ACOS_MOD_ONELINE */
|
||||
|
||||
return result < 0 ? result : 0;
|
||||
}
|
||||
case SNDRV_PCM_IOCTL_WRITEN_FRAMES:
|
||||
|
||||
Reference in New Issue
Block a user