msm: kgsl: embed kgsl_context struct in adreno_context struct

Having a separate allocated struct for the device specific context
makes ownership unclear, which could lead to reference counting
problems or invalid pointers. Also, duplicate members were
starting to appear in adreno_context because there wasn't a safe
way to reach the kgsl_context from some parts of the adreno code.
This can now be done via container_of().

This change alters the lifecycle of the context->id, which is
now freed when the context reference count hits zero rather
than in kgsl_context_detach().

It also changes the context creation and destruction sequence.
The device specific code must allocate a structure containing
a struct kgsl_context and passes a pointer it to kgsl_init_context()
before doing any device specific initialization. There is also a
separate drawctxt_detach() callback for doing device specific
cleanup. This is separate from freeing memory, which is done
by the drawctxt_destroy() callback.

Change-Id: I7d238476a3bfec98fd8dbc28971cf3187a81dac2
Signed-off-by: Jeremy Gebben <jgebben@codeaurora.org>
This commit is contained in:
Jeremy Gebben
2013-07-10 07:14:27 -07:00
committed by Gerrit - the friendly Code Review server
parent 708089fe3b
commit 0ca32f2a38
16 changed files with 343 additions and 255 deletions
+45 -36
View File
@@ -865,7 +865,7 @@ static void adreno_iommu_setstate(struct kgsl_device *device,
if (context == NULL)
return;
adreno_ctx = context->devctxt;
adreno_ctx = ADRENO_CONTEXT(context);
if (kgsl_mmu_enable_clk(&device->mmu,
KGSL_IOMMU_CONTEXT_USER))
@@ -939,7 +939,7 @@ static void adreno_gpummu_setstate(struct kgsl_device *device,
context = kgsl_context_get(device, context_id);
if (context == NULL)
return;
adreno_ctx = context->devctxt;
adreno_ctx = ADRENO_CONTEXT(context);
if (flags & KGSL_MMUFLAGS_PTUPDATE) {
/* wait for graphics pipe to be idle */
@@ -1912,7 +1912,7 @@ static int _mark_context_status(int id, void *ptr, void *data)
{
unsigned int ft_status = *((unsigned int *) data);
struct kgsl_context *context = ptr;
struct adreno_context *adreno_context = context->devctxt;
struct adreno_context *adreno_context = ADRENO_CONTEXT(context);
if (ft_status) {
context->reset_status =
@@ -1953,7 +1953,7 @@ static int _set_max_ts(int id, void *ptr, void *data)
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
struct kgsl_context *context = ptr;
struct adreno_context *drawctxt = context->devctxt;
struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
if (drawctxt->flags & CTXT_FLAGS_GPU_HANG) {
kgsl_sharedmem_writel(device, &device->memstore,
@@ -2219,7 +2219,7 @@ static void adreno_setup_ft_data(struct kgsl_device *device,
}
if (context) {
adreno_context = context->devctxt;
adreno_context = ADRENO_CONTEXT(context);
if (adreno_context->flags & CTXT_FLAGS_PREAMBLE) {
if (ft_data->ib1) {
ret = _find_hanging_ib_sequence(rb,
@@ -2348,11 +2348,9 @@ _adreno_ft_restart_device(struct kgsl_device *device,
}
reset_done:
if (context) {
struct adreno_context *adreno_context = context->devctxt;
kgsl_mmu_setstate(&device->mmu, adreno_context->pagetable,
KGSL_MEMSTORE_GLOBAL);
}
if (context)
kgsl_mmu_setstate(&device->mmu, context->pagetable,
KGSL_MEMSTORE_GLOBAL);
/* If iommu is used then we need to make sure that the iommu clocks
* are on since there could be commands in pipeline that touch iommu */
@@ -2471,7 +2469,7 @@ _adreno_ft(struct kgsl_device *device,
}
} else {
no_context_ft = 0;
adreno_context = context->devctxt;
adreno_context = ADRENO_CONTEXT(context);
adreno_context->flags |= CTXT_FLAGS_GPU_HANG;
/*
* set the invalid ts flag to 0 for this context since we have
@@ -2527,16 +2525,16 @@ _adreno_ft(struct kgsl_device *device,
goto play_good_cmds;
}
/* Do not try the reply if hang is due to a pagefault */
if (adreno_context && adreno_context->pagefault) {
/* Do not try to replay if hang is due to a pagefault */
if (context && test_bit(KGSL_CONTEXT_PAGEFAULT, &context->priv)) {
/* Resume MMU */
mmu->mmu_ops->mmu_pagefault_resume(mmu);
if ((ft_data->context_id == adreno_context->id) &&
(ft_data->global_eop == adreno_context->pagefault_ts)) {
if ((ft_data->context_id == context->id) &&
(ft_data->global_eop == context->pagefault_ts)) {
ft_data->ft_policy &= ~KGSL_FT_REPLAY;
KGSL_FT_ERR(device, "MMU fault skipping replay\n");
}
adreno_context->pagefault = 0;
clear_bit(KGSL_CONTEXT_PAGEFAULT, &context->priv);
}
if (ft_data->ft_policy & KGSL_FT_REPLAY) {
@@ -2652,8 +2650,7 @@ play_good_cmds:
ft_data->last_valid_ctx_id);
if (last_ctx)
adreno_dev->drawctxt_active = last_ctx->devctxt;
adreno_dev->drawctxt_active = ADRENO_CONTEXT(last_ctx);
kgsl_context_put(last_ctx);
}
@@ -2720,7 +2717,7 @@ adreno_ft(struct kgsl_device *device,
/* Restore correct states after fault tolerance */
if (adreno_dev->drawctxt_active)
device->mmu.hwpagetable =
adreno_dev->drawctxt_active->pagetable;
adreno_dev->drawctxt_active->base.pagetable;
else
device->mmu.hwpagetable = device->mmu.defaultpagetable;
rb->timestamp[KGSL_MEMSTORE_GLOBAL] = timestamp;
@@ -3119,21 +3116,20 @@ struct kgsl_memdesc *adreno_find_ctxtmem(struct kgsl_device *device,
phys_addr_t pt_base, unsigned int gpuaddr, unsigned int size)
{
struct kgsl_context *context;
struct adreno_context *adreno_context = NULL;
int next = 0;
struct kgsl_memdesc *desc = NULL;
read_lock(&device->context_lock);
while (1) {
context = idr_get_next(&device->context_idr, &next);
if (context == NULL)
break;
adreno_context = (struct adreno_context *)context->devctxt;
if (kgsl_mmu_pt_equal(&device->mmu, adreno_context->pagetable,
if (kgsl_mmu_pt_equal(&device->mmu, context->pagetable,
pt_base)) {
struct adreno_context *adreno_context;
adreno_context = ADRENO_CONTEXT(context);
desc = &adreno_context->gpustate;
if (kgsl_gpuaddr_in_memdesc(desc, gpuaddr, size))
break;
@@ -3267,9 +3263,10 @@ static void adreno_regwrite(struct kgsl_device *device,
static unsigned int _get_context_id(struct kgsl_context *k_ctxt)
{
unsigned int context_id = KGSL_MEMSTORE_GLOBAL;
if (k_ctxt != NULL) {
struct adreno_context *a_ctxt = k_ctxt->devctxt;
if (k_ctxt->id == KGSL_CONTEXT_INVALID || a_ctxt == NULL)
struct adreno_context *a_ctxt = ADRENO_CONTEXT(k_ctxt);
if (kgsl_context_detached(k_ctxt))
context_id = KGSL_CONTEXT_INVALID;
else if (a_ctxt->flags & CTXT_FLAGS_PER_CONTEXT_TS)
context_id = k_ctxt->id;
@@ -3340,7 +3337,8 @@ static unsigned int adreno_check_hw_ts(struct kgsl_device *device,
*/
if (context && device->state != KGSL_STATE_SLUMBER) {
adreno_ringbuffer_issuecmds(device, context->devctxt,
adreno_ringbuffer_issuecmds(device,
ADRENO_CONTEXT(context),
KGSL_CMD_FLAGS_GET_INT, NULL, 0);
}
}
@@ -3400,6 +3398,7 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
unsigned int curr_context_id = 0;
static struct adreno_context *curr_context;
static struct kgsl_context *context;
static char pid_name[TASK_COMM_LEN] = "unknown";
if (!adreno_dev->fast_hang_detect)
fast_hang_detected = 0;
@@ -3463,8 +3462,13 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
if (curr_global_ts == prev_global_ts) {
/* Get the current context here */
if (context == NULL) {
/* If we don't already have a good context, get it. */
if (kgsl_context_detached(context)) {
kgsl_context_put(context);
context = NULL;
curr_context = NULL;
strlcpy(pid_name, "unknown", sizeof(pid_name));
kgsl_sharedmem_readl(&device->memstore,
&curr_context_id,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
@@ -3474,8 +3478,12 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
context = kgsl_context_get(device, curr_context_id);
if (context != NULL) {
curr_context = context->devctxt;
struct task_struct *task;
curr_context = ADRENO_CONTEXT(context);
curr_context->ib_gpu_time_used = 0;
task = find_task_by_vpid(context->pid);
if (task)
get_task_comm(pid_name, task);
} else {
KGSL_DRV_ERR(device,
"Fault tolerance no context found\n");
@@ -3499,8 +3507,7 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
KGSL_FT_ERR(device,
"Proc %s, ctxt_id %d ts %d triggered fault tolerance"
" on global ts %d\n",
curr_context ? curr_context->pid_name : "",
curr_context ? curr_context->id : 0,
pid_name, context ? context->id : 0,
(kgsl_readtimestamp(device, context,
KGSL_TIMESTAMP_RETIRED) + 1),
curr_global_ts + 1);
@@ -3512,7 +3519,7 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
curr_context->ib_gpu_time_used += KGSL_TIMEOUT_PART;
KGSL_FT_INFO(device,
"Proc %s used GPU Time %d ms on timestamp 0x%X\n",
curr_context->pid_name, curr_context->ib_gpu_time_used,
pid_name, curr_context->ib_gpu_time_used,
curr_global_ts+1);
if ((long_ib_detected) &&
@@ -3528,8 +3535,7 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
"Proc %s, ctxt_id %d ts %d"
"used GPU for %d ms long ib "
"detected on global ts %d\n",
curr_context->pid_name,
curr_context->id,
pid_name, context->id,
(kgsl_readtimestamp(device,
context,
KGSL_TIMESTAMP_RETIRED)+1),
@@ -3551,6 +3557,7 @@ unsigned int adreno_ft_detect(struct kgsl_device *device,
kgsl_context_put(context);
context = NULL;
curr_context = NULL;
strlcpy(pid_name, "unknown", sizeof(pid_name));
adreno_dev->long_ib = 0;
adreno_dev->long_ib_ts = 0;
}
@@ -3608,7 +3615,8 @@ static int adreno_waittimestamp(struct kgsl_device *device,
unsigned int msecs)
{
static unsigned int io_cnt;
struct adreno_context *adreno_ctx = context ? context->devctxt : NULL;
struct adreno_context *adreno_ctx = context ? ADRENO_CONTEXT(context) :
NULL;
struct kgsl_pwrctrl *pwr = &device->pwrctrl;
unsigned int context_id = _get_context_id(context);
unsigned int time_elapsed = 0;
@@ -3929,6 +3937,7 @@ static const struct kgsl_functable adreno_functable = {
/* Optional functions */
.setstate = adreno_setstate,
.drawctxt_create = adreno_drawctxt_create,
.drawctxt_detach = adreno_drawctxt_detach,
.drawctxt_destroy = adreno_drawctxt_destroy,
.setproperty = adreno_setproperty,
.postmortem_dump = adreno_dump,
+3
View File
@@ -25,6 +25,9 @@
#define ADRENO_DEVICE(device) \
KGSL_CONTAINER_OF(device, struct adreno_device, dev)
#define ADRENO_CONTEXT(device) \
KGSL_CONTAINER_OF(device, struct adreno_context, base)
#define ADRENO_CHIPID_CORE(_id) (((_id) >> 24) & 0xFF)
#define ADRENO_CHIPID_MAJOR(_id) (((_id) >> 16) & 0xFF)
#define ADRENO_CHIPID_MINOR(_id) (((_id) >> 8) & 0xFF)
+31 -21
View File
@@ -1355,7 +1355,7 @@ static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
tmp_ctx.gmem_base = adreno_dev->gmem_base;
result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
drawctxt->base.pagetable, drawctxt->context_gmem_shadow.size);
if (result)
return result;
@@ -1364,7 +1364,7 @@ static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW;
/* blank out gmem shadow. */
kgsl_sharedmem_set(drawctxt->dev_priv->device,
kgsl_sharedmem_set(drawctxt->base.device,
&drawctxt->context_gmem_shadow.gmemshadow, 0, 0,
drawctxt->context_gmem_shadow.size);
@@ -1389,7 +1389,7 @@ static int a2xx_create_gmem_shadow(struct adreno_device *adreno_dev,
kgsl_cache_range_op(&drawctxt->context_gmem_shadow.gmemshadow,
KGSL_CACHE_OP_FLUSH);
kgsl_cffdump_syncmem(drawctxt->dev_priv,
kgsl_cffdump_syncmem(drawctxt->base.device,
&drawctxt->context_gmem_shadow.gmemshadow,
drawctxt->context_gmem_shadow.gmemshadow.gpuaddr,
drawctxt->context_gmem_shadow.gmemshadow.size, false);
@@ -1410,13 +1410,13 @@ static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
*/
ret = kgsl_allocate(&drawctxt->gpustate,
drawctxt->pagetable, _context_size(adreno_dev));
drawctxt->base.pagetable, _context_size(adreno_dev));
if (ret)
return ret;
kgsl_sharedmem_set(drawctxt->dev_priv->device, &drawctxt->gpustate, 0,
0, _context_size(adreno_dev));
kgsl_sharedmem_set(drawctxt->base.device, &drawctxt->gpustate,
0, 0, _context_size(adreno_dev));
tmp_ctx.cmd = tmp_ctx.start
= (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET);
@@ -1440,8 +1440,8 @@ static int a2xx_drawctxt_create(struct adreno_device *adreno_dev,
kgsl_cache_range_op(&drawctxt->gpustate,
KGSL_CACHE_OP_FLUSH);
kgsl_cffdump_syncmem(drawctxt->dev_priv, &drawctxt->gpustate,
drawctxt->gpustate.gpuaddr,
kgsl_cffdump_syncmem(drawctxt->base.device,
&drawctxt->gpustate, drawctxt->gpustate.gpuaddr,
drawctxt->gpustate.size, false);
done:
@@ -1516,7 +1516,7 @@ static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
"Current active context has caused gpu hang\n");
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
kgsl_cffdump_syncmem(context->base.device, &context->gpustate,
context->reg_save[1],
context->reg_save[2] << 2, true);
/* save registers and constants. */
@@ -1525,7 +1525,7 @@ static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
context->reg_save, 3);
if (context->flags & CTXT_FLAGS_SHADER_SAVE) {
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->shader_save[1],
context->shader_save[2] << 2, true);
@@ -1534,7 +1534,7 @@ static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
KGSL_CMD_FLAGS_PMODE,
context->shader_save, 3);
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->shader_fixup[1],
context->shader_fixup[2] << 2, true);
@@ -1552,7 +1552,7 @@ static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
if ((context->flags & CTXT_FLAGS_GMEM_SAVE) &&
(context->flags & CTXT_FLAGS_GMEM_SHADOW)) {
kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
kgsl_cffdump_syncmem(context->base.device, &context->gpustate,
context->context_gmem_shadow.gmem_save[1],
context->context_gmem_shadow.gmem_save[2] << 2, true);
/* save gmem.
@@ -1562,7 +1562,7 @@ static void a2xx_drawctxt_save(struct adreno_device *adreno_dev,
KGSL_CMD_FLAGS_PMODE,
context->context_gmem_shadow.gmem_save, 3);
kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
kgsl_cffdump_syncmem(context->base.device, &context->gpustate,
context->chicken_restore[1],
context->chicken_restore[2] << 2, true);
@@ -1586,9 +1586,18 @@ static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
unsigned int cmds[5];
if (context == NULL) {
/* No context - set the default apgetable and thats it */
/* No context - set the default pagetable and thats it */
unsigned int id;
/*
* If there isn't a current context, the kgsl_mmu_setstate
* will use the CPU path so we don't need to give
* it a valid context id.
*/
id = (adreno_dev->drawctxt_active != NULL)
? adreno_dev->drawctxt_active->base.id
: KGSL_CONTEXT_INVALID;
kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable,
adreno_dev->drawctxt_active->id);
id);
return;
}
@@ -1597,16 +1606,17 @@ static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
cmds[3] = device->memstore.gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
cmds[4] = context->id;
cmds[4] = context->base.id;
adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
cmds, 5);
kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
kgsl_mmu_setstate(&device->mmu, context->base.pagetable,
context->base.id);
/* restore gmem.
* (note: changes shader. shader must not already be restored.)
*/
if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
kgsl_cffdump_syncmem(context->base.device, &context->gpustate,
context->context_gmem_shadow.gmem_restore[1],
context->context_gmem_shadow.gmem_restore[2] << 2,
true);
@@ -1616,7 +1626,7 @@ static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
context->context_gmem_shadow.gmem_restore, 3);
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->chicken_restore[1],
context->chicken_restore[2] << 2, true);
@@ -1631,7 +1641,7 @@ static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
}
if (!(context->flags & CTXT_FLAGS_PREAMBLE)) {
kgsl_cffdump_syncmem(context->dev_priv, &context->gpustate,
kgsl_cffdump_syncmem(context->base.device, &context->gpustate,
context->reg_restore[1],
context->reg_restore[2] << 2, true);
@@ -1641,7 +1651,7 @@ static void a2xx_drawctxt_restore(struct adreno_device *adreno_dev,
/* restore shader instructions & partitioning. */
if (context->flags & CTXT_FLAGS_SHADER_RESTORE) {
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->shader_restore[1],
context->shader_restore[2] << 2, true);
+17 -7
View File
@@ -2321,7 +2321,7 @@ static int a3xx_create_gmem_shadow(struct adreno_device *adreno_dev,
tmp_ctx.gmem_base = adreno_dev->gmem_base;
result = kgsl_allocate(&drawctxt->context_gmem_shadow.gmemshadow,
drawctxt->pagetable, drawctxt->context_gmem_shadow.size);
drawctxt->base.pagetable, drawctxt->context_gmem_shadow.size);
if (result)
return result;
@@ -2355,7 +2355,7 @@ static int a3xx_drawctxt_create(struct adreno_device *adreno_dev,
*/
ret = kgsl_allocate(&drawctxt->gpustate,
drawctxt->pagetable, CONTEXT_SIZE);
drawctxt->base.pagetable, CONTEXT_SIZE);
if (ret)
return ret;
@@ -2420,7 +2420,7 @@ static void a3xx_drawctxt_save(struct adreno_device *adreno_dev,
* already be saved.)
*/
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->context_gmem_shadow.gmem_save[1],
context->context_gmem_shadow.gmem_save[2] << 2, true);
@@ -2441,8 +2441,17 @@ static void a3xx_drawctxt_restore(struct adreno_device *adreno_dev,
if (context == NULL) {
/* No context - set the default pagetable and thats it */
unsigned int id;
/*
* If there isn't a current context, the kgsl_mmu_setstate
* will use the CPU path so we don't need to give
* it a valid context id.
*/
id = (adreno_dev->drawctxt_active != NULL)
? adreno_dev->drawctxt_active->base.id
: KGSL_CONTEXT_INVALID;
kgsl_mmu_setstate(&device->mmu, device->mmu.defaultpagetable,
adreno_dev->drawctxt_active->id);
id);
return;
}
@@ -2451,10 +2460,11 @@ static void a3xx_drawctxt_restore(struct adreno_device *adreno_dev,
cmds[2] = cp_type3_packet(CP_MEM_WRITE, 2);
cmds[3] = device->memstore.gpuaddr +
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL, current_context);
cmds[4] = context->id;
cmds[4] = context->base.id;
adreno_ringbuffer_issuecmds(device, context, KGSL_CMD_FLAGS_NONE,
cmds, 5);
kgsl_mmu_setstate(&device->mmu, context->pagetable, context->id);
kgsl_mmu_setstate(&device->mmu, context->base.pagetable,
context->base.id);
/*
* Restore GMEM. (note: changes shader.
@@ -2462,7 +2472,7 @@ static void a3xx_drawctxt_restore(struct adreno_device *adreno_dev,
*/
if (context->flags & CTXT_FLAGS_GMEM_RESTORE) {
kgsl_cffdump_syncmem(context->dev_priv,
kgsl_cffdump_syncmem(context->base.device,
&context->gpustate,
context->context_gmem_shadow.gmem_restore[1],
context->context_gmem_shadow.gmem_restore[2] << 2,
+50 -44
View File
@@ -134,34 +134,33 @@ void build_quad_vtxbuff(struct adreno_context *drawctxt,
/**
* adreno_drawctxt_create - create a new adreno draw context
* @device - KGSL device to create the context on
* @pagetable - Pagetable for the context
* @context- Generic KGSL context structure
* @flags - flags for the context (passed from user space)
* @dev_priv: the owner of the context
* @flags: flags for the context (passed from user space)
*
* Create a new draw context for the 3D core. Return 0 on success,
* or error code on failure.
* Create and return a new draw context for the 3D core.
*/
int adreno_drawctxt_create(struct kgsl_device *device,
struct kgsl_pagetable *pagetable,
struct kgsl_context *context, uint32_t *flags)
struct kgsl_context *
adreno_drawctxt_create(struct kgsl_device_private *dev_priv,
uint32_t *flags)
{
struct adreno_context *drawctxt;
struct kgsl_device *device = dev_priv->device;
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct adreno_ringbuffer *rb = &adreno_dev->ringbuffer;
int ret;
drawctxt = kzalloc(sizeof(struct adreno_context), GFP_KERNEL);
if (drawctxt == NULL)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
ret = kgsl_context_init(dev_priv, &drawctxt->base);
if (ret != 0) {
kfree(drawctxt);
return ERR_PTR(ret);
}
drawctxt->pid = task_pid_nr(current);
strlcpy(drawctxt->pid_name, current->comm, TASK_COMM_LEN);
drawctxt->pagetable = pagetable;
drawctxt->bin_base_offset = 0;
drawctxt->id = context->id;
rb->timestamp[context->id] = 0;
rb->timestamp[drawctxt->base.id] = 0;
*flags &= (KGSL_CONTEXT_PREAMBLE |
KGSL_CONTEXT_NO_GMEM_ALLOC |
@@ -192,50 +191,47 @@ int adreno_drawctxt_create(struct kgsl_device *device,
drawctxt->type =
(*flags & KGSL_CONTEXT_TYPE_MASK) >> KGSL_CONTEXT_TYPE_SHIFT;
drawctxt->dev_priv = context->dev_priv;
ret = adreno_dev->gpudev->ctxt_create(adreno_dev, drawctxt);
if (ret)
goto err;
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->id, ref_wait_ts),
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, ref_wait_ts),
KGSL_INIT_REFTIMESTAMP);
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->id, ts_cmp_enable), 0);
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, ts_cmp_enable),
0);
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->id, soptimestamp), 0);
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, soptimestamp),
0);
kgsl_sharedmem_writel(device, &device->memstore,
KGSL_MEMSTORE_OFFSET(drawctxt->id, eoptimestamp), 0);
KGSL_MEMSTORE_OFFSET(drawctxt->base.id, eoptimestamp),
0);
context->devctxt = drawctxt;
return 0;
return &drawctxt->base;
err:
kfree(drawctxt);
return ret;
kgsl_context_put(&drawctxt->base);
return ERR_PTR(ret);
}
/**
* adreno_drawctxt_destroy - destroy a draw context
* @device - KGSL device that owns the context
* @context- Generic KGSL context container for the context
* adreno_drawctxt_detach(): detach a context from the GPU
* @context: Generic KGSL context container for the context
*
* Destroy an existing context. Return 0 on success or error
* code on failure.
*/
/* destroy a drawing context */
void adreno_drawctxt_destroy(struct kgsl_device *device,
struct kgsl_context *context)
void adreno_drawctxt_detach(struct kgsl_context *context)
{
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
struct kgsl_device *device;
struct adreno_device *adreno_dev;
struct adreno_context *drawctxt;
if (context == NULL || context->devctxt == NULL)
if (context == NULL)
return;
drawctxt = context->devctxt;
device = context->device;
adreno_dev = ADRENO_DEVICE(device);
drawctxt = ADRENO_CONTEXT(context);
/* deactivate context */
if (adreno_dev->drawctxt_active == drawctxt) {
/* no need to save GMEM or shader, the context is
@@ -256,9 +252,17 @@ void adreno_drawctxt_destroy(struct kgsl_device *device,
kgsl_sharedmem_free(&drawctxt->gpustate);
kgsl_sharedmem_free(&drawctxt->context_gmem_shadow.gmemshadow);
}
void adreno_drawctxt_destroy(struct kgsl_context *context)
{
struct adreno_context *drawctxt;
if (context == NULL)
return;
drawctxt = ADRENO_CONTEXT(context);
kfree(drawctxt);
context->devctxt = NULL;
}
/**
@@ -274,10 +278,12 @@ void adreno_drawctxt_set_bin_base_offset(struct kgsl_device *device,
struct kgsl_context *context,
unsigned int offset)
{
struct adreno_context *drawctxt = context->devctxt;
struct adreno_context *drawctxt;
if (drawctxt)
drawctxt->bin_base_offset = offset;
if (context == NULL)
return;
drawctxt = ADRENO_CONTEXT(context);
drawctxt->bin_base_offset = offset;
}
/**
@@ -316,8 +322,8 @@ void adreno_drawctxt_switch(struct adreno_device *adreno_dev,
KGSL_CTXT_INFO(device, "from %d to %d flags %d\n",
adreno_dev->drawctxt_active ?
adreno_dev->drawctxt_active->id : 0,
drawctxt ? drawctxt->id : 0, flags);
adreno_dev->drawctxt_active->base.id : 0,
drawctxt ? drawctxt->base.id : 0, flags);
/* Save the old context */
adreno_dev->gpudev->ctxt_save(adreno_dev, adreno_dev->drawctxt_active);
+6 -14
View File
@@ -13,8 +13,6 @@
#ifndef __ADRENO_DRAWCTXT_H
#define __ADRENO_DRAWCTXT_H
#include <linux/sched.h>
#include "adreno_pm4types.h"
#include "a2xx_reg.h"
@@ -96,15 +94,10 @@ struct gmem_shadow_t {
};
struct adreno_context {
pid_t pid;
char pid_name[TASK_COMM_LEN];
unsigned int id;
struct kgsl_context base;
unsigned int ib_gpu_time_used;
uint32_t flags;
uint32_t pagefault;
unsigned long pagefault_ts;
unsigned int type;
struct kgsl_pagetable *pagetable;
struct kgsl_memdesc gpustate;
unsigned int reg_restore[3];
unsigned int shader_save[3];
@@ -131,16 +124,15 @@ struct adreno_context {
struct kgsl_memdesc constant_load_commands[3];
struct kgsl_memdesc cond_execs[4];
struct kgsl_memdesc hlsqcontrol_restore_commands[1];
struct kgsl_device_private *dev_priv;
};
int adreno_drawctxt_create(struct kgsl_device *device,
struct kgsl_pagetable *pagetable,
struct kgsl_context *context,
struct kgsl_context *adreno_drawctxt_create(struct kgsl_device_private *,
uint32_t *flags);
void adreno_drawctxt_destroy(struct kgsl_device *device,
struct kgsl_context *context);
void adreno_drawctxt_detach(struct kgsl_context *context);
void adreno_drawctxt_destroy(struct kgsl_context *context);
void adreno_drawctxt_switch(struct adreno_device *adreno_dev,
struct adreno_context *drawctxt,
+5 -12
View File
@@ -138,7 +138,7 @@ err:
if (context && context->flags & CTXT_FLAGS_GPU_HANG) {
KGSL_CTXT_WARN(rb->device,
"Context %p caused a gpu hang. Will not accept commands for context %d\n",
context, context->id);
context, context->base.id);
return -EDEADLK;
}
wait_time = jiffies + wait_timeout;
@@ -616,7 +616,7 @@ adreno_ringbuffer_addcmds(struct adreno_ringbuffer *rb,
*/
if ((context && (context->flags & CTXT_FLAGS_PER_CONTEXT_TS)) &&
!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE))
context_id = context->id;
context_id = context->base.id;
if ((context && (context->flags & CTXT_FLAGS_USER_GENERATED_TS)) &&
!(flags & KGSL_CMD_FLAGS_INTERNAL_ISSUE)) {
@@ -1097,12 +1097,9 @@ adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv,
ret = -EINVAL;
goto done;
}
drawctxt = context->devctxt;
drawctxt = ADRENO_CONTEXT(context);
if (drawctxt->flags & CTXT_FLAGS_GPU_HANG) {
KGSL_CTXT_ERR(device, "proc %s failed fault tolerance"
" will not accept commands for context %d\n",
drawctxt->pid_name, drawctxt->id);
ret = -EDEADLK;
goto done;
}
@@ -1116,10 +1113,6 @@ adreno_ringbuffer_issueibcmds(struct kgsl_device_private *dev_priv,
start_index = 1;
if (drawctxt->flags & CTXT_FLAGS_SKIP_EOF) {
KGSL_CTXT_ERR(device,
"proc %s triggered fault tolerance"
" skipping commands for context till EOF %d\n",
drawctxt->pid_name, drawctxt->id);
if (flags & KGSL_CMD_FLAGS_EOF)
drawctxt->flags &= ~CTXT_FLAGS_SKIP_EOF;
if (start_index)
@@ -1282,7 +1275,7 @@ void adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
k_ctxt = kgsl_context_get(device, ft_data->context_id);
if (k_ctxt) {
a_ctxt = k_ctxt->devctxt;
a_ctxt = ADRENO_CONTEXT(k_ctxt);
if (a_ctxt->flags & CTXT_FLAGS_PREAMBLE)
_turn_preamble_on_for_ib_seq(rb, rb_rptr);
kgsl_context_put(k_ctxt);
@@ -1319,7 +1312,7 @@ void adreno_ringbuffer_extract(struct adreno_ringbuffer *rb,
k_ctxt = kgsl_context_get(rb->device, val2);
if (k_ctxt) {
a_ctxt = k_ctxt->devctxt;
a_ctxt = ADRENO_CONTEXT(k_ctxt);
/* If we are changing to a good context and were not
* copying commands then copy over commands to the good
+64 -65
View File
@@ -448,20 +448,24 @@ static void kgsl_mem_entry_detach_process(struct kgsl_mem_entry *entry)
entry->priv = NULL;
}
/* Allocate a new context id */
static struct kgsl_context *
kgsl_create_context(struct kgsl_device_private *dev_priv)
/**
* kgsl_context_init() - helper to initialize kgsl_context members
* @dev_priv: the owner of the context
* @context: the newly created context struct, should be allocated by
* the device specific drawctxt_create function.
*
* This is a helper function for the device specific drawctxt_create
* function to initialize the common members of its context struct.
* If this function succeeds, reference counting is active in the context
* struct and the caller should kgsl_context_put() it on error.
* If it fails, the caller should just free the context structure
* it passed in.
*/
int kgsl_context_init(struct kgsl_device_private *dev_priv,
struct kgsl_context *context)
{
int ret = 0, id;
struct kgsl_device *device = dev_priv->device;
struct kgsl_context *context;
int ret, id = 0;
context = kzalloc(sizeof(*context), GFP_KERNEL);
if (context == NULL)
return ERR_PTR(-ENOMEM);
while (1) {
if (idr_pre_get(&device->context_idr, GFP_KERNEL) == 0) {
@@ -480,30 +484,26 @@ kgsl_create_context(struct kgsl_device_private *dev_priv)
}
if (ret)
goto func_end;
goto fail;
/* MAX - 1, there is one memdesc in memstore for device info */
if (id >= KGSL_MEMSTORE_MAX) {
KGSL_DRV_INFO(device, "cannot have more than %d "
"ctxts due to memstore limitation\n",
KGSL_MEMSTORE_MAX);
write_lock(&device->context_lock);
idr_remove(&device->context_idr, id);
write_unlock(&device->context_lock);
ret = -ENOSPC;
goto func_end;
goto fail_free_id;
}
kref_init(&context->refcount);
context->dev_priv = dev_priv;
context->device = dev_priv->device;
context->pagetable = dev_priv->process_priv->pagetable;
context->pid = dev_priv->process_priv->pid;
ret = kgsl_sync_timeline_create(context);
if (ret) {
write_lock(&device->context_lock);
idr_remove(&dev_priv->device->context_idr, id);
write_unlock(&device->context_lock);
goto func_end;
}
if (ret)
goto fail_free_id;
/* Initialize the pending event list */
INIT_LIST_HEAD(&context->events);
@@ -518,15 +518,15 @@ kgsl_create_context(struct kgsl_device_private *dev_priv)
*/
INIT_LIST_HEAD(&context->events_list);
func_end:
if (ret) {
kfree(context);
return ERR_PTR(ret);
}
return context;
return 0;
fail_free_id:
write_lock(&device->context_lock);
idr_remove(&dev_priv->device->context_idr, id);
write_unlock(&device->context_lock);
fail:
return ret;
}
EXPORT_SYMBOL(kgsl_context_init);
/**
* kgsl_context_detach - Release the "master" context reference
@@ -536,37 +536,36 @@ func_end:
* has requested for it to be destroyed. The context itself may
* exist a bit longer until its reference count goes to zero.
* Other code referencing the context can detect that it has been
* detached because the context id will be set to KGSL_CONTEXT_INVALID.
* detached by checking the KGSL_CONTEXT_DETACHED bit in
* context->priv.
*/
void
kgsl_context_detach(struct kgsl_context *context)
{
int id;
struct kgsl_device *device;
if (context == NULL)
return;
device = context->dev_priv->device;
trace_kgsl_context_detach(device, context);
id = context->id;
if (device->ftbl->drawctxt_destroy)
device->ftbl->drawctxt_destroy(device, context);
/*device specific drawctxt_destroy MUST clean up devctxt */
BUG_ON(context->devctxt);
device = context->device;
/*
* Mark the context as detached to keep others from using
* the context before it gets fully removed, and to make sure
* we don't try to detach twice.
*/
if (test_and_set_bit(KGSL_CONTEXT_DETACHED, &context->priv))
return;
trace_kgsl_context_detach(device, context);
device->ftbl->drawctxt_detach(context);
/*
* Cancel events after the device-specific context is
* destroyed, to avoid possibly freeing memory while
* detached, to avoid possibly freeing memory while
* it is still in use by the GPU.
*/
kgsl_cancel_events_ctxt(device, context);
write_lock(&device->context_lock);
context->id = KGSL_CONTEXT_INVALID;
idr_remove(&device->context_idr, id);
write_unlock(&device->context_lock);
context->dev_priv = NULL;
kgsl_context_put(context);
}
@@ -575,8 +574,19 @@ kgsl_context_destroy(struct kref *kref)
{
struct kgsl_context *context = container_of(kref, struct kgsl_context,
refcount);
struct kgsl_device *device = context->device;
trace_kgsl_context_destroy(device, context);
write_lock(&device->context_lock);
if (context->id != KGSL_CONTEXT_INVALID) {
idr_remove(&device->context_idr, context->id);
context->id = KGSL_CONTEXT_INVALID;
}
write_unlock(&device->context_lock);
kgsl_sync_timeline_destroy(context);
kfree(context);
device->ftbl->drawctxt_destroy(context);
}
struct kgsl_device *kgsl_get_device(int dev_idx)
@@ -975,7 +985,7 @@ static int kgsl_release(struct inode *inodep, struct file *filep)
if (context == NULL)
break;
if (context->dev_priv == dev_priv)
if (context->pid == private->pid)
kgsl_context_detach(context);
next = next + 1;
@@ -1623,27 +1633,16 @@ static long kgsl_ioctl_drawctxt_create(struct kgsl_device_private *dev_priv,
int result = 0;
struct kgsl_drawctxt_create *param = data;
struct kgsl_context *context = NULL;
struct kgsl_device *device = dev_priv->device;
context = kgsl_create_context(dev_priv);
context = device->ftbl->drawctxt_create(dev_priv, &param->flags);
if (IS_ERR(context)) {
result = PTR_ERR(context);
goto done;
}
if (dev_priv->device->ftbl->drawctxt_create) {
result = dev_priv->device->ftbl->drawctxt_create(
dev_priv->device, dev_priv->process_priv->pagetable,
context, &param->flags);
if (result)
goto done;
}
trace_kgsl_context_create(dev_priv->device, context, param->flags);
param->drawctxt_id = context->id;
done:
if (result && !IS_ERR(context))
kgsl_context_detach(context);
return result;
}
@@ -2600,7 +2599,7 @@ static long kgsl_ioctl_cff_syncmem(struct kgsl_device_private *dev_priv,
if (!entry)
return -EINVAL;
kgsl_cffdump_syncmem(dev_priv, &entry->memdesc, param->gpuaddr,
kgsl_cffdump_syncmem(dev_priv->device, &entry->memdesc, param->gpuaddr,
param->len, true);
kgsl_mem_entry_put(entry);
+5 -15
View File
@@ -410,29 +410,19 @@ void kgsl_cffdump_user_event(struct kgsl_device *device,
cffdump_printline(-1, cff_opcode, op1, op2, op3, op4, op5);
}
void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
struct kgsl_memdesc *memdesc, uint gpuaddr, uint sizebytes,
bool clean_cache)
void kgsl_cffdump_syncmem(struct kgsl_device *device,
struct kgsl_memdesc *memdesc, uint gpuaddr,
uint sizebytes, bool clean_cache)
{
struct kgsl_device *device = dev_priv->device;
const void *src;
if (!device->cff_dump_enable)
return;
BUG_ON(memdesc == NULL);
total_syncmem += sizebytes;
if (memdesc == NULL) {
struct kgsl_mem_entry *entry;
entry = kgsl_sharedmem_find_region(dev_priv->process_priv,
gpuaddr, sizebytes);
if (entry == NULL) {
KGSL_CORE_ERR("did not find mapping "
"for gpuaddr: 0x%08x\n", gpuaddr);
return;
}
memdesc = &entry->memdesc;
}
src = (uint *)kgsl_gpuaddr_to_vaddr(memdesc, gpuaddr);
if (memdesc->hostptr == NULL) {
KGSL_CORE_ERR(
+2 -2
View File
@@ -28,7 +28,7 @@ void kgsl_cffdump_init(void);
void kgsl_cffdump_destroy(void);
void kgsl_cffdump_open(struct kgsl_device *device);
void kgsl_cffdump_close(struct kgsl_device *device);
void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
void kgsl_cffdump_syncmem(struct kgsl_device *,
struct kgsl_memdesc *memdesc, uint physaddr, uint sizebytes,
bool clean_cache);
void kgsl_cffdump_setmem(struct kgsl_device *device, uint addr,
@@ -74,7 +74,7 @@ static inline void kgsl_cffdump_close(struct kgsl_device *device)
return;
}
static inline void kgsl_cffdump_syncmem(struct kgsl_device_private *dev_priv,
static inline void kgsl_cffdump_syncmem(struct kgsl_device *device,
struct kgsl_memdesc *memdesc, uint physaddr, uint sizebytes,
bool clean_cache)
{
+54 -19
View File
@@ -15,6 +15,7 @@
#include <linux/idr.h>
#include <linux/pm_qos.h>
#include <linux/sched.h>
#include "kgsl.h"
#include "kgsl_mmu.h"
@@ -103,11 +104,10 @@ struct kgsl_functable {
calling the hook */
void (*setstate) (struct kgsl_device *device, unsigned int context_id,
uint32_t flags);
int (*drawctxt_create) (struct kgsl_device *device,
struct kgsl_pagetable *pagetable, struct kgsl_context *context,
uint32_t *flags);
void (*drawctxt_destroy) (struct kgsl_device *device,
struct kgsl_context *context);
struct kgsl_context *(*drawctxt_create) (struct kgsl_device_private *,
uint32_t *flags);
void (*drawctxt_detach) (struct kgsl_context *context);
void (*drawctxt_destroy) (struct kgsl_context *context);
long (*ioctl) (struct kgsl_device_private *dev_priv,
unsigned int cmd, void *data);
int (*setproperty) (struct kgsl_device *device,
@@ -254,31 +254,44 @@ void kgsl_process_events(struct work_struct *work);
.ver_minor = DRIVER_VERSION_MINOR
/* bits for struct kgsl_context.priv */
/* the context has been destroyed by userspace and is no longer using the gpu */
#define KGSL_CONTEXT_DETACHED 0
/* the context has caused a pagefault */
#define KGSL_CONTEXT_PAGEFAULT 1
/**
* struct kgsl_context - Master structure for a KGSL context object
* @refcount - kref object for reference counting the context
* @id - integer identifier for the context
* @dev_priv - pointer to the owning device instance
* @devctxt - pointer to the device specific context information
* @reset_status - status indication whether a gpu reset occured and whether
* @refcount: kref object for reference counting the context
* @id: integer identifier for the context
* @priv: in-kernel context flags, use KGSL_CONTEXT_* values
* @dev_priv: pointer to the owning device instance
* @reset_status: status indication whether a gpu reset occured and whether
* this context was responsible for causing it
* @wait_on_invalid_ts - flag indicating if this context has tried to wait on a
* @wait_on_invalid_ts: flag indicating if this context has tried to wait on a
* bad timestamp
* @timeline - sync timeline used to create fences that can be signaled when a
* @timeline: sync timeline used to create fences that can be signaled when a
* sync_pt timestamp expires
* @events - list head of pending events for this context
* @events_list - list node for the list of all contexts that have pending events
* @events: list head of pending events for this context
* @events_list: list node for the list of all contexts that have pending events
* @pid: process that owns this context.
* @pagefault: flag set if this context caused a pagefault.
* @pagefault_ts: global timestamp of the pagefault, if KGSL_CONTEXT_PAGEFAULT
* is set.
*/
struct kgsl_context {
struct kref refcount;
uint32_t id;
struct kgsl_device_private *dev_priv;
void *devctxt;
pid_t pid;
unsigned long priv;
struct kgsl_device *device;
struct kgsl_pagetable *pagetable;
unsigned int reset_status;
bool wait_on_invalid_ts;
struct sync_timeline *timeline;
struct list_head events;
struct list_head events_list;
unsigned int pagefault_ts;
};
struct kgsl_process_private {
@@ -429,6 +442,9 @@ kgsl_device_get_drvdata(struct kgsl_device *dev)
void kgsl_context_destroy(struct kref *kref);
int kgsl_context_init(struct kgsl_device_private *, struct kgsl_context
*context);
/**
* kgsl_context_put() - Release context reference count
* @context: Pointer to the KGSL context to be released
@@ -442,6 +458,22 @@ kgsl_context_put(struct kgsl_context *context)
if (context)
kref_put(&context->refcount, kgsl_context_destroy);
}
/**
* kgsl_context_detached() - check if a context is detached
* @context: the context
*
* Check if a context has been destroyed by userspace and is only waiting
* for reference counts to go away. This check is used to weed out
* contexts that shouldn't use the gpu so NULL is considered detached.
*/
static inline bool kgsl_context_detached(struct kgsl_context *context)
{
return (context == NULL || test_bit(KGSL_CONTEXT_DETACHED,
&context->priv));
}
/**
* kgsl_context_get() - get a pointer to a KGSL context
* @device: Pointer to the KGSL device that owns the context
@@ -462,7 +494,10 @@ static inline struct kgsl_context *kgsl_context_get(struct kgsl_device *device,
context = idr_find(&device->context_idr, id);
if (context)
/* Don't return a context that has been detached */
if (kgsl_context_detached(context))
context = NULL;
else
kref_get(&context->refcount);
read_unlock(&device->context_lock);
@@ -489,8 +524,8 @@ static inline struct kgsl_context *kgsl_context_get_owner(
context = kgsl_context_get(dev_priv->device, id);
/* Verify that the context belongs to the dev_priv instance */
if (context && context->dev_priv != dev_priv) {
/* Verify that the context belongs to current calling process. */
if (context != NULL && context->pid != dev_priv->process_priv->pid) {
kgsl_context_put(context);
return NULL;
}
+5 -12
View File
@@ -327,7 +327,7 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
unsigned int no_page_fault_log = 0;
unsigned int curr_context_id = 0;
unsigned int curr_global_ts = 0;
static struct kgsl_context *context;
struct kgsl_context *context;
ret = get_iommu_unit(dev, &mmu, &iommu_unit);
if (ret)
@@ -401,23 +401,16 @@ static int kgsl_iommu_fault_handler(struct iommu_domain *domain,
context = kgsl_context_get(device, curr_context_id);
if (context != NULL) {
struct adreno_context *drawctxt = context->devctxt;
kgsl_sharedmem_readl(&device->memstore, &curr_global_ts,
KGSL_MEMSTORE_OFFSET(KGSL_MEMSTORE_GLOBAL,
eoptimestamp));
/*
* Store pagefault's timestamp in adreno context,
* this information will be used in GFT
*/
if (drawctxt != NULL) {
drawctxt->pagefault = 1;
drawctxt->pagefault_ts = curr_global_ts;
}
/* save pagefault timestamp for GFT */
set_bit(KGSL_CONTEXT_PAGEFAULT, &context->priv);
context->pagefault_ts = curr_global_ts;
kgsl_context_put(context);
context = NULL;
}
trace_kgsl_mmu_pagefault(iommu_dev->kgsldev, addr,
+1 -1
View File
@@ -109,7 +109,7 @@ static int snapshot_context_info(int id, void *ptr, void *data)
struct kgsl_device *device;
if (context)
device = context->dev_priv->device;
device = context->device;
else
device = (struct kgsl_device *)data;
+2 -2
View File
@@ -239,7 +239,7 @@ int kgsl_sync_timeline_create(struct kgsl_context *context)
char ktimeline_name[sizeof(context->timeline->name)] = {};
snprintf(ktimeline_name, sizeof(ktimeline_name),
"%s_%.15s(%d)-%.15s(%d)-%d",
context->dev_priv->device->name,
context->device->name,
current->group_leader->comm, current->group_leader->pid,
current->comm, current->pid, context->id);
@@ -250,7 +250,7 @@ int kgsl_sync_timeline_create(struct kgsl_context *context)
ktimeline = (struct kgsl_sync_timeline *) context->timeline;
ktimeline->last_timestamp = 0;
ktimeline->device = context->dev_priv->device;
ktimeline->device = context->device;
ktimeline->context_id = context->id;
return 0;
+22
View File
@@ -678,6 +678,28 @@ TRACE_EVENT(kgsl_context_detach,
)
);
TRACE_EVENT(kgsl_context_destroy,
TP_PROTO(struct kgsl_device *device, struct kgsl_context *context),
TP_ARGS(device, context),
TP_STRUCT__entry(
__string(device_name, device->name)
__field(unsigned int, id)
),
TP_fast_assign(
__assign_str(device_name, device->name);
__entry->id = context->id;
),
TP_printk(
"d_name=%s ctx=%u",
__get_str(device_name), __entry->id
)
);
TRACE_EVENT(kgsl_mmu_pagefault,
TP_PROTO(struct kgsl_device *device, unsigned int page,
+31 -5
View File
@@ -859,11 +859,30 @@ static int z180_wait(struct kgsl_device *device,
return status;
}
static void
z180_drawctxt_destroy(struct kgsl_device *device,
struct kgsl_context *context)
struct kgsl_context *
z180_drawctxt_create(struct kgsl_device_private *dev_priv,
uint32_t *flags)
{
struct z180_device *z180_dev = Z180_DEVICE(device);
int ret;
struct kgsl_context *context = kzalloc(sizeof(*context), GFP_KERNEL);
if (context == NULL)
return ERR_PTR(-ENOMEM);
ret = kgsl_context_init(dev_priv, context);
if (ret != 0) {
kfree(context);
return ERR_PTR(ret);
}
return context;
}
static void
z180_drawctxt_detach(struct kgsl_context *context)
{
struct kgsl_device *device;
struct z180_device *z180_dev;
device = context->device;
z180_dev = Z180_DEVICE(device);
z180_idle(device);
@@ -875,6 +894,12 @@ z180_drawctxt_destroy(struct kgsl_device *device,
}
}
static void
z180_drawctxt_destroy(struct kgsl_context *context)
{
kfree(context);
}
static void z180_power_stats(struct kgsl_device *device,
struct kgsl_power_stats *stats)
{
@@ -941,7 +966,8 @@ static const struct kgsl_functable z180_functable = {
.gpuid = z180_gpuid,
.irq_handler = z180_irq_handler,
/* Optional functions */
.drawctxt_create = NULL,
.drawctxt_create = z180_drawctxt_create,
.drawctxt_detach = z180_drawctxt_detach,
.drawctxt_destroy = z180_drawctxt_destroy,
.ioctl = NULL,
.postmortem_dump = z180_dump,