-/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2017, 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
static int adreno_ib_find_objs(struct kgsl_device *device,
struct kgsl_process_private *process,
uint64_t gpuaddr, uint64_t dwords,
- int obj_type,
+ uint64_t ib2base, int obj_type,
struct adreno_ib_object_list *ib_obj_list,
int ib_level);
ret = adreno_ib_find_objs(device, process,
ib_parse_vars->set_draw_groups[i].cmd_stream_addr,
ib_parse_vars->set_draw_groups[i].cmd_stream_dwords,
- SNAPSHOT_GPU_OBJECT_DRAW,
+ 0, SNAPSHOT_GPU_OBJECT_DRAW,
ib_obj_list, 2);
if (ret)
break;
if (cmd_stream_dwords)
ret = adreno_ib_find_objs(device, process,
cmd_stream_addr, cmd_stream_dwords,
- SNAPSHOT_GPU_OBJECT_DRAW, ib_obj_list,
- 2);
+ 0, SNAPSHOT_GPU_OBJECT_DRAW,
+ ib_obj_list, 2);
if (ret)
break;
continue;
gpuaddr = gpuaddr << 32 | ptr[i + 1];
ret = adreno_ib_find_objs(device, process,
gpuaddr, (ptr[i] & 0x0000FFFF),
- SNAPSHOT_GPU_OBJECT_IB,
+ 0, SNAPSHOT_GPU_OBJECT_IB,
ib_obj_list, 2);
if (ret)
break;
if (flags & 0x8) {
ret = adreno_ib_find_objs(device, process,
ptr[i + 1], (ptr[i] & 0x0000FFFF),
- SNAPSHOT_GPU_OBJECT_IB,
+ 0, SNAPSHOT_GPU_OBJECT_IB,
ib_obj_list, 2);
if (ret)
break;
* @process: Process in which the IB is allocated
* @gpuaddr: IB2 gpuaddr
* @dwords: IB2 size in dwords
+ * @ib2base: Base address of active IB2
* @ib_obj_list: List of objects found in IB
* @ib_level: The level from which function is called, either from IB1 or IB2
*
*/
static int adreno_cp_parse_ib2(struct kgsl_device *device,
struct kgsl_process_private *process,
- uint64_t gpuaddr, uint64_t dwords,
+ uint64_t gpuaddr, uint64_t dwords, uint64_t ib2base,
struct adreno_ib_object_list *ib_obj_list,
int ib_level)
{
*/
if (2 == ib_level)
return -EINVAL;
+
+ /* Save current IB2 statically */
+ if (ib2base == gpuaddr)
+ kgsl_snapshot_push_object(process, gpuaddr, dwords);
/*
* only try to find sub objects iff this IB has
* not been processed already
return 0;
}
- return adreno_ib_find_objs(device, process, gpuaddr, dwords,
+ return adreno_ib_find_objs(device, process, gpuaddr, dwords, ib2base,
SNAPSHOT_GPU_OBJECT_IB, ib_obj_list, 2);
}
* @device: The device pointer on which the IB executes
* @process: The process in which the IB and all contained objects are mapped.
* @gpuaddr: The gpu address of the IB
+ * @ib2base: IB2 base address
* @dwords: Size of ib in dwords
* @obj_type: The object type can be either an IB or a draw state sequence
* @ib_obj_list: The list in which the IB and the objects in it are added.
static int adreno_ib_find_objs(struct kgsl_device *device,
struct kgsl_process_private *process,
uint64_t gpuaddr, uint64_t dwords,
- int obj_type,
+ uint64_t ib2base, int obj_type,
struct adreno_ib_object_list *ib_obj_list,
int ib_level)
{
uint64_t size = src[i + 2];
ret = adreno_cp_parse_ib2(device, process,
- gpuaddrib2, size,
+ gpuaddrib2, size, ib2base,
ib_obj_list, ib_level);
if (ret)
goto done;
gpuaddrib2 = gpuaddrib2 << 32 | src[i + 1];
ret = adreno_cp_parse_ib2(device, process,
- gpuaddrib2, size,
+ gpuaddrib2, size, ib2base,
ib_obj_list, ib_level);
if (ret)
goto done;
* @process: The process in which the IB and all contained objects are mapped
* @gpuaddr: The gpu address of the IB
* @dwords: Size of ib in dwords
+ * @ib2base: Base address of active IB2
* @ib_obj_list: The list in which the IB and the objects in it are added.
*
* Find all the memory objects that an IB needs for execution and place
*/
int adreno_ib_create_object_list(struct kgsl_device *device,
struct kgsl_process_private *process,
- uint64_t gpuaddr, uint64_t dwords,
+ uint64_t gpuaddr, uint64_t dwords, uint64_t ib2base,
struct adreno_ib_object_list **out_ib_obj_list)
{
int ret = 0;
return -ENOMEM;
}
- ret = adreno_ib_find_objs(device, process, gpuaddr, dwords,
+ ret = adreno_ib_find_objs(device, process, gpuaddr, dwords, ib2base,
SNAPSHOT_GPU_OBJECT_IB, ib_obj_list, 1);
/* Even if there was an error return the remaining objects found */
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2017, 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
#define SNAPSHOT_OBJ_BUFSIZE 64
-#define SNAPSHOT_OBJ_TYPE_IB 0
-
/* Used to print error message if an IB has too many objects in it */
static int ib_max_objs;
}
/* Push a new buffer object onto the list */
-static void push_object(int type,
- struct kgsl_process_private *process,
+void kgsl_snapshot_push_object(struct kgsl_process_private *process,
uint64_t gpuaddr, uint64_t dwords)
{
int index;
}
/* Put it on the list of things to parse */
- objbuf[objbufptr].type = type;
objbuf[objbufptr].gpuaddr = gpuaddr;
objbuf[objbufptr].size = dwords << 2;
objbuf[objbufptr++].entry = entry;
* to be dumped
*/
-static int find_object(int type, uint64_t gpuaddr,
- struct kgsl_process_private *process)
+static int find_object(uint64_t gpuaddr, struct kgsl_process_private *process)
{
int index;
* @snapshot: The snapshot data.
* @process: The process to which the IB belongs
* @ib_obj_list: List of the IB objects
- * @ib2base: IB2 base address at time of the fault
*
* Returns 0 on success else error code
*/
static int snapshot_freeze_obj_list(struct kgsl_snapshot *snapshot,
struct kgsl_process_private *process,
- struct adreno_ib_object_list *ib_obj_list,
- uint64_t ib2base)
+ struct adreno_ib_object_list *ib_obj_list)
{
int ret = 0;
struct adreno_ib_object *ib_objs;
}
if (freeze) {
- /* Save current IB2 statically */
- if (ib2base == ib_objs->gpuaddr) {
- push_object(SNAPSHOT_OBJ_TYPE_IB,
- process, ib_objs->gpuaddr, ib_objs->size >> 2);
+ temp_ret = kgsl_snapshot_get_object(snapshot,
+ process, ib_objs->gpuaddr,
+ ib_objs->size,
+ ib_objs->snapshot_obj_type);
+ if (temp_ret < 0) {
+ if (ret >= 0)
+ ret = temp_ret;
} else {
- temp_ret = kgsl_snapshot_get_object(snapshot,
- process, ib_objs->gpuaddr,
- ib_objs->size,
- ib_objs->snapshot_obj_type);
- if (temp_ret < 0) {
- if (ret >= 0)
- ret = temp_ret;
- } else {
- snapshot_frozen_objsize += temp_ret;
- }
+ snapshot_frozen_objsize += temp_ret;
}
}
}
* list
*/
if (gpuaddr == snapshot->ib1base) {
- push_object(SNAPSHOT_OBJ_TYPE_IB, process,
- gpuaddr, dwords);
+ kgsl_snapshot_push_object(process, gpuaddr, dwords);
return;
}
return;
if (-E2BIG == adreno_ib_create_object_list(device, process,
- gpuaddr, dwords, &ib_obj_list))
+ gpuaddr, dwords, snapshot->ib2base,
+ &ib_obj_list))
ib_max_objs = 1;
if (ib_obj_list)
int index = -ENOENT;
if (!snapshot->ib1dumped)
- index = find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib1base,
- snapshot->process);
+ index = find_object(snapshot->ib1base, snapshot->process);
/* only do this for IB1 because the IB2's are part of IB1 objects */
if ((index != -ENOENT) &&
objbuf[index].entry->priv,
objbuf[index].gpuaddr,
objbuf[index].size >> 2,
+ snapshot->ib2base,
&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);
+ ib_obj_list);
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);
+ index = find_object(snapshot->ib2base, snapshot->process);
if (index != -ENOENT)
parse_ib(device, snapshot, snapshot->process,
struct adreno_ib_object_list *ib_obj_list;
struct kgsl_snapshot *snapshot;
struct kgsl_snapshot_object *obj;
+ struct kgsl_memdesc *memdesc;
if (meta == NULL || meta->snapshot == NULL || meta->obj == NULL) {
KGSL_CORE_ERR("snapshot: bad metadata");
}
snapshot = meta->snapshot;
obj = meta->obj;
+ memdesc = &obj->entry->memdesc;
+
+ /* If size is zero get it from the medesc size */
+ if (!obj->size)
+ obj->size = (memdesc->size - (obj->gpuaddr - memdesc->gpuaddr));
if (remain < (obj->size + sizeof(*header))) {
KGSL_CORE_ERR("snapshot: Not enough memory for the ib\n");
return 0;
}
- src = kgsl_gpuaddr_to_vaddr(&obj->entry->memdesc, obj->gpuaddr);
+ src = kgsl_gpuaddr_to_vaddr(memdesc, obj->gpuaddr);
if (src == NULL) {
KGSL_DRV_ERR(device,
"snapshot: Unable to map GPU memory object 0x%016llX into the kernel\n",
if (-E2BIG == adreno_ib_create_object_list(device,
obj->entry->priv,
obj->gpuaddr, obj->size >> 2,
+ snapshot->ib2base,
&ib_obj_list))
ib_max_objs = 1;
if (ib_obj_list) {
/* freeze the IB objects in the IB */
snapshot_freeze_obj_list(snapshot,
obj->entry->priv,
- ib_obj_list, meta->ib2base);
+ ib_obj_list);
adreno_ib_destroy_obj_list(ib_obj_list);
}
}
{
struct snapshot_ib_meta meta;
- switch (objbuf[obj].type) {
- case SNAPSHOT_OBJ_TYPE_IB:
- meta.snapshot = snapshot;
- meta.obj = &objbuf[obj];
- meta.ib1base = snapshot->ib1base;
- meta.ib1size = snapshot->ib1size;
- meta.ib2base = snapshot->ib2base;
- meta.ib2size = snapshot->ib2size;
+ meta.snapshot = snapshot;
+ meta.obj = &objbuf[obj];
+ 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,
+ kgsl_snapshot_add_section(device, KGSL_SNAPSHOT_SECTION_IB_V2,
snapshot, snapshot_ib, &meta);
- if (objbuf[obj].entry) {
- kgsl_memdesc_unmap(&(objbuf[obj].entry->memdesc));
- kgsl_mem_entry_put(objbuf[obj].entry);
- }
- break;
- default:
- KGSL_CORE_ERR("snapshot: Invalid snapshot object type: %d\n",
- objbuf[obj].type);
- break;
+ if (objbuf[obj].entry) {
+ kgsl_memdesc_unmap(&(objbuf[obj].entry->memdesc));
+ kgsl_mem_entry_put(objbuf[obj].entry);
}
}
* figure how often this really happens.
*/
- if (-ENOENT == find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib1base,
- snapshot->process) && snapshot->ib1size) {
- push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
- snapshot->ib1base, snapshot->ib1size);
+ if (-ENOENT == find_object(snapshot->ib1base, snapshot->process) &&
+ snapshot->ib1size) {
+ kgsl_snapshot_push_object(snapshot->process, snapshot->ib1base,
+ snapshot->ib1size);
KGSL_CORE_ERR(
"CP_IB1_BASE not found in the ringbuffer.Dumping %x dwords of the buffer.\n",
snapshot->ib1size);
* correct size.
*/
- if (-ENOENT == find_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->ib2base,
- snapshot->process)) {
- push_object(SNAPSHOT_OBJ_TYPE_IB, snapshot->process,
- snapshot->ib2base, snapshot->ib2size);
+ if (-ENOENT == find_object(snapshot->ib2base, snapshot->process)) {
+ kgsl_snapshot_push_object(snapshot->process, snapshot->ib2base,
+ snapshot->ib2size);
}
/*