mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-22 17:36:20 +03:00
gpu: nvgpu: define error_notifiers in common code
All the linux specific error_notifier codes are defined in linux specific header file <uapi/linux/nvgpu.h> and used in all the common driver But since they are defined in linux specific file, we need to move all the uses of those error_notifiers in linux specific code only Hence define new error_notifiers in include/nvgpu/error_notifier.h and use them in the common code Add new API nvgpu_error_notifier_to_channel_notifier() to convert common error_notifier of the form NVGPU_ERR_NOTIFIER_* to linux specific error notifier of the form NVGPU_CHANNEL_* Any future additions to error notifiers requires update to both the form of error notifiers Move all error notifier related metadata from channel_gk20a (common code) to linux specific structure nvgpu_channel_linux Update all accesses to this data from new structure instead of channel_gk20a Move and rename below APIs to linux specific file and declare them in error_notifier.h nvgpu_set_error_notifier_locked() nvgpu_set_error_notifier() nvgpu_is_error_notifier_set() Add below new API and use it in fifo_vgpu.c nvgpu_set_error_notifier_if_empty() Include <nvgpu/error_notifier.h> wherever new error_notifier codes are used NVGPU-426 Change-Id: Iaa5bfc150e6e9ec17d797d445c2d6407afe9f4bd Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1593361 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
committed by
mobile promotions
parent
a0cea295e7
commit
c6b9177cff
@@ -17,6 +17,7 @@
|
||||
#include <nvgpu/enabled.h>
|
||||
#include <nvgpu/debug.h>
|
||||
#include <nvgpu/ltc.h>
|
||||
#include <nvgpu/error_notifier.h>
|
||||
|
||||
/*
|
||||
* This is required for nvgpu_vm_find_buf() which is used in the tracing
|
||||
@@ -37,6 +38,124 @@
|
||||
#include <trace/events/gk20a.h>
|
||||
#include <uapi/linux/nvgpu.h>
|
||||
|
||||
/*
|
||||
* API to convert error_notifiers in common code and of the form
|
||||
* NVGPU_ERR_NOTIFIER_* into Linux specific error_notifiers exposed to user
|
||||
* space and of the form NVGPU_CHANNEL_*
|
||||
*/
|
||||
static u32 nvgpu_error_notifier_to_channel_notifier(u32 error_notifier)
|
||||
{
|
||||
switch (error_notifier) {
|
||||
case NVGPU_ERR_NOTIFIER_FIFO_ERROR_IDLE_TIMEOUT:
|
||||
return NVGPU_CHANNEL_FIFO_ERROR_IDLE_TIMEOUT;
|
||||
case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_METHOD:
|
||||
return NVGPU_CHANNEL_GR_ERROR_SW_METHOD;
|
||||
case NVGPU_ERR_NOTIFIER_GR_ERROR_SW_NOTIFY:
|
||||
return NVGPU_CHANNEL_GR_ERROR_SW_NOTIFY;
|
||||
case NVGPU_ERR_NOTIFIER_GR_EXCEPTION:
|
||||
return NVGPU_CHANNEL_GR_EXCEPTION;
|
||||
case NVGPU_ERR_NOTIFIER_GR_SEMAPHORE_TIMEOUT:
|
||||
return NVGPU_CHANNEL_GR_SEMAPHORE_TIMEOUT;
|
||||
case NVGPU_ERR_NOTIFIER_GR_ILLEGAL_NOTIFY:
|
||||
return NVGPU_CHANNEL_GR_ILLEGAL_NOTIFY;
|
||||
case NVGPU_ERR_NOTIFIER_FIFO_ERROR_MMU_ERR_FLT:
|
||||
return NVGPU_CHANNEL_FIFO_ERROR_MMU_ERR_FLT;
|
||||
case NVGPU_ERR_NOTIFIER_PBDMA_ERROR:
|
||||
return NVGPU_CHANNEL_PBDMA_ERROR;
|
||||
case NVGPU_ERR_NOTIFIER_FECS_ERR_UNIMP_FIRMWARE_METHOD:
|
||||
return NVGPU_CHANNEL_FECS_ERR_UNIMP_FIRMWARE_METHOD;
|
||||
case NVGPU_ERR_NOTIFIER_RESETCHANNEL_VERIF_ERROR:
|
||||
return NVGPU_CHANNEL_RESETCHANNEL_VERIF_ERROR;
|
||||
case NVGPU_ERR_NOTIFIER_PBDMA_PUSHBUFFER_CRC_MISMATCH:
|
||||
return NVGPU_CHANNEL_PBDMA_PUSHBUFFER_CRC_MISMATCH;
|
||||
}
|
||||
|
||||
pr_warn("%s: invalid error_notifier requested %u\n", __func__, error_notifier);
|
||||
|
||||
return error_notifier;
|
||||
}
|
||||
|
||||
/**
|
||||
* nvgpu_set_error_notifier_locked()
|
||||
* Should be called with ch->error_notifier_mutex held
|
||||
*
|
||||
* error should be of the form NVGPU_ERR_NOTIFIER_*
|
||||
*/
|
||||
void nvgpu_set_error_notifier_locked(struct channel_gk20a *ch, u32 error)
|
||||
{
|
||||
struct nvgpu_channel_linux *priv = ch->os_priv;
|
||||
|
||||
error = nvgpu_error_notifier_to_channel_notifier(error);
|
||||
|
||||
if (priv->error_notifier.dmabuf) {
|
||||
struct nvgpu_notification *notification =
|
||||
priv->error_notifier.notification;
|
||||
struct timespec time_data;
|
||||
u64 nsec;
|
||||
|
||||
getnstimeofday(&time_data);
|
||||
nsec = ((u64)time_data.tv_sec) * 1000000000u +
|
||||
(u64)time_data.tv_nsec;
|
||||
notification->time_stamp.nanoseconds[0] =
|
||||
(u32)nsec;
|
||||
notification->time_stamp.nanoseconds[1] =
|
||||
(u32)(nsec >> 32);
|
||||
notification->info32 = error;
|
||||
notification->status = 0xffff;
|
||||
|
||||
nvgpu_err(ch->g,
|
||||
"error notifier set to %d for ch %d", error, ch->chid);
|
||||
}
|
||||
}
|
||||
|
||||
/* error should be of the form NVGPU_ERR_NOTIFIER_* */
|
||||
void nvgpu_set_error_notifier(struct channel_gk20a *ch, u32 error)
|
||||
{
|
||||
struct nvgpu_channel_linux *priv = ch->os_priv;
|
||||
|
||||
nvgpu_mutex_acquire(&priv->error_notifier.mutex);
|
||||
nvgpu_set_error_notifier_locked(ch, error);
|
||||
nvgpu_mutex_release(&priv->error_notifier.mutex);
|
||||
}
|
||||
|
||||
void nvgpu_set_error_notifier_if_empty(struct channel_gk20a *ch, u32 error)
|
||||
{
|
||||
struct nvgpu_channel_linux *priv = ch->os_priv;
|
||||
|
||||
nvgpu_mutex_acquire(&priv->error_notifier.mutex);
|
||||
if (priv->error_notifier.dmabuf) {
|
||||
struct nvgpu_notification *notification =
|
||||
priv->error_notifier.notification;
|
||||
|
||||
/* Don't overwrite error flag if it is already set */
|
||||
if (notification->status != 0xffff)
|
||||
nvgpu_set_error_notifier_locked(ch, error);
|
||||
}
|
||||
nvgpu_mutex_release(&priv->error_notifier.mutex);
|
||||
}
|
||||
|
||||
/* error_notifier should be of the form NVGPU_ERR_NOTIFIER_* */
|
||||
bool nvgpu_is_error_notifier_set(struct channel_gk20a *ch, u32 error_notifier)
|
||||
{
|
||||
struct nvgpu_channel_linux *priv = ch->os_priv;
|
||||
bool notifier_set = false;
|
||||
|
||||
error_notifier = nvgpu_error_notifier_to_channel_notifier(error_notifier);
|
||||
|
||||
nvgpu_mutex_acquire(&priv->error_notifier.mutex);
|
||||
if (priv->error_notifier.dmabuf) {
|
||||
struct nvgpu_notification *notification =
|
||||
priv->error_notifier.notification;
|
||||
u32 err = notification->info32;
|
||||
|
||||
if (err == error_notifier)
|
||||
notifier_set = true;
|
||||
}
|
||||
nvgpu_mutex_release(&priv->error_notifier.mutex);
|
||||
|
||||
return notifier_set;
|
||||
}
|
||||
|
||||
static void gk20a_channel_update_runcb_fn(struct work_struct *work)
|
||||
{
|
||||
struct nvgpu_channel_completion_cb *completion_cb =
|
||||
@@ -128,6 +247,7 @@ static void nvgpu_channel_close_linux(struct channel_gk20a *ch)
|
||||
static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch)
|
||||
{
|
||||
struct nvgpu_channel_linux *priv;
|
||||
int err;
|
||||
|
||||
priv = nvgpu_kzalloc(g, sizeof(*priv));
|
||||
if (!priv)
|
||||
@@ -136,6 +256,12 @@ static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch)
|
||||
ch->os_priv = priv;
|
||||
priv->ch = ch;
|
||||
|
||||
err = nvgpu_mutex_init(&priv->error_notifier.mutex);
|
||||
if (err) {
|
||||
nvgpu_kfree(g, priv);
|
||||
return err;
|
||||
}
|
||||
|
||||
nvgpu_channel_work_completion_init(ch);
|
||||
|
||||
return 0;
|
||||
@@ -143,7 +269,10 @@ static int nvgpu_channel_alloc_linux(struct gk20a *g, struct channel_gk20a *ch)
|
||||
|
||||
static void nvgpu_channel_free_linux(struct gk20a *g, struct channel_gk20a *ch)
|
||||
{
|
||||
nvgpu_kfree(g, ch->os_priv);
|
||||
struct nvgpu_channel_linux *priv = ch->os_priv;
|
||||
|
||||
nvgpu_mutex_destroy(&priv->error_notifier.mutex);
|
||||
nvgpu_kfree(g, priv);
|
||||
}
|
||||
|
||||
int nvgpu_init_channel_support_linux(struct nvgpu_os_linux *l)
|
||||
|
||||
Reference in New Issue
Block a user