From 624d7a2830370ec13402b964a1c8ff564249ddb6 Mon Sep 17 00:00:00 2001 From: Aingara Paramakuru Date: Wed, 24 Dec 2014 12:24:33 -0500 Subject: 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 Reviewed-on: http://git-master/r/670329 Reviewed-by: Terje Bergstrom --- drivers/gpu/nvgpu/vgpu/fifo_vgpu.c | 53 +++++++++++++++++++++++++++- drivers/gpu/nvgpu/vgpu/gr_vgpu.c | 71 ++++++++++++++++++++++---------------- drivers/gpu/nvgpu/vgpu/vgpu.c | 4 ++- drivers/gpu/nvgpu/vgpu/vgpu.h | 12 +++++-- include/linux/tegra_vgpu.h | 24 +++++++++++-- 5 files changed, 128 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c index 24b9f4be..45d956a2 100644 --- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c @@ -1,7 +1,7 @@ /* * 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 * 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; } +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) { gops->fifo.bind_channel = vgpu_channel_bind; diff --git a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c index b1a8027e..aac097d9 100644 --- a/drivers/gpu/nvgpu/vgpu/gr_vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/gr_vgpu.c @@ -1,7 +1,7 @@ /* * 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 * 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); } -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) { - struct gr_isr_data isr_data; + struct fifo_gk20a *f = &g->fifo; + struct channel_gk20a *ch = &f->channel[info->chid]; gk20a_dbg_fn(""); - - isr_data.chid = info->chid; - - if (info->type == TEGRA_VGPU_GR_INTR_NOTIFY) - vgpu_gr_handle_notify_pending(g, &isr_data); + if (info->type != TEGRA_VGPU_GR_INTR_NOTIFY) + gk20a_err(dev_from_gk20a(g), "gr intr (%d) on ch %u", + info->type, info->chid); + + switch (info->type) { + case TEGRA_VGPU_GR_INTR_NOTIFY: + wake_up(&ch->notifier_wq); + 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; } diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.c b/drivers/gpu/nvgpu/vgpu/vgpu.c index 36d65ee8..d3d793d1 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.c +++ b/drivers/gpu/nvgpu/vgpu/vgpu.c @@ -1,7 +1,7 @@ /* * 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 * 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) 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); } diff --git a/drivers/gpu/nvgpu/vgpu/vgpu.h b/drivers/gpu/nvgpu/vgpu/vgpu.h index 4677b36c..1a7ef7ba 100644 --- a/drivers/gpu/nvgpu/vgpu/vgpu.h +++ b/drivers/gpu/nvgpu/vgpu/vgpu.h @@ -27,6 +27,7 @@ int vgpu_probe(struct platform_device *dev); int vgpu_remove(struct platform_device *dev); 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_fifo_isr(struct gk20a *g, struct tegra_vgpu_fifo_intr_info *info); void vgpu_init_fifo_ops(struct gpu_ops *gops); void vgpu_init_gr_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; } -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; } -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; } diff --git a/include/linux/tegra_vgpu.h b/include/linux/tegra_vgpu.h index e0a7ff66..61ffff70 100644 --- a/include/linux/tegra_vgpu.h +++ b/include/linux/tegra_vgpu.h @@ -1,7 +1,7 @@ /* * 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 * under the terms and conditions of the GNU General Public License, @@ -210,7 +210,18 @@ struct tegra_vgpu_cmd_msg { }; 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 { @@ -218,8 +229,14 @@ struct tegra_vgpu_gr_intr_info { u32 chid; }; +struct tegra_vgpu_fifo_intr_info { + u32 type; + u32 chid; +}; + enum { - TEGRA_VGPU_INTR_GR = 0 + TEGRA_VGPU_INTR_GR = 0, + TEGRA_VGPU_INTR_FIFO }; enum { @@ -232,6 +249,7 @@ struct tegra_vgpu_intr_msg { u32 unit; union { struct tegra_vgpu_gr_intr_info gr_intr; + struct tegra_vgpu_fifo_intr_info fifo_intr; } info; }; -- cgit v1.2.2