Merge "msm: kgsl: Revisit the GPU snapshot dumping"
This commit is contained in:
commit
be6bc701ce
4 changed files with 172 additions and 67 deletions
|
@ -108,7 +108,7 @@ static void push_object(int type,
|
|||
}
|
||||
|
||||
/*
|
||||
* Return a 1 if the specified object is already on the list of buffers
|
||||
* Returns index of the specified object is already on the list of buffers
|
||||
* to be dumped
|
||||
*/
|
||||
|
||||
|
@ -120,10 +120,9 @@ static int find_object(int type, uint64_t gpuaddr,
|
|||
for (index = 0; index < objbufptr; index++) {
|
||||
if (objbuf[index].gpuaddr == gpuaddr &&
|
||||
objbuf[index].entry->priv == process)
|
||||
return 1;
|
||||
return index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -196,8 +195,6 @@ static inline void parse_ib(struct kgsl_device *device,
|
|||
struct kgsl_process_private *process,
|
||||
uint64_t gpuaddr, uint64_t dwords)
|
||||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
uint64_t ib1base;
|
||||
struct adreno_ib_object_list *ib_obj_list;
|
||||
|
||||
/*
|
||||
|
@ -205,11 +202,7 @@ static inline void parse_ib(struct kgsl_device *device,
|
|||
* then push it into the static blob otherwise put it in the dynamic
|
||||
* list
|
||||
*/
|
||||
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB1_BASE,
|
||||
ADRENO_REG_CP_IB1_BASE_HI, &ib1base);
|
||||
|
||||
if (gpuaddr == ib1base) {
|
||||
if (gpuaddr == snapshot->ib1base) {
|
||||
push_object(SNAPSHOT_OBJ_TYPE_IB, process,
|
||||
gpuaddr, dwords);
|
||||
return;
|
||||
|
@ -295,17 +288,12 @@ static void snapshot_rb_ibs(struct kgsl_device *device,
|
|||
{
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
unsigned int rptr, *rbptr;
|
||||
uint64_t ibbase;
|
||||
int index, i;
|
||||
int parse_ibs = 0, ib_parse_start;
|
||||
|
||||
/* Get the current read pointers for the RB */
|
||||
adreno_readreg(adreno_dev, ADRENO_REG_CP_RB_RPTR, &rptr);
|
||||
|
||||
/* Address of the last processed IB */
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB1_BASE,
|
||||
ADRENO_REG_CP_IB1_BASE_HI, &ibbase);
|
||||
|
||||
/*
|
||||
* Figure out the window of ringbuffer data to dump. First we need to
|
||||
* find where the last processed IB ws submitted. Start walking back
|
||||
|
@ -333,14 +321,14 @@ static void snapshot_rb_ibs(struct kgsl_device *device,
|
|||
|
||||
if (adreno_cmd_is_ib(adreno_dev, rbptr[index])) {
|
||||
if (ADRENO_LEGACY_PM4(adreno_dev)) {
|
||||
if (rbptr[index + 1] == ibbase)
|
||||
if (rbptr[index + 1] == snapshot->ib1base)
|
||||
break;
|
||||
} else {
|
||||
uint64_t ibaddr;
|
||||
|
||||
ibaddr = rbptr[index + 2];
|
||||
ibaddr = ibaddr << 32 | rbptr[index + 1];
|
||||
if (ibaddr == ibbase)
|
||||
if (ibaddr == snapshot->ib1base)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -564,6 +552,67 @@ struct snapshot_ib_meta {
|
|||
uint64_t ib2size;
|
||||
};
|
||||
|
||||
void kgsl_snapshot_add_active_ib_obj_list(struct kgsl_device *device,
|
||||
struct kgsl_snapshot *snapshot)
|
||||
{
|
||||
struct adreno_ib_object_list *ib_obj_list;
|
||||
int index = -ENOENT;
|
||||
|
||||
if (!snapshot->ib1dumped)
|
||||
index = find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib1base,
|
||||
snapshot->process);
|
||||
|
||||
/* only do this for IB1 because the IB2's are part of IB1 objects */
|
||||
if ((index != -ENOENT) &&
|
||||
(snapshot->ib1base == objbuf[index].gpuaddr)) {
|
||||
if (-E2BIG == adreno_ib_create_object_list(device,
|
||||
objbuf[index].entry->priv,
|
||||
objbuf[index].gpuaddr,
|
||||
objbuf[index].size >> 2,
|
||||
&ib_obj_list))
|
||||
ib_max_objs = 1;
|
||||
if (ib_obj_list) {
|
||||
/* freeze the IB objects in the IB */
|
||||
snapshot_freeze_obj_list(snapshot,
|
||||
objbuf[index].entry->priv,
|
||||
ib_obj_list, snapshot->ib2base);
|
||||
adreno_ib_destroy_obj_list(ib_obj_list);
|
||||
}
|
||||
} else {
|
||||
/* Get the IB2 index from parsed object */
|
||||
index = find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib2base,
|
||||
snapshot->process);
|
||||
|
||||
if (index != -ENOENT)
|
||||
parse_ib(device, snapshot, snapshot->process,
|
||||
snapshot->ib2base, objbuf[index].size >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* active_ib_is_parsed() - Checks if active ib is already parsed
|
||||
* @gpuaddr: Active IB base address at the time of fault
|
||||
* @size: Active IB size
|
||||
* @process: The process to which the IB belongs
|
||||
*
|
||||
* Function returns true if the active is already is parsed
|
||||
* else false
|
||||
*/
|
||||
static bool active_ib_is_parsed(uint64_t gpuaddr, uint64_t size,
|
||||
struct kgsl_process_private *process)
|
||||
{
|
||||
int index;
|
||||
/* go through the static list for gpuaddr is in list or not */
|
||||
for (index = 0; index < objbufptr; index++) {
|
||||
if ((objbuf[index].gpuaddr <= gpuaddr) &&
|
||||
((objbuf[index].gpuaddr +
|
||||
(objbuf[index].size)) >=
|
||||
(gpuaddr + size)) &&
|
||||
(objbuf[index].entry->priv == process))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Snapshot the memory for an indirect buffer */
|
||||
static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
|
||||
size_t remain, void *priv)
|
||||
|
@ -596,13 +645,11 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (remain < (obj->size + sizeof(*header))) {
|
||||
KGSL_CORE_ERR("snapshot: Not enough memory for the ib\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only do this for IB1 because the IB2's are part of IB1 objects */
|
||||
if (meta->ib1base == obj->gpuaddr) {
|
||||
|
||||
snapshot->ib1dumped = active_ib_is_parsed(obj->gpuaddr,
|
||||
obj->size, obj->entry->priv);
|
||||
if (-E2BIG == adreno_ib_create_object_list(device,
|
||||
obj->entry->priv,
|
||||
obj->gpuaddr, obj->size >> 2,
|
||||
|
@ -617,6 +664,11 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (meta->ib2base == obj->gpuaddr)
|
||||
snapshot->ib2dumped = active_ib_is_parsed(obj->gpuaddr,
|
||||
obj->size, obj->entry->priv);
|
||||
|
||||
/* Write the sub-header for the section */
|
||||
header->gpuaddr = obj->gpuaddr;
|
||||
header->ptbase =
|
||||
|
@ -632,9 +684,7 @@ static size_t snapshot_ib(struct kgsl_device *device, u8 *buf,
|
|||
|
||||
/* Dump another item on the current pending list */
|
||||
static void dump_object(struct kgsl_device *device, int obj,
|
||||
struct kgsl_snapshot *snapshot,
|
||||
uint64_t ib1base, uint64_t ib1size,
|
||||
uint64_t ib2base, uint64_t ib2size)
|
||||
struct kgsl_snapshot *snapshot)
|
||||
{
|
||||
struct snapshot_ib_meta meta;
|
||||
|
||||
|
@ -642,10 +692,10 @@ static void dump_object(struct kgsl_device *device, int obj,
|
|||
case SNAPSHOT_OBJ_TYPE_IB:
|
||||
meta.snapshot = snapshot;
|
||||
meta.obj = &objbuf[obj];
|
||||
meta.ib1base = ib1base;
|
||||
meta.ib1size = ib1size;
|
||||
meta.ib2base = ib2base;
|
||||
meta.ib2size = ib2size;
|
||||
meta.ib1base = snapshot->ib1base;
|
||||
meta.ib1size = snapshot->ib1size;
|
||||
meta.ib2base = snapshot->ib2base;
|
||||
meta.ib2size = snapshot->ib2size;
|
||||
|
||||
kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_IB_V2,
|
||||
snapshot, snapshot_ib, &meta);
|
||||
|
@ -792,8 +842,6 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
struct kgsl_context *context)
|
||||
{
|
||||
unsigned int i;
|
||||
uint64_t ib1base, ib2base;
|
||||
unsigned int ib1size, ib2size;
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
struct adreno_gpudev *gpudev = ADRENO_GPU_DEVICE(adreno_dev);
|
||||
|
||||
|
@ -806,6 +854,16 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
setup_fault_process(device, snapshot,
|
||||
context ? context->proc_priv : NULL);
|
||||
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB1_BASE,
|
||||
ADRENO_REG_CP_IB1_BASE_HI, &snapshot->ib1base);
|
||||
adreno_readreg(adreno_dev, ADRENO_REG_CP_IB1_BUFSZ, &snapshot->ib1size);
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB2_BASE,
|
||||
ADRENO_REG_CP_IB2_BASE_HI, &snapshot->ib2base);
|
||||
adreno_readreg(adreno_dev, ADRENO_REG_CP_IB2_BUFSZ, &snapshot->ib2size);
|
||||
|
||||
snapshot->ib1dumped = false;
|
||||
snapshot->ib2dumped = false;
|
||||
|
||||
adreno_snapshot_ringbuffer(device, snapshot, adreno_dev->cur_rb);
|
||||
|
||||
/* Dump the prev ringbuffer */
|
||||
|
@ -818,13 +876,6 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
adreno_snapshot_ringbuffer(device, snapshot,
|
||||
adreno_dev->next_rb);
|
||||
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB1_BASE,
|
||||
ADRENO_REG_CP_IB1_BASE_HI, &ib1base);
|
||||
adreno_readreg(adreno_dev, ADRENO_REG_CP_IB1_BUFSZ, &ib1size);
|
||||
adreno_readreg64(adreno_dev, ADRENO_REG_CP_IB2_BASE,
|
||||
ADRENO_REG_CP_IB2_BASE_HI, &ib2base);
|
||||
adreno_readreg(adreno_dev, ADRENO_REG_CP_IB2_BUFSZ, &ib2size);
|
||||
|
||||
/* Add GPU specific sections - registers mainly, but other stuff too */
|
||||
if (gpudev->snapshot)
|
||||
gpudev->snapshot(adreno_dev, snapshot);
|
||||
|
@ -858,13 +909,13 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
* figure how often this really happens.
|
||||
*/
|
||||
|
||||
if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ib1base,
|
||||
snapshot->process) && ib1size) {
|
||||
if (-ENOENT == find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib1base,
|
||||
snapshot->process) && snapshot->ib1size) {
|
||||
push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
|
||||
ib1base, ib1size);
|
||||
snapshot->ib1base, snapshot->ib1size);
|
||||
KGSL_CORE_ERR(
|
||||
"CP_IB1_BASE not found in the ringbuffer.Dumping %x dwords of the buffer.\n",
|
||||
ib1size);
|
||||
snapshot->ib1size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -875,10 +926,10 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
* correct size.
|
||||
*/
|
||||
|
||||
if (!find_object(SNAPSHOT_OBJ_TYPE_IB, ib2base,
|
||||
snapshot->process) && ib2size) {
|
||||
if (-ENOENT == find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib2base,
|
||||
snapshot->process)) {
|
||||
push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
|
||||
ib2base, ib2size);
|
||||
snapshot->ib2base, snapshot->ib2size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -886,8 +937,15 @@ void adreno_snapshot(struct kgsl_device *device, struct kgsl_snapshot *snapshot,
|
|||
* are parsed, more objects might be found, and objbufptr will increase
|
||||
*/
|
||||
for (i = 0; i < objbufptr; i++)
|
||||
dump_object(device, i, snapshot, ib1base, ib1size,
|
||||
ib2base, ib2size);
|
||||
dump_object(device, i, snapshot);
|
||||
|
||||
/*
|
||||
* Incase snapshot static blob is running out of memory, Add Active IB1
|
||||
* and IB2 entries to obj_list so that active ib's can be dumped to
|
||||
* snapshot dynamic blob.
|
||||
*/
|
||||
if (!snapshot->ib1dumped || !snapshot->ib2dumped)
|
||||
kgsl_snapshot_add_active_ib_obj_list(device, snapshot);
|
||||
|
||||
if (ib_max_objs)
|
||||
KGSL_CORE_ERR("Max objects found in IB\n");
|
||||
|
|
|
@ -422,6 +422,12 @@ struct kgsl_device_private {
|
|||
|
||||
/**
|
||||
* struct kgsl_snapshot - details for a specific snapshot instance
|
||||
* @ib1base: Active IB1 base address at the time of fault
|
||||
* @ib2base: Active IB2 base address at the time of fault
|
||||
* @ib1size: Number of DWORDS pending in IB1 at the time of fault
|
||||
* @ib2size: Number of DWORDS pending in IB2 at the time of fault
|
||||
* @ib1dumped: Active IB1 dump status to sansphot binary
|
||||
* @ib2dumped: Active IB2 dump status to sansphot binary
|
||||
* @start: Pointer to the start of the static snapshot region
|
||||
* @size: Size of the current snapshot instance
|
||||
* @ptr: Pointer to the next block of memory to write to during snapshotting
|
||||
|
@ -437,6 +443,12 @@ struct kgsl_device_private {
|
|||
* @sysfs_read: An atomic for concurrent snapshot reads via syfs.
|
||||
*/
|
||||
struct kgsl_snapshot {
|
||||
uint64_t ib1base;
|
||||
uint64_t ib2base;
|
||||
unsigned int ib1size;
|
||||
unsigned int ib2size;
|
||||
bool ib1dumped;
|
||||
bool ib2dumped;
|
||||
u8 *start;
|
||||
size_t size;
|
||||
u8 *ptr;
|
||||
|
|
|
@ -100,8 +100,8 @@ static u8 *_ctxtptr;
|
|||
|
||||
static int snapshot_context_info(int id, void *ptr, void *data)
|
||||
{
|
||||
struct kgsl_snapshot_linux_context *header =
|
||||
(struct kgsl_snapshot_linux_context *)_ctxtptr;
|
||||
struct kgsl_snapshot_linux_context_v2 *header =
|
||||
(struct kgsl_snapshot_linux_context_v2 *)_ctxtptr;
|
||||
struct kgsl_context *context = ptr;
|
||||
struct kgsl_device *device;
|
||||
|
||||
|
@ -115,10 +115,12 @@ static int snapshot_context_info(int id, void *ptr, void *data)
|
|||
|
||||
kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_QUEUED,
|
||||
&header->timestamp_queued);
|
||||
kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_CONSUMED,
|
||||
&header->timestamp_consumed);
|
||||
kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED,
|
||||
&header->timestamp_retired);
|
||||
|
||||
_ctxtptr += sizeof(struct kgsl_snapshot_linux_context);
|
||||
_ctxtptr += sizeof(struct kgsl_snapshot_linux_context_v2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -127,11 +129,11 @@ static int snapshot_context_info(int id, void *ptr, void *data)
|
|||
static size_t snapshot_os(struct kgsl_device *device,
|
||||
u8 *buf, size_t remain, void *priv)
|
||||
{
|
||||
struct kgsl_snapshot_linux *header = (struct kgsl_snapshot_linux *)buf;
|
||||
struct kgsl_snapshot_linux_v2 *header =
|
||||
(struct kgsl_snapshot_linux_v2 *)buf;
|
||||
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
|
||||
int ctxtcount = 0;
|
||||
size_t size = sizeof(*header);
|
||||
u64 temp_ptbase;
|
||||
struct kgsl_context *context;
|
||||
|
||||
/* Figure out how many active contexts there are - these will
|
||||
|
@ -141,7 +143,7 @@ static size_t snapshot_os(struct kgsl_device *device,
|
|||
idr_for_each(&device->context_idr, snapshot_context_count, &ctxtcount);
|
||||
read_unlock(&device->context_lock);
|
||||
|
||||
size += ctxtcount * sizeof(struct kgsl_snapshot_linux_context);
|
||||
size += ctxtcount * sizeof(struct kgsl_snapshot_linux_context_v2);
|
||||
|
||||
/* Make sure there is enough room for the data */
|
||||
if (remain < size) {
|
||||
|
@ -151,9 +153,7 @@ static size_t snapshot_os(struct kgsl_device *device,
|
|||
|
||||
memset(header, 0, sizeof(*header));
|
||||
|
||||
header->osid = KGSL_SNAPSHOT_OS_LINUX;
|
||||
|
||||
header->state = SNAPSHOT_STATE_HUNG;
|
||||
header->osid = KGSL_SNAPSHOT_OS_LINUX_V3;
|
||||
|
||||
/* Get the kernel build information */
|
||||
strlcpy(header->release, utsname()->release, sizeof(header->release));
|
||||
|
@ -178,9 +178,8 @@ static size_t snapshot_os(struct kgsl_device *device,
|
|||
context = kgsl_context_get(device, header->current_context);
|
||||
|
||||
/* Get the current PT base */
|
||||
temp_ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
|
||||
/* Truncate to 32 bits in case LPAE is used */
|
||||
header->ptbase = (__u32)temp_ptbase;
|
||||
header->ptbase = kgsl_mmu_get_current_ttbr0(&device->mmu);
|
||||
|
||||
/* And the PID for the task leader */
|
||||
if (context) {
|
||||
header->pid = context->tid;
|
||||
|
@ -982,7 +981,8 @@ int kgsl_snapshot_add_ib_obj_list(struct kgsl_snapshot *snapshot,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static size_t _mempool_add_object(u8 *data, struct kgsl_snapshot_object *obj)
|
||||
static size_t _mempool_add_object(struct kgsl_snapshot *snapshot, u8 *data,
|
||||
struct kgsl_snapshot_object *obj)
|
||||
{
|
||||
struct kgsl_snapshot_section_header *section =
|
||||
(struct kgsl_snapshot_section_header *)data;
|
||||
|
@ -1008,6 +1008,14 @@ static size_t _mempool_add_object(u8 *data, struct kgsl_snapshot_object *obj)
|
|||
kgsl_mmu_pagetable_get_ttbr0(obj->entry->priv->pagetable);
|
||||
header->type = obj->type;
|
||||
|
||||
if (kgsl_addr_range_overlap(obj->gpuaddr, obj->size,
|
||||
snapshot->ib1base, snapshot->ib1size))
|
||||
snapshot->ib1dumped = true;
|
||||
|
||||
if (kgsl_addr_range_overlap(obj->gpuaddr, obj->size,
|
||||
snapshot->ib2base, snapshot->ib2size))
|
||||
snapshot->ib2dumped = true;
|
||||
|
||||
memcpy(dest, obj->entry->memdesc.hostptr + obj->offset, size);
|
||||
kgsl_memdesc_unmap(&obj->entry->memdesc);
|
||||
|
||||
|
@ -1049,7 +1057,7 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work)
|
|||
/* even if vmalloc fails, make sure we clean up the obj_list */
|
||||
list_for_each_entry_safe(obj, tmp, &snapshot->obj_list, node) {
|
||||
if (snapshot->mempool) {
|
||||
size_t ret = _mempool_add_object(ptr, obj);
|
||||
size_t ret = _mempool_add_object(snapshot, ptr, obj);
|
||||
ptr += ret;
|
||||
snapshot->mempool_size += ret;
|
||||
}
|
||||
|
@ -1064,6 +1072,13 @@ done:
|
|||
kgsl_process_private_put(snapshot->process);
|
||||
snapshot->process = NULL;
|
||||
|
||||
if (snapshot->ib1base && !snapshot->ib1dumped)
|
||||
pr_warn("kgsl: snapshot: Active IB1:%016llx not dumped\n",
|
||||
snapshot->ib1base);
|
||||
else if (snapshot->ib2base && !snapshot->ib2dumped)
|
||||
pr_warn("kgsl: snapshot: Active IB2:%016llx not dumped\n",
|
||||
snapshot->ib2base);
|
||||
|
||||
complete_all(&snapshot->dump_gate);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
|
||||
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
|
@ -63,12 +63,9 @@ struct kgsl_snapshot_section_header {
|
|||
|
||||
/* OS sub-section header */
|
||||
#define KGSL_SNAPSHOT_OS_LINUX 0x0001
|
||||
#define KGSL_SNAPSHOT_OS_LINUX_V3 0x00000202
|
||||
|
||||
/* Linux OS specific information */
|
||||
|
||||
#define SNAPSHOT_STATE_HUNG 0
|
||||
#define SNAPSHOT_STATE_RUNNING 1
|
||||
|
||||
struct kgsl_snapshot_linux {
|
||||
int osid; /* subsection OS identifier */
|
||||
int state; /* 1 if the thread is running, 0 for hung */
|
||||
|
@ -87,6 +84,23 @@ struct kgsl_snapshot_linux {
|
|||
unsigned char comm[16]; /* Name of the process that owns the PT */
|
||||
} __packed;
|
||||
|
||||
struct kgsl_snapshot_linux_v2 {
|
||||
int osid; /* subsection OS identifier */
|
||||
__u32 seconds; /* Unix timestamp for the snapshot */
|
||||
__u32 power_flags; /* Current power flags */
|
||||
__u32 power_level; /* Current power level */
|
||||
__u32 power_interval_timeout; /* Power interval timeout */
|
||||
__u32 grpclk; /* Current GP clock value */
|
||||
__u32 busclk; /* Current busclk value */
|
||||
__u64 ptbase; /* Current ptbase */
|
||||
__u32 pid; /* PID of the process that owns the PT */
|
||||
__u32 current_context; /* ID of the current context */
|
||||
__u32 ctxtcount; /* Number of contexts appended to section */
|
||||
unsigned char release[32]; /* kernel release */
|
||||
unsigned char version[32]; /* kernel version */
|
||||
unsigned char comm[16]; /* Name of the process that owns the PT */
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* This structure contains a record of an active context.
|
||||
* These are appended one after another in the OS section below
|
||||
|
@ -99,6 +113,12 @@ struct kgsl_snapshot_linux_context {
|
|||
__u32 timestamp_retired; /* The last timestamp retired by HW */
|
||||
};
|
||||
|
||||
struct kgsl_snapshot_linux_context_v2 {
|
||||
__u32 id; /* The context ID */
|
||||
__u32 timestamp_queued; /* The last queued timestamp */
|
||||
__u32 timestamp_consumed; /* The last timestamp consumed by HW */
|
||||
__u32 timestamp_retired; /* The last timestamp retired by HW */
|
||||
};
|
||||
/* Ringbuffer sub-section header */
|
||||
struct kgsl_snapshot_rb {
|
||||
int start; /* dword at the start of the dump */
|
||||
|
|
Loading…
Add table
Reference in a new issue