diff --git a/drivers/gpu/nvgpu/common/fifo/tsg.c b/drivers/gpu/nvgpu/common/fifo/tsg.c index 58bbd6177..63f25973d 100644 --- a/drivers/gpu/nvgpu/common/fifo/tsg.c +++ b/drivers/gpu/nvgpu/common/fifo/tsg.c @@ -709,6 +709,28 @@ u32 nvgpu_tsg_get_timeslice(struct nvgpu_tsg *tsg) { return tsg->timeslice_us; } + +int nvgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us) +{ + struct gk20a *g = tsg->g; + + nvgpu_log(g, gpu_dbg_sched, "tsgid=%u timeslice=%u us", + tsg->tsgid, timeslice_us); + + if (timeslice_us < g->tsg_timeslice_min_us || + timeslice_us > g->tsg_dbg_timeslice_max_us) { + return -EINVAL; + } + + tsg->timeslice_us = timeslice_us; + + /* TSG may not be bound yet */ + if (tsg->runlist == NULL) { + return 0; + } + + return g->ops.runlist.reload(g, tsg->runlist, true, true); +} #endif u32 nvgpu_tsg_default_timeslice_us(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c index 86c327493..c403ca2bd 100644 --- a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c +++ b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2015-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -116,3 +116,27 @@ int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, err = err ? err : msg.ret; return err; } + +int vgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us) +{ + struct tegra_vgpu_cmd_msg msg = {0}; + struct tegra_vgpu_tsg_timeslice_params *p = + &msg.params.tsg_timeslice; + int err; + struct gk20a *g = tsg->g; + + nvgpu_log_fn(g, " "); + + msg.cmd = TEGRA_VGPU_CMD_TSG_SET_LONG_TIMESLICE; + msg.handle = vgpu_get_handle(g); + p->tsg_id = tsg->tsgid; + p->timeslice_us = timeslice_us; + err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); + err = err ? err : msg.ret; + WARN_ON(err); + if (!err) { + tsg->timeslice_us = timeslice_us; + } + + return err; +} \ No newline at end of file diff --git a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h index bf805e236..d0bea845d 100644 --- a/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h +++ b/drivers/gpu/nvgpu/common/vgpu/debugger_vgpu.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -37,5 +37,6 @@ int vgpu_exec_regops(struct gk20a *g, u32 *flags); int vgpu_dbg_set_powergate(struct dbg_session_gk20a *dbg_s, bool disable_powergate); +int vgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us); #endif /* NVGPU_DBG_VGPU_H */ diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.c b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.c index 8057b257d..18b6784ab 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.c +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -43,6 +43,11 @@ u32 gk20a_runlist_entry_size(struct gk20a *g) return ram_rl_entry_size_v(); } +u32 gk20a_runlist_max_timeslice(void) +{ + return ((RL_MAX_TIMESLICE_TIMEOUT << RL_MAX_TIMESLICE_SCALE) / 1000) * 1024; +} + void gk20a_runlist_get_tsg_entry(struct nvgpu_tsg *tsg, u32 *runlist, u32 timeslice) { diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.h b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.h index 322c97607..fc31c4a18 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.h +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gk20a.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2011-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,6 +30,7 @@ struct nvgpu_tsg; struct gk20a; u32 gk20a_runlist_entry_size(struct gk20a *g); +u32 gk20a_runlist_max_timeslice(void); void gk20a_runlist_get_tsg_entry(struct nvgpu_tsg *tsg, u32 *runlist, u32 timeslice); void gk20a_runlist_get_ch_entry(struct nvgpu_channel *ch, u32 *runlist); diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b.h b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b.h index d3bb1c96d..881fedaa0 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b.h +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,6 +29,7 @@ struct nvgpu_channel; struct nvgpu_tsg; u32 gv11b_runlist_entry_size(struct gk20a *g); +u32 gv11b_runlist_max_timeslice(void); void gv11b_runlist_get_tsg_entry(struct nvgpu_tsg *tsg, u32 *runlist, u32 timeslice); void gv11b_runlist_get_ch_entry(struct nvgpu_channel *ch, u32 *runlist); diff --git a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b_fusa.c b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b_fusa.c index 2225400ee..1873011f2 100644 --- a/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b_fusa.c +++ b/drivers/gpu/nvgpu/hal/fifo/runlist_ram_gv11b_fusa.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2016-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -37,6 +37,11 @@ u32 gv11b_runlist_entry_size(struct gk20a *g) return ram_rl_entry_size_v(); } +u32 gv11b_runlist_max_timeslice(void) +{ + return ((RL_MAX_TIMESLICE_TIMEOUT << RL_MAX_TIMESLICE_SCALE) / 1000) * 1024; +} + void gv11b_runlist_get_tsg_entry(struct nvgpu_tsg *tsg, u32 *runlist, u32 timeslice) { diff --git a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c index aec424960..8de0801c6 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gm20b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gm20b.c @@ -695,6 +695,7 @@ static const struct gops_runlist gm20b_ops_runlist = { .wait_pending = gk20a_runlist_wait_pending, .write_state = gk20a_runlist_write_state, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gk20a_runlist_max_timeslice, }; static const struct gops_userd gm20b_ops_userd = { @@ -745,6 +746,7 @@ static const struct gops_tsg gm20b_ops_tsg = { #endif #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING .set_timeslice = nvgpu_tsg_set_timeslice, + .set_long_timeslice = nvgpu_tsg_set_long_timeslice, #endif .default_timeslice_us = nvgpu_tsg_default_timeslice_us, }; diff --git a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c index 73ea8823d..9a5796f5c 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gp10b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gp10b.c @@ -780,6 +780,7 @@ static const struct gops_runlist gp10b_ops_runlist = { .wait_pending = gk20a_runlist_wait_pending, .write_state = gk20a_runlist_write_state, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gk20a_runlist_max_timeslice, }; static const struct gops_userd gp10b_ops_userd = { @@ -833,6 +834,7 @@ static const struct gops_tsg gp10b_ops_tsg = { #endif #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING .set_timeslice = nvgpu_tsg_set_timeslice, + .set_long_timeslice = nvgpu_tsg_set_long_timeslice, #endif .default_timeslice_us = nvgpu_tsg_default_timeslice_us, }; diff --git a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c index df00baa6f..bdec0bc9c 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/init/hal_gv11b.c @@ -953,6 +953,7 @@ static const struct gops_runlist gv11b_ops_runlist = { .wait_pending = gk20a_runlist_wait_pending, .write_state = gk20a_runlist_write_state, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gv11b_runlist_max_timeslice, }; static const struct gops_userd gv11b_ops_userd = { @@ -1007,6 +1008,7 @@ static const struct gops_tsg gv11b_ops_tsg = { #endif #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING .set_timeslice = nvgpu_tsg_set_timeslice, + .set_long_timeslice = nvgpu_tsg_set_long_timeslice, #endif .default_timeslice_us = nvgpu_tsg_default_timeslice_us, }; diff --git a/drivers/gpu/nvgpu/hal/init/hal_tu104.c b/drivers/gpu/nvgpu/hal/init/hal_tu104.c index 80917dfd4..94be478cc 100644 --- a/drivers/gpu/nvgpu/hal/init/hal_tu104.c +++ b/drivers/gpu/nvgpu/hal/init/hal_tu104.c @@ -1008,6 +1008,7 @@ static const struct gops_runlist tu104_ops_runlist = { .wait_pending = tu104_runlist_wait_pending, .write_state = gk20a_runlist_write_state, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gv11b_runlist_max_timeslice, }; static const struct gops_userd tu104_ops_userd = { @@ -1062,6 +1063,7 @@ static const struct gops_tsg tu104_ops_tsg = { #endif #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING .set_timeslice = nvgpu_tsg_set_timeslice, + .set_long_timeslice = nvgpu_tsg_set_long_timeslice, #endif .default_timeslice_us = nvgpu_tsg_default_timeslice_us, }; diff --git a/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gp10b.c b/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gp10b.c index 99ab529b2..bba5261e2 100644 --- a/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gp10b.c +++ b/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gp10b.c @@ -556,6 +556,7 @@ static const struct gops_runlist vgpu_gp10b_ops_runlist = { .hw_submit = NULL, .wait_pending = NULL, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gk20a_runlist_max_timeslice, }; static const struct gops_userd vgpu_gp10b_ops_userd = { @@ -605,6 +606,7 @@ static const struct gops_tsg vgpu_gp10b_ops_tsg = { .set_timeslice = vgpu_tsg_set_timeslice, .default_timeslice_us = vgpu_tsg_default_timeslice_us, .set_interleave = vgpu_tsg_set_interleave, + .set_long_timeslice = vgpu_tsg_set_long_timeslice, }; static const struct gops_netlist vgpu_gp10b_ops_netlist = { diff --git a/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gv11b.c b/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gv11b.c index 2c465fa8b..fe53baf31 100644 --- a/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gv11b.c +++ b/drivers/gpu/nvgpu/hal/vgpu/init/vgpu_hal_gv11b.c @@ -659,6 +659,7 @@ static const struct gops_runlist vgpu_gv11b_ops_runlist = { .hw_submit = NULL, .wait_pending = NULL, .init_enginfo = nvgpu_runlist_init_enginfo, + .get_tsg_max_timeslice = gv11b_runlist_max_timeslice, }; static const struct gops_userd vgpu_gv11b_ops_userd = { @@ -708,6 +709,7 @@ static const struct gops_tsg vgpu_gv11b_ops_tsg = { .set_timeslice = vgpu_tsg_set_timeslice, .default_timeslice_us = vgpu_tsg_default_timeslice_us, .set_interleave = vgpu_tsg_set_interleave, + .set_long_timeslice = vgpu_tsg_set_long_timeslice, }; static const struct gops_usermode vgpu_gv11b_ops_usermode = { diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 669db5588..6483dff50 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h @@ -488,6 +488,7 @@ struct gk20a { u32 tsg_timeslice_high_priority_us; u32 tsg_timeslice_min_us; u32 tsg_timeslice_max_us; + u32 tsg_dbg_timeslice_max_us; bool runlist_interleave; /** @endcond */ diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h b/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h index f9741070f..53dc9fe85 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/runlist.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2021, NVIDIA CORPORATION. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -88,6 +88,7 @@ struct gops_runlist { int (*reschedule_preempt_next_locked)(struct nvgpu_channel *ch, bool wait_preempt); void (*init_enginfo)(struct gk20a *g, struct nvgpu_fifo *f); + u32 (*get_tsg_max_timeslice)(void); #if defined(CONFIG_NVGPU_HAL_NON_FUSA) && defined(CONFIG_NVGPU_NEXT) #include "include/nvgpu/nvgpu_next_gops_runlist.h" #endif diff --git a/drivers/gpu/nvgpu/include/nvgpu/gops/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/gops/tsg.h index 0f9bace4d..aff7a4eb2 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gops/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gops/tsg.h @@ -76,6 +76,7 @@ struct gops_tsg { struct nvgpu_channel *ch, struct nvgpu_channel_hw_state *state); int (*set_timeslice)(struct nvgpu_tsg *tsg, u32 timeslice_us); + int (*set_long_timeslice)(struct nvgpu_tsg *tsg, u32 timeslice_us); u32 (*default_timeslice_us)(struct gk20a *g); int (*set_interleave)(struct nvgpu_tsg *tsg, u32 new_level); diff --git a/drivers/gpu/nvgpu/include/nvgpu/tsg.h b/drivers/gpu/nvgpu/include/nvgpu/tsg.h index b38396f69..fcc00d13d 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/tsg.h +++ b/drivers/gpu/nvgpu/include/nvgpu/tsg.h @@ -43,6 +43,7 @@ #define NVGPU_TSG_TIMESLICE_HIGH_PRIORITY_US 5200U #define NVGPU_TSG_TIMESLICE_MIN_US 1000U #define NVGPU_TSG_TIMESLICE_MAX_US 50000U +#define NVGPU_TSG_DBG_TIMESLICE_MAX_US_DEFAULT 4000000U /** * Default TSG timeslice value in microseconds. Currently it is 1024 us. */ @@ -532,6 +533,7 @@ bool nvgpu_tsg_check_ctxsw_timeout(struct nvgpu_tsg *tsg, #ifdef CONFIG_NVGPU_CHANNEL_TSG_SCHEDULING int nvgpu_tsg_set_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us); u32 nvgpu_tsg_get_timeslice(struct nvgpu_tsg *tsg); +int nvgpu_tsg_set_long_timeslice(struct nvgpu_tsg *tsg, u32 timeslice_us); int nvgpu_tsg_set_priority(struct gk20a *g, struct nvgpu_tsg *tsg, u32 priority); int nvgpu_tsg_set_interleave(struct nvgpu_tsg *tsg, u32 level); diff --git a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h index 3680e1dcb..9ec5a8b27 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vgpu/tegra_vgpu.h @@ -119,6 +119,7 @@ enum { TEGRA_VGPU_CMD_FB_SET_MMU_DEBUG_MODE = 88, TEGRA_VGPU_CMD_GR_SET_MMU_DEBUG_MODE = 89, TEGRA_VGPU_CMD_PERFBUF_INST_BLOCK_MGT = 90, + TEGRA_VGPU_CMD_TSG_SET_LONG_TIMESLICE = 91, }; struct tegra_vgpu_connect_params { diff --git a/drivers/gpu/nvgpu/os/linux/debug.c b/drivers/gpu/nvgpu/os/linux/debug.c index e4d99bc49..da984a2ab 100644 --- a/drivers/gpu/nvgpu/os/linux/debug.c +++ b/drivers/gpu/nvgpu/os/linux/debug.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017-2020 NVIDIA Corporation. All rights reserved. + * Copyright (C) 2017-2021 NVIDIA Corporation. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -338,6 +339,49 @@ static const struct file_operations timeouts_enabled_fops = { .write = timeouts_enabled_write, }; +static ssize_t dbg_tsg_timeslice_max_read(struct file *file, + char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[10]; + struct gk20a *g = file->private_data; + unsigned int val = g->tsg_dbg_timeslice_max_us; + + memcpy(buf, (char*)&val, sizeof(unsigned int)); + return simple_read_from_buffer(user_buf, count, ppos, buf, 2); +} + +static ssize_t dbg_tsg_timeslice_max_write(struct file *file, + const char __user *user_buf, size_t count, loff_t *ppos) +{ + char buf[10]; + int buf_size; + unsigned int val = 0; + struct gk20a *g = file->private_data; + unsigned int max_hw_timeslice_us = g->ops.runlist.get_tsg_max_timeslice(); + + (void) memset(buf, 0, sizeof(buf)); + buf_size = min(count, (sizeof(buf)-1)); + if (copy_from_user(buf, user_buf, buf_size)) + return -EFAULT; + + if (kstrtouint(buf, 10, &val) < 0) + return -EINVAL; + + if (val < NVGPU_TSG_TIMESLICE_MIN_US || + val > max_hw_timeslice_us) + return -EINVAL; + + g->tsg_dbg_timeslice_max_us = val; + + return count; +} + +static const struct file_operations dbg_tsg_timeslice_max_fops = { + .open = simple_open, + .read = dbg_tsg_timeslice_max_read, + .write = dbg_tsg_timeslice_max_write, +}; + void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) { struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); @@ -405,6 +449,12 @@ void gk20a_debug_init(struct gk20a *g, const char *debugfs_symlink) debugfs_create_u32("tsg_timeslice_high_priority_us", S_IRUGO|S_IWUSR, l->debugfs, &g->tsg_timeslice_high_priority_us); + l->debugfs_dbg_tsg_timeslice_max_us = + debugfs_create_file("max_dbg_tsg_timeslice_us", + S_IRUGO|S_IWUSR, + l->debugfs, g, + &dbg_tsg_timeslice_max_fops); + l->debugfs_runlist_interleave = debugfs_create_bool("runlist_interleave", S_IRUGO|S_IWUSR, diff --git a/drivers/gpu/nvgpu/os/linux/driver_common.c b/drivers/gpu/nvgpu/os/linux/driver_common.c index a41a200c2..5e44ad529 100644 --- a/drivers/gpu/nvgpu/os/linux/driver_common.c +++ b/drivers/gpu/nvgpu/os/linux/driver_common.c @@ -151,6 +151,7 @@ static void nvgpu_init_timeslice(struct gk20a *g) g->tsg_timeslice_min_us = NVGPU_TSG_TIMESLICE_MIN_US; g->tsg_timeslice_max_us = NVGPU_TSG_TIMESLICE_MAX_US; + g->tsg_dbg_timeslice_max_us = NVGPU_TSG_DBG_TIMESLICE_MAX_US_DEFAULT; } static void nvgpu_init_pm_vars(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index 335af2f7c..16770d021 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -457,6 +457,7 @@ static long gk20a_ctrl_ioctl_gpu_characteristics( gpu.ctxsw_ioctl_nr_last = NVGPU_CTXSW_IOCTL_LAST; gpu.prof_ioctl_nr_last = NVGPU_PROFILER_IOCTL_LAST; gpu.gpu_va_bit_count = 40; + gpu.max_dbg_tsg_timeslice = g->tsg_dbg_timeslice_max_us; strlcpy(gpu.chipname, g->name, sizeof(gpu.chipname)); gpu.max_fbps_count = nvgpu_fbp_get_max_fbps_count(g->fbp); diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index b7b0969a2..f3ede75f7 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -1,7 +1,7 @@ /* * Tegra GK20A GPU Debugger/Profiler Driver * - * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2021, 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, @@ -574,6 +574,68 @@ static int dbg_unbind_all_channels_gk20a(struct dbg_session_gk20a *dbg_s) return 0; } +static int nvgpu_dbg_gpu_ioctl_tsg_set_timeslice(struct dbg_session_gk20a *dbg_s, + struct nvgpu_timeslice_args *arg) +{ + struct nvgpu_tsg *tsg; + struct nvgpu_channel *ch; + struct gk20a *g = dbg_s->g; + struct nvgpu_sched_ctrl *sched = &g->sched_ctrl; + int err; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + tsg = nvgpu_tsg_from_ch(ch); + if (tsg == NULL) { + nvgpu_err(g, "no valid tsg from ch"); + return -EINVAL; + } + + nvgpu_log(g, gpu_dbg_fn | gpu_dbg_sched, "tsgid=%u timeslice=%u", + tsg->tsgid, arg->timeslice_us); + + nvgpu_mutex_acquire(&sched->control_lock); + if (sched->control_locked) { + err = -EPERM; + goto done; + } + err = gk20a_busy(g); + if (err) { + nvgpu_err(g, "failed to power on gpu"); + goto done; + } + err = g->ops.tsg.set_long_timeslice(tsg, arg->timeslice_us); + gk20a_idle(g); +done: + nvgpu_mutex_release(&sched->control_lock); + return err; +} + +static int nvgpu_dbg_gpu_ioctl_tsg_get_timeslice(struct dbg_session_gk20a *dbg_s, + struct nvgpu_timeslice_args *arg) +{ + struct nvgpu_tsg *tsg; + struct nvgpu_channel *ch; + struct gk20a *g = dbg_s->g; + + ch = nvgpu_dbg_gpu_get_session_channel(dbg_s); + if (ch == NULL) { + return -EINVAL; + } + + tsg = nvgpu_tsg_from_ch(ch); + if (tsg == NULL) { + nvgpu_err(g, "no valid tsg from ch"); + return -EINVAL; + } + + arg->timeslice_us = nvgpu_tsg_get_timeslice(tsg); + return 0; +} + #ifdef CONFIG_NVGPU_DEBUGGER /* * Convert common regops op values of the form of NVGPU_DBG_REG_OP_* @@ -2377,6 +2439,16 @@ long gk20a_dbg_gpu_dev_ioctl(struct file *filp, unsigned int cmd, (struct nvgpu_dbg_gpu_set_ctx_mmu_debug_mode_args *)buf); break; + case NVGPU_DBG_GPU_IOCTL_TSG_SET_TIMESLICE: + err = nvgpu_dbg_gpu_ioctl_tsg_set_timeslice(dbg_s, + (struct nvgpu_timeslice_args *)buf); + break; + + case NVGPU_DBG_GPU_IOCTL_TSG_GET_TIMESLICE: + err = nvgpu_dbg_gpu_ioctl_tsg_get_timeslice(dbg_s, + (struct nvgpu_timeslice_args *)buf); + break; + default: nvgpu_err(g, "unrecognized dbg gpu ioctl cmd: 0x%x", diff --git a/drivers/gpu/nvgpu/os/linux/os_linux.h b/drivers/gpu/nvgpu/os/linux/os_linux.h index 7b534662e..439f907ea 100644 --- a/drivers/gpu/nvgpu/os/linux/os_linux.h +++ b/drivers/gpu/nvgpu/os/linux/os_linux.h @@ -119,6 +119,7 @@ struct nvgpu_os_linux { struct dentry *debugfs_ltc_enabled; struct dentry *debugfs_timeouts_enabled; struct dentry *debugfs_disable_bigpage; + struct dentry *debugfs_dbg_tsg_timeslice_max_us; struct dentry *debugfs_runlist_interleave; struct dentry *debugfs_allocators; diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c index 9bb41aa09..5665eb012 100644 --- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c +++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c @@ -1,7 +1,7 @@ /* * Virtualized GPU for Linux * - * Copyright (c) 2018-2020, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2018-2021, 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, @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -454,6 +455,7 @@ int vgpu_probe(struct platform_device *pdev) gk20a->poll_timeout_default = NVGPU_DEFAULT_POLL_TIMEOUT_MS; gk20a->timeouts_disabled_by_user = false; nvgpu_atomic_set(&gk20a->timeouts_disabled_refcount, 0); + gk20a->tsg_dbg_timeslice_max_us = NVGPU_TSG_DBG_TIMESLICE_MAX_US_DEFAULT; vgpu_create_sysfs(dev); diff --git a/include/uapi/linux/nvgpu-ctrl.h b/include/uapi/linux/nvgpu-ctrl.h index d208b9416..1d4506ce4 100644 --- a/include/uapi/linux/nvgpu-ctrl.h +++ b/include/uapi/linux/nvgpu-ctrl.h @@ -322,6 +322,9 @@ struct nvgpu_gpu_characteristics { /** Max gpfifo entries allowed by nvgpu-rm. */ __u32 max_gpfifo_entries; + __u32 max_dbg_tsg_timeslice; + __u32 reserved5; + /* Notes: - This struct can be safely appended with new fields. However, always keep the structure size multiple of 8 and make sure that the binary diff --git a/include/uapi/linux/nvgpu.h b/include/uapi/linux/nvgpu.h index 114d96ca9..26ab89f28 100644 --- a/include/uapi/linux/nvgpu.h +++ b/include/uapi/linux/nvgpu.h @@ -502,8 +502,16 @@ struct nvgpu_dbg_gpu_get_gr_context_args { _IOW(NVGPU_DBG_GPU_IOCTL_MAGIC, 28, \ struct nvgpu_dbg_gpu_get_gr_context_args) +#define NVGPU_DBG_GPU_IOCTL_TSG_SET_TIMESLICE \ + _IOW(NVGPU_DBG_GPU_IOCTL_MAGIC, 29, \ + struct nvgpu_timeslice_args) + +#define NVGPU_DBG_GPU_IOCTL_TSG_GET_TIMESLICE \ + _IOR(NVGPU_DBG_GPU_IOCTL_MAGIC, 30, \ + struct nvgpu_timeslice_args) + #define NVGPU_DBG_GPU_IOCTL_LAST \ - _IOC_NR(NVGPU_DBG_GPU_IOCTL_GET_GR_CONTEXT) + _IOC_NR(NVGPU_DBG_GPU_IOCTL_TSG_GET_TIMESLICE) #define NVGPU_DBG_GPU_IOCTL_MAX_ARG_SIZE \ sizeof(struct nvgpu_dbg_gpu_access_fb_memory_args)