gpu: nvgpu: vgpu: handle fifo and gr exceptions

Handle the gr and fifo exceptions delivered from the server
and update the channel state as needed.

Bug 1551865

Change-Id: Ie19626c6e8a72f92ffd134983fe6d84e5c6c8736
Signed-off-by: Aingara Paramakuru <aparamakuru@nvidia.com>
Reviewed-on: http://git-master/r/670329
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
This commit is contained in:
Aingara Paramakuru
2014-12-24 12:24:33 -05:00
committed by Dan Willemsen
parent f6587d13e4
commit 624d7a2830
5 changed files with 127 additions and 35 deletions

View File

@@ -1,7 +1,7 @@
/* /*
* Virtualized GPU Fifo * Virtualized GPU Fifo
* *
* Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -551,6 +551,57 @@ static int vgpu_fifo_wait_engine_idle(struct gk20a *g)
return 0; return 0;
} }
static void vgpu_fifo_set_ctx_mmu_error(struct gk20a *g,
struct channel_gk20a *ch)
{
if (ch->error_notifier) {
if (ch->error_notifier->status == 0xffff) {
/* If error code is already set, this mmu fault
* was triggered as part of recovery from other
* error condition.
* Don't overwrite error flag. */
} else {
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT);
}
}
/* mark channel as faulted */
ch->has_timedout = true;
wmb();
/* unblock pending waits */
wake_up(&ch->semaphore_wq);
wake_up(&ch->notifier_wq);
wake_up(&ch->submit_wq);
}
int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info)
{
struct fifo_gk20a *f = &g->fifo;
struct channel_gk20a *ch = &f->channel[info->chid];
gk20a_err(dev_from_gk20a(g), "fifo intr (%d) on ch %u",
info->type, info->chid);
switch (info->type) {
case TEGRA_VGPU_FIFO_INTR_PBDMA:
gk20a_set_error_notifier(ch, NVGPU_CHANNEL_PBDMA_ERROR);
break;
case TEGRA_VGPU_FIFO_INTR_CTXSW_TIMEOUT:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT);
break;
case TEGRA_VGPU_FIFO_INTR_MMU_FAULT:
gk20a_channel_abort(ch);
vgpu_fifo_set_ctx_mmu_error(g, ch);
break;
default:
WARN_ON(1);
break;
}
return 0;
}
void vgpu_init_fifo_ops(struct gpu_ops *gops) void vgpu_init_fifo_ops(struct gpu_ops *gops)
{ {
gops->fifo.bind_channel = vgpu_channel_bind; gops->fifo.bind_channel = vgpu_channel_bind;

View File

@@ -1,7 +1,7 @@
/* /*
* Virtualized GPU Graphics * Virtualized GPU Graphics
* *
* Copyright (c) 2014 NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -668,38 +668,51 @@ int vgpu_init_gr_support(struct gk20a *g)
return vgpu_gr_init_gr_setup_sw(g); return vgpu_gr_init_gr_setup_sw(g);
} }
struct gr_isr_data {
u32 addr;
u32 data_lo;
u32 data_hi;
u32 curr_ctx;
u32 chid;
u32 offset;
u32 sub_chan;
u32 class_num;
};
static int vgpu_gr_handle_notify_pending(struct gk20a *g,
struct gr_isr_data *isr_data)
{
struct fifo_gk20a *f = &g->fifo;
struct channel_gk20a *ch = &f->channel[isr_data->chid];
gk20a_dbg_fn("");
wake_up(&ch->notifier_wq);
return 0;
}
int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info) int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info)
{ {
struct gr_isr_data isr_data; struct fifo_gk20a *f = &g->fifo;
struct channel_gk20a *ch = &f->channel[info->chid];
gk20a_dbg_fn(""); gk20a_dbg_fn("");
if (info->type != TEGRA_VGPU_GR_INTR_NOTIFY)
gk20a_err(dev_from_gk20a(g), "gr intr (%d) on ch %u",
info->type, info->chid);
isr_data.chid = info->chid; switch (info->type) {
case TEGRA_VGPU_GR_INTR_NOTIFY:
if (info->type == TEGRA_VGPU_GR_INTR_NOTIFY) wake_up(&ch->notifier_wq);
vgpu_gr_handle_notify_pending(g, &isr_data); break;
case TEGRA_VGPU_GR_INTR_SEMAPHORE_TIMEOUT:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_SEMAPHORE_TIMEOUT);
break;
case TEGRA_VGPU_GR_INTR_ILLEGAL_NOTIFY:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_ILLEGAL_NOTIFY);
case TEGRA_VGPU_GR_INTR_ILLEGAL_METHOD:
break;
case TEGRA_VGPU_GR_INTR_ILLEGAL_CLASS:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY);
break;
case TEGRA_VGPU_GR_INTR_FECS_ERROR:
break;
case TEGRA_VGPU_GR_INTR_CLASS_ERROR:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY);
break;
case TEGRA_VGPU_GR_INTR_FIRMWARE_METHOD:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY);
break;
case TEGRA_VGPU_GR_INTR_EXCEPTION:
gk20a_set_error_notifier(ch,
NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY);
break;
default:
WARN_ON(1);
break;
}
return 0; return 0;
} }

View File

@@ -1,7 +1,7 @@
/* /*
* Virtualized GPU * Virtualized GPU
* *
* Copyright (c) 2014-2015 NVIDIA CORPORATION. All rights reserved. * Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -114,6 +114,8 @@ static int vgpu_intr_thread(void *dev_id)
if (msg->unit == TEGRA_VGPU_INTR_GR) if (msg->unit == TEGRA_VGPU_INTR_GR)
vgpu_gr_isr(g, &msg->info.gr_intr); vgpu_gr_isr(g, &msg->info.gr_intr);
else if (msg->unit == TEGRA_VGPU_INTR_FIFO)
vgpu_fifo_isr(g, &msg->info.fifo_intr);
tegra_gr_comm_release(handle); tegra_gr_comm_release(handle);
} }

View File

@@ -27,6 +27,7 @@ int vgpu_probe(struct platform_device *dev);
int vgpu_remove(struct platform_device *dev); int vgpu_remove(struct platform_device *dev);
u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt, u64 size); u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt, u64 size);
int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info); int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info);
int vgpu_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info);
void vgpu_init_fifo_ops(struct gpu_ops *gops); void vgpu_init_fifo_ops(struct gpu_ops *gops);
void vgpu_init_gr_ops(struct gpu_ops *gops); void vgpu_init_gr_ops(struct gpu_ops *gops);
void vgpu_init_ltc_ops(struct gpu_ops *gops); void vgpu_init_ltc_ops(struct gpu_ops *gops);
@@ -56,11 +57,18 @@ static inline int vgpu_remove(struct platform_device *dev)
{ {
return -ENOSYS; return -ENOSYS;
} }
static inline u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt, u64 size) static inline u64 vgpu_bar1_map(struct gk20a *g, struct sg_table **sgt,
u64 size)
{ {
return 0; return 0;
} }
static inline int vgpu_gr_isr(struct gk20a *g, struct tegra_vgpu_gr_intr_info *info) static inline int vgpu_gr_isr(struct gk20a *g,
struct tegra_vgpu_gr_intr_info *info)
{
return 0;
}
static inline int vgpu_fifo_isr(struct gk20a *g,
struct tegra_vgpu_fifo_intr_info *info)
{ {
return 0; return 0;
} }

View File

@@ -1,7 +1,7 @@
/* /*
* Tegra GPU Virtualization Interfaces to Server * Tegra GPU Virtualization Interfaces to Server
* *
* Copyright (c) 2014, NVIDIA Corporation. All rights reserved. * Copyright (c) 2014-2015, NVIDIA Corporation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
@@ -210,7 +210,18 @@ struct tegra_vgpu_cmd_msg {
}; };
enum { enum {
TEGRA_VGPU_GR_INTR_NOTIFY = 0 TEGRA_VGPU_GR_INTR_NOTIFY = 0,
TEGRA_VGPU_GR_INTR_SEMAPHORE_TIMEOUT,
TEGRA_VGPU_GR_INTR_ILLEGAL_NOTIFY,
TEGRA_VGPU_GR_INTR_ILLEGAL_METHOD,
TEGRA_VGPU_GR_INTR_ILLEGAL_CLASS,
TEGRA_VGPU_GR_INTR_FECS_ERROR,
TEGRA_VGPU_GR_INTR_CLASS_ERROR,
TEGRA_VGPU_GR_INTR_FIRMWARE_METHOD,
TEGRA_VGPU_GR_INTR_EXCEPTION,
TEGRA_VGPU_FIFO_INTR_PBDMA,
TEGRA_VGPU_FIFO_INTR_CTXSW_TIMEOUT,
TEGRA_VGPU_FIFO_INTR_MMU_FAULT
}; };
struct tegra_vgpu_gr_intr_info { struct tegra_vgpu_gr_intr_info {
@@ -218,8 +229,14 @@ struct tegra_vgpu_gr_intr_info {
u32 chid; u32 chid;
}; };
struct tegra_vgpu_fifo_intr_info {
u32 type;
u32 chid;
};
enum { enum {
TEGRA_VGPU_INTR_GR = 0 TEGRA_VGPU_INTR_GR = 0,
TEGRA_VGPU_INTR_FIFO
}; };
enum { enum {
@@ -232,6 +249,7 @@ struct tegra_vgpu_intr_msg {
u32 unit; u32 unit;
union { union {
struct tegra_vgpu_gr_intr_info gr_intr; struct tegra_vgpu_gr_intr_info gr_intr;
struct tegra_vgpu_fifo_intr_info fifo_intr;
} info; } info;
}; };