mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 09:57:08 +03:00
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:
committed by
Dan Willemsen
parent
f6587d13e4
commit
624d7a2830
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user