Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2f65d761 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Add facility to BUG_ON for a gpu fault"

parents 682c6945 7bd05939
Loading
Loading
Loading
Loading
+106 −48
Original line number Diff line number Diff line
@@ -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");
+13 −0
Original line number Diff line number Diff line
@@ -263,6 +263,7 @@ struct kgsl_device {
	struct kgsl_snapshot *snapshot;

	u32 snapshot_faultcount;	/* Total number of faults since boot */
	bool force_panic;		/* Force panic after snapshot dump */
	struct kobject snapshot_kobj;

	struct kobject ppd_kobj;
@@ -429,6 +430,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
@@ -444,6 +451,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;
+64 −15
Original line number Diff line number Diff line
@@ -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;
@@ -804,6 +803,29 @@ static ssize_t faultcount_store(struct kgsl_device *device, const char *buf,
	return count;
}

/* Show the force_panic request status */
static ssize_t force_panic_show(struct kgsl_device *device, char *buf)
{
	return snprintf(buf, PAGE_SIZE, "%d\n", device->force_panic);
}

/* Store the panic request value to force_panic */
static ssize_t force_panic_store(struct kgsl_device *device, const char *buf,
	size_t count)
{
	unsigned int val = 0;
	int ret;

	if (device && count > 0)
		device->force_panic = 0;

	ret = kgsl_sysfs_store(buf, &val);

	if (!ret && device)
		device->force_panic = (bool)val;

	return (ssize_t) ret < 0 ? ret : count;
}
/* Show the timestamp of the last collected snapshot */
static ssize_t timestamp_show(struct kgsl_device *device, char *buf)
{
@@ -829,6 +851,7 @@ struct kgsl_snapshot_attribute attr_##_name = { \

static SNAPSHOT_ATTR(timestamp, 0444, timestamp_show, NULL);
static SNAPSHOT_ATTR(faultcount, 0644, faultcount_show, faultcount_store);
static SNAPSHOT_ATTR(force_panic, 0644, force_panic_show, force_panic_store);

static ssize_t snapshot_sysfs_show(struct kobject *kobj,
	struct attribute *attr, char *buf)
@@ -908,6 +931,7 @@ int kgsl_device_snapshot_init(struct kgsl_device *device)

	device->snapshot = NULL;
	device->snapshot_faultcount = 0;
	device->force_panic = 0;

	ret = kobject_init_and_add(&device->snapshot_kobj, &ktype_snapshot,
		&device->dev->kobj, "snapshot");
@@ -923,7 +947,11 @@ int kgsl_device_snapshot_init(struct kgsl_device *device)
		goto done;

	ret  = sysfs_create_file(&device->snapshot_kobj, &attr_faultcount.attr);
	if (ret)
		goto done;

	ret  = sysfs_create_file(&device->snapshot_kobj,
			&attr_force_panic.attr);
done:
	return ret;
}
@@ -948,6 +976,7 @@ void kgsl_device_snapshot_close(struct kgsl_device *device)
	device->snapshot_memory.ptr = NULL;
	device->snapshot_memory.size = 0;
	device->snapshot_faultcount = 0;
	device->force_panic = 0;
}
EXPORT_SYMBOL(kgsl_device_snapshot_close);

@@ -975,7 +1004,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;
@@ -1001,6 +1031,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);

@@ -1017,6 +1055,7 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work)
{
	struct kgsl_snapshot *snapshot = container_of(work,
				struct kgsl_snapshot, work);
	struct kgsl_device *device = kgsl_get_device(KGSL_DEVICE_3D0);
	struct kgsl_snapshot_object *obj, *tmp;
	size_t size = 0;
	void *ptr;
@@ -1036,7 +1075,7 @@ void kgsl_snapshot_save_frozen_objs(struct work_struct *work)

	snapshot->mempool = vmalloc(size);
	if (snapshot->mempool != NULL)
		KGSL_CORE_ERR("snapshot: mempool address %p, size %zx\n",
		KGSL_DRV_ERR(device, "snapshot: mempool address %p, size %zx\n",
				snapshot->mempool, size);

	ptr = snapshot->mempool;
@@ -1045,7 +1084,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;
		}
@@ -1060,6 +1099,16 @@ done:
	kgsl_process_private_put(snapshot->process);
	snapshot->process = NULL;

	if (snapshot->ib1base && !snapshot->ib1dumped)
		KGSL_DRV_ERR(device,
				"snapshot: Active IB1:%016llx not dumped\n",
				snapshot->ib1base);
	else if (snapshot->ib2base && !snapshot->ib2dumped)
		KGSL_DRV_ERR(device,
			       "snapshot: Active IB2:%016llx not dumped\n",
				snapshot->ib2base);

	complete_all(&snapshot->dump_gate);
	BUG_ON(device->force_panic);
	return;
}
+25 −5
Original line number Diff line number Diff line
/* 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 */