mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 01:50:07 +03:00
gpu: nvgpu: Cache channel state before dumping
Split channel debug dump into two phases. In first phase we just copy the data to a temporary buffer, and in second phase we dump the state from the temporary buffer. Change-Id: I2578b9fdaaa76f1230df7badbca9fcb5f3854e56 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/717886 Reviewed-by: Konsta Holtta <kholtta@nvidia.com>
This commit is contained in:
committed by
Dan Willemsen
parent
1eded55286
commit
78d8f8fe36
@@ -34,6 +34,11 @@
|
||||
unsigned int gk20a_debug_trace_cmdbuf;
|
||||
static struct platform_device *gk20a_device;
|
||||
|
||||
struct ch_state {
|
||||
int pid;
|
||||
u8 inst_block[0];
|
||||
};
|
||||
|
||||
static const char * const ccsr_chan_status_str[] = {
|
||||
"idle",
|
||||
"pending",
|
||||
@@ -97,23 +102,25 @@ void gk20a_debug_output(struct gk20a_debug_output *o,
|
||||
|
||||
static void gk20a_debug_show_channel(struct gk20a *g,
|
||||
struct gk20a_debug_output *o,
|
||||
struct channel_gk20a *ch)
|
||||
u32 hw_chid,
|
||||
struct ch_state *ch_state)
|
||||
{
|
||||
u32 channel = gk20a_readl(g, ccsr_channel_r(ch->hw_chid));
|
||||
u32 channel = gk20a_readl(g, ccsr_channel_r(hw_chid));
|
||||
u32 status = ccsr_channel_status_v(channel);
|
||||
u32 syncpointa, syncpointb;
|
||||
void *inst_ptr;
|
||||
|
||||
inst_ptr = ch->inst_block.cpu_va;
|
||||
if (!inst_ptr)
|
||||
if (!ch_state)
|
||||
return;
|
||||
|
||||
inst_ptr = &ch_state->inst_block[0];
|
||||
|
||||
syncpointa = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointa_w());
|
||||
syncpointb = gk20a_mem_rd32(inst_ptr, ram_fc_syncpointb_w());
|
||||
|
||||
gk20a_debug_output(o, "%d-%s, pid %d: ", ch->hw_chid,
|
||||
ch->g->dev->name,
|
||||
ch->pid);
|
||||
gk20a_debug_output(o, "%d-%s, pid %d: ", hw_chid,
|
||||
g->dev->name,
|
||||
ch_state->pid);
|
||||
gk20a_debug_output(o, "%s in use %s %s\n",
|
||||
ccsr_channel_enable_v(channel) ? "" : "not",
|
||||
ccsr_chan_status_str[status],
|
||||
@@ -160,6 +167,8 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o)
|
||||
u32 chid;
|
||||
int i, err;
|
||||
|
||||
struct ch_state **ch_state;
|
||||
|
||||
err = gk20a_busy(g->dev);
|
||||
if (err) {
|
||||
gk20a_debug_output(o, "failed to power on gpu: %d\n", err);
|
||||
@@ -214,12 +223,34 @@ void gk20a_debug_show_dump(struct gk20a *g, struct gk20a_debug_output *o)
|
||||
}
|
||||
gk20a_debug_output(o, "\n");
|
||||
|
||||
ch_state = kzalloc(sizeof(*ch_state)
|
||||
* f->num_channels, GFP_KERNEL);
|
||||
if (!ch_state) {
|
||||
gk20a_debug_output(o, "cannot alloc memory for channels\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
for (chid = 0; chid < f->num_channels; chid++) {
|
||||
if (f->channel[chid].in_use) {
|
||||
struct channel_gk20a *gpu_ch = &f->channel[chid];
|
||||
gk20a_debug_show_channel(g, o, gpu_ch);
|
||||
if (f->channel[chid].in_use)
|
||||
ch_state[chid] = kmalloc(sizeof(struct ch_state) + ram_in_alloc_size_v(), GFP_KERNEL);
|
||||
}
|
||||
|
||||
for (chid = 0; chid < f->num_channels; chid++) {
|
||||
if (ch_state[chid] && f->channel[chid].inst_block.cpu_va) {
|
||||
ch_state[chid]->pid = f->channel[chid].pid;
|
||||
memcpy(&ch_state[chid]->inst_block[0],
|
||||
f->channel[chid].inst_block.cpu_va,
|
||||
ram_in_alloc_size_v());
|
||||
}
|
||||
}
|
||||
for (chid = 0; chid < f->num_channels; chid++) {
|
||||
if (ch_state[chid]) {
|
||||
gk20a_debug_show_channel(g, o, chid, ch_state[chid]);
|
||||
kfree(ch_state[chid]);
|
||||
}
|
||||
}
|
||||
kfree(ch_state);
|
||||
done:
|
||||
gk20a_idle(g->dev);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user