mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 10:34:43 +03:00
gpu: nvgpu: enable semaphore acquire timeout
It'll detect dead semaphore acquire. The worst case is when ACQUIRE_SWITCH is disabled, semaphore acquire will poll and consume full gpu timeslicees. The timeout value is set to half of channel WDT. Bug 1636800 Change-Id: Ida6ccc534006a191513edf47e7b82d4b5b758684 Signed-off-by: Richard Zhao <rizhao@nvidia.com> Reviewed-on: http://git-master/r/928827 GVS: Gerrit_Virtual_Submit Reviewed-by: Vladislav Buzov <vbuzov@nvidia.com>
This commit is contained in:
committed by
Vladislav Buzov
parent
3484fd0d13
commit
a9c6f59539
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* GK20A Graphics channel
|
||||
*
|
||||
* Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2011-2016, 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,
|
||||
@@ -62,6 +62,8 @@ static int channel_gk20a_update_runlist(struct channel_gk20a *c,
|
||||
bool add);
|
||||
static void gk20a_free_error_notifiers(struct channel_gk20a *ch);
|
||||
|
||||
static u32 gk20a_get_channel_watchdog_timeout(struct channel_gk20a *ch);
|
||||
|
||||
/* allocate GPU channel */
|
||||
static struct channel_gk20a *allocate_channel(struct fifo_gk20a *f)
|
||||
{
|
||||
@@ -204,6 +206,38 @@ static int channel_gk20a_set_schedule_params(struct channel_gk20a *c,
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 channel_gk20a_pbdma_acquire_val(struct channel_gk20a *c)
|
||||
{
|
||||
u32 val, exp, man;
|
||||
u64 timeout;
|
||||
int val_len;
|
||||
|
||||
timeout = gk20a_get_channel_watchdog_timeout(c);
|
||||
do_div(timeout, 2); /* set acquire timeout to half of channel wdt */
|
||||
timeout *= 1000000UL; /* ms -> ns */
|
||||
do_div(timeout, 1024); /* in unit of 1024ns */
|
||||
val_len = fls(timeout >> 32) + 32;
|
||||
if (val_len == 32)
|
||||
val_len = fls(timeout);
|
||||
if (val_len > 16 + pbdma_acquire_timeout_exp_max_v()) { /* man: 16bits */
|
||||
exp = pbdma_acquire_timeout_exp_max_v();
|
||||
man = pbdma_acquire_timeout_man_max_v();
|
||||
} else if (val_len > 16) {
|
||||
exp = val_len - 16;
|
||||
man = timeout >> exp;
|
||||
} else {
|
||||
exp = 0;
|
||||
man = timeout;
|
||||
}
|
||||
|
||||
val = pbdma_acquire_retry_man_2_f() |
|
||||
pbdma_acquire_retry_exp_2_f() |
|
||||
pbdma_acquire_timeout_exp_f(exp) |
|
||||
pbdma_acquire_timeout_man_f(man) |
|
||||
pbdma_acquire_timeout_en_enable_f();
|
||||
return val;
|
||||
}
|
||||
|
||||
int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
|
||||
u64 gpfifo_base, u32 gpfifo_entries, u32 flags)
|
||||
{
|
||||
@@ -249,11 +283,7 @@ int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
|
||||
gk20a_mem_wr32(inst_ptr, ram_fc_target_w(), pbdma_target_engine_sw_f());
|
||||
|
||||
gk20a_mem_wr32(inst_ptr, ram_fc_acquire_w(),
|
||||
pbdma_acquire_retry_man_2_f() |
|
||||
pbdma_acquire_retry_exp_2_f() |
|
||||
pbdma_acquire_timeout_exp_max_f() |
|
||||
pbdma_acquire_timeout_man_max_f() |
|
||||
pbdma_acquire_timeout_en_disable_f());
|
||||
channel_gk20a_pbdma_acquire_val(c));
|
||||
|
||||
gk20a_mem_wr32(inst_ptr, ram_fc_runlist_timeslice_w(),
|
||||
fifo_runlist_timeslice_timeout_128_f() |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* GK20A graphics channel
|
||||
*
|
||||
* Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2011-2016, 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,
|
||||
@@ -252,6 +252,7 @@ void channel_gk20a_unbind(struct channel_gk20a *ch_gk20a);
|
||||
void channel_gk20a_disable(struct channel_gk20a *ch);
|
||||
int channel_gk20a_alloc_inst(struct gk20a *g, struct channel_gk20a *ch);
|
||||
void channel_gk20a_free_inst(struct gk20a *g, struct channel_gk20a *ch);
|
||||
u32 channel_gk20a_pbdma_acquire_val(struct channel_gk20a *c);
|
||||
int channel_gk20a_setup_ramfc(struct channel_gk20a *c,
|
||||
u64 gpfifo_base, u32 gpfifo_entries, u32 flags);
|
||||
void channel_gk20a_enable(struct channel_gk20a *ch);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* GK20A Graphics FIFO (gr host)
|
||||
*
|
||||
* Copyright (c) 2011-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2011-2016, 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,
|
||||
@@ -1642,6 +1642,12 @@ static u32 gk20a_fifo_handle_pbdma_intr(struct device *dev,
|
||||
pbdma_intr_0);
|
||||
}
|
||||
|
||||
if (pbdma_intr_0 & pbdma_intr_0_acquire_pending_f()) {
|
||||
u32 val = gk20a_readl(g, pbdma_acquire_r(pbdma_id));
|
||||
val &= ~pbdma_acquire_timeout_en_enable_f();
|
||||
gk20a_writel(g, pbdma_acquire_r(pbdma_id), val);
|
||||
}
|
||||
|
||||
if (pbdma_intr_0 & pbdma_intr_0_pbentry_pending_f()) {
|
||||
gk20a_fifo_reset_pbdma_header(g, pbdma_id);
|
||||
gk20a_fifo_reset_pbdma_method(g, pbdma_id, 0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2012-2016, 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,
|
||||
@@ -274,14 +274,34 @@ static inline u32 pbdma_acquire_retry_exp_2_f(void)
|
||||
{
|
||||
return 0x100;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_f(u32 v)
|
||||
{
|
||||
return (v & 0xf) << 11;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_max_v(void)
|
||||
{
|
||||
return 0x0000000f;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_max_f(void)
|
||||
{
|
||||
return 0x7800;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_f(u32 v)
|
||||
{
|
||||
return (v & 0xffff) << 15;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_max_v(void)
|
||||
{
|
||||
return 0x0000ffff;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_max_f(void)
|
||||
{
|
||||
return 0x7fff8000;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_en_enable_f(void)
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_en_disable_f(void)
|
||||
{
|
||||
return 0x0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2014-2015, NVIDIA CORPORATION. All rights reserved.
|
||||
* Copyright (c) 2014-2016, 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,
|
||||
@@ -262,14 +262,34 @@ static inline u32 pbdma_acquire_retry_exp_2_f(void)
|
||||
{
|
||||
return 0x100;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_f(u32 v)
|
||||
{
|
||||
return (v & 0xf) << 11;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_max_v(void)
|
||||
{
|
||||
return 0x0000000f;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_exp_max_f(void)
|
||||
{
|
||||
return 0x7800;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_f(u32 v)
|
||||
{
|
||||
return (v & 0xffff) << 15;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_max_v(void)
|
||||
{
|
||||
return 0x0000ffff;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_man_max_f(void)
|
||||
{
|
||||
return 0x7fff8000;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_en_enable_f(void)
|
||||
{
|
||||
return 0x80000000;
|
||||
}
|
||||
static inline u32 pbdma_acquire_timeout_en_disable_f(void)
|
||||
{
|
||||
return 0x0;
|
||||
|
||||
Reference in New Issue
Block a user