gpu: nvgpu: add ioctls to get current timeslice

Add the following ioctls
- NVGPU_CHANNEL_IOCTL_GET_TIMESLICE for channel timeslice in us
- NVGPU_TSG_IOCTL_GET_TIMESLICE for TSG timeslice in us

If timeslice has not been set explicitly, ioctl returns the
default timeslice that will be used when programming the runlist
entry.

Bug 1883271

Change-Id: Ib18fdd836323b1a2d4efceb1e27d07713bd6fca5
Signed-off-by: Thomas Fleury <tfleury@nvidia.com>
Reviewed-on: http://git-master/r/1469040
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Thomas Fleury
2017-04-19 16:47:13 -07:00
committed by mobile promotions
parent a823c72219
commit b03afb6d5c
13 changed files with 77 additions and 6 deletions

View File

@@ -1125,6 +1125,10 @@ long gk20a_channel_ioctl(struct file *filp,
gk20a_channel_trace_sched_param( gk20a_channel_trace_sched_param(
trace_gk20a_channel_set_timeslice, ch); trace_gk20a_channel_set_timeslice, ch);
break; break;
case NVGPU_IOCTL_CHANNEL_GET_TIMESLICE:
((struct nvgpu_timeslice_args *)buf)->timeslice_us =
gk20a_channel_get_timeslice(ch);
break;
case NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE: case NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE:
if (ch->g->ops.gr.set_preemption_mode) { if (ch->g->ops.gr.set_preemption_mode) {
err = gk20a_busy(ch->g); err = gk20a_busy(ch->g);

View File

@@ -340,6 +340,12 @@ done:
return err; return err;
} }
static int gk20a_tsg_ioctl_get_timeslice(struct gk20a *g,
struct tsg_gk20a *tsg, struct nvgpu_timeslice_args *arg)
{
arg->timeslice_us = gk20a_tsg_get_timeslice(tsg);
return 0;
}
long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
@@ -455,6 +461,12 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd,
(struct nvgpu_timeslice_args *)buf); (struct nvgpu_timeslice_args *)buf);
break; break;
} }
case NVGPU_IOCTL_TSG_GET_TIMESLICE:
{
err = gk20a_tsg_ioctl_get_timeslice(g, tsg,
(struct nvgpu_timeslice_args *)buf);
break;
}
default: default:
nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x", nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x",

View File

@@ -146,6 +146,16 @@ int channel_gk20a_commit_va(struct channel_gk20a *c)
return 0; return 0;
} }
u32 gk20a_channel_get_timeslice(struct channel_gk20a *ch)
{
struct gk20a *g = ch->g;
if (!ch->timeslice_us)
return g->ops.fifo.default_timeslice_us(g);
return ch->timeslice_us;
}
int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
int timeslice_period, int timeslice_period,
int *__timeslice_timeout, int *__timeslice_scale) int *__timeslice_timeout, int *__timeslice_scale)

View File

@@ -388,6 +388,7 @@ void channel_gk20a_joblist_lock(struct channel_gk20a *c);
void channel_gk20a_joblist_unlock(struct channel_gk20a *c); void channel_gk20a_joblist_unlock(struct channel_gk20a *c);
bool channel_gk20a_joblist_is_empty(struct channel_gk20a *c); bool channel_gk20a_joblist_is_empty(struct channel_gk20a *c);
u32 gk20a_channel_get_timeslice(struct channel_gk20a *ch);
int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g, int gk20a_channel_get_timescale_from_timeslice(struct gk20a *g,
int timeslice_period, int timeslice_period,
int *__timeslice_timeout, int *__timeslice_scale); int *__timeslice_timeout, int *__timeslice_scale);

View File

@@ -2920,14 +2920,24 @@ void gk20a_get_tsg_runlist_entry(struct tsg_gk20a *tsg, u32 *runlist)
ram_rl_entry_timeslice_timeout_f(tsg->timeslice_timeout); ram_rl_entry_timeslice_timeout_f(tsg->timeslice_timeout);
else else
runlist_entry_0 |= runlist_entry_0 |=
ram_rl_entry_timeslice_scale_3_f() | ram_rl_entry_timeslice_scale_f(
ram_rl_entry_timeslice_timeout_128_f(); NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE) |
ram_rl_entry_timeslice_timeout_f(
NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT);
runlist[0] = runlist_entry_0; runlist[0] = runlist_entry_0;
runlist[1] = 0; runlist[1] = 0;
} }
u32 gk20a_fifo_default_timeslice_us(struct gk20a *g)
{
return (((u64)(NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT <<
NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE) *
(u64)g->ptimer_src_freq) /
(u64)PTIMER_REF_FREQ_HZ);
}
void gk20a_get_ch_runlist_entry(struct channel_gk20a *ch, u32 *runlist) void gk20a_get_ch_runlist_entry(struct channel_gk20a *ch, u32 *runlist)
{ {
runlist[0] = ram_rl_entry_chid_f(ch->hw_chid); runlist[0] = ram_rl_entry_chid_f(ch->hw_chid);

View File

@@ -47,6 +47,9 @@
#define RC_TYPE_PBDMA_FAULT 2 #define RC_TYPE_PBDMA_FAULT 2
#define RC_TYPE_NO_RC 0xff #define RC_TYPE_NO_RC 0xff
#define NVGPU_FIFO_DEFAULT_TIMESLICE_TIMEOUT 128UL
#define NVGPU_FIFO_DEFAULT_TIMESLICE_SCALE 3UL
/* /*
* Number of entries in the kickoff latency buffer, used to calculate * Number of entries in the kickoff latency buffer, used to calculate
* the profiling and histogram. This number is calculated to be statistically * the profiling and histogram. This number is calculated to be statistically
@@ -399,4 +402,6 @@ void gk20a_fifo_reset_pbdma_method(struct gk20a *g, int pbdma_id,
int pbdma_method_index); int pbdma_method_index);
unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id, unsigned int gk20a_fifo_handle_pbdma_intr_0(struct gk20a *g, u32 pbdma_id,
u32 pbdma_intr_0, u32 *handled, u32 *error_notifier); u32 pbdma_intr_0, u32 *handled, u32 *error_notifier);
u32 gk20a_fifo_default_timeslice_us(struct gk20a *g);
#endif /*__GR_GK20A_H__*/ #endif /*__GR_GK20A_H__*/

View File

@@ -445,6 +445,7 @@ struct gpu_ops {
int (*channel_set_timeslice)(struct channel_gk20a *ch, int (*channel_set_timeslice)(struct channel_gk20a *ch,
u32 timeslice); u32 timeslice);
int (*tsg_set_timeslice)(struct tsg_gk20a *tsg, u32 timeslice); int (*tsg_set_timeslice)(struct tsg_gk20a *tsg, u32 timeslice);
u32 (*default_timeslice_us)(struct gk20a *);
int (*force_reset_ch)(struct channel_gk20a *ch, int (*force_reset_ch)(struct channel_gk20a *ch,
u32 err_code, bool verbose); u32 err_code, bool verbose);
int (*engine_enum_from_type)(struct gk20a *g, u32 engine_type, int (*engine_enum_from_type)(struct gk20a *g, u32 engine_type,

View File

@@ -211,6 +211,16 @@ int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice)
return g->ops.fifo.tsg_set_timeslice(tsg, timeslice); return g->ops.fifo.tsg_set_timeslice(tsg, timeslice);
} }
u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg)
{
struct gk20a *g = tsg->g;
if (!tsg->timeslice_us)
return g->ops.fifo.default_timeslice_us(g);
return tsg->timeslice_us;
}
static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg) static void release_used_tsg(struct fifo_gk20a *f, struct tsg_gk20a *tsg)
{ {
nvgpu_mutex_acquire(&f->tsg_inuse_mutex); nvgpu_mutex_acquire(&f->tsg_inuse_mutex);

View File

@@ -70,6 +70,7 @@ void gk20a_tsg_event_id_post_event(struct tsg_gk20a *tsg,
int event_id); int event_id);
int gk20a_tsg_set_runlist_interleave(struct tsg_gk20a *tsg, u32 level); int gk20a_tsg_set_runlist_interleave(struct tsg_gk20a *tsg, u32 level);
int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice); int gk20a_tsg_set_timeslice(struct tsg_gk20a *tsg, u32 timeslice);
u32 gk20a_tsg_get_timeslice(struct tsg_gk20a *tsg);
int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg, int gk20a_tsg_set_priority(struct gk20a *g, struct tsg_gk20a *tsg,
u32 priority); u32 priority);

View File

@@ -195,6 +195,7 @@ void gm20b_init_fifo(struct gpu_ops *gops)
gops->fifo.setup_ramfc = gk20a_fifo_setup_ramfc; gops->fifo.setup_ramfc = gk20a_fifo_setup_ramfc;
gops->fifo.channel_set_priority = gk20a_fifo_set_priority; gops->fifo.channel_set_priority = gk20a_fifo_set_priority;
gops->fifo.channel_set_timeslice = gk20a_fifo_set_timeslice; gops->fifo.channel_set_timeslice = gk20a_fifo_set_timeslice;
gops->fifo.default_timeslice_us = gk20a_fifo_default_timeslice_us;
gops->fifo.setup_userd = gk20a_fifo_setup_userd; gops->fifo.setup_userd = gk20a_fifo_setup_userd;
gops->fifo.userd_gp_get = gk20a_fifo_userd_gp_get; gops->fifo.userd_gp_get = gk20a_fifo_userd_gp_get;
gops->fifo.userd_gp_put = gk20a_fifo_userd_gp_put; gops->fifo.userd_gp_put = gk20a_fifo_userd_gp_put;

View File

@@ -655,8 +655,11 @@ static int vgpu_channel_set_timeslice(struct channel_gk20a *ch, u32 timeslice)
p->handle = ch->virt_ctx; p->handle = ch->virt_ctx;
p->timeslice_us = timeslice; p->timeslice_us = timeslice;
err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg)); err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
WARN_ON(err || msg.ret); err = err ? err : msg.ret;
return err ? err : msg.ret; WARN_ON(err);
if (!err)
ch->timeslice_us = p->timeslice_us;
return err;
} }
static int vgpu_fifo_force_reset_ch(struct channel_gk20a *ch, static int vgpu_fifo_force_reset_ch(struct channel_gk20a *ch,
@@ -776,6 +779,13 @@ int vgpu_fifo_nonstall_isr(struct gk20a *g,
return 0; return 0;
} }
u32 vgpu_fifo_default_timeslice_us(struct gk20a *g)
{
struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
return priv->constants.default_timeslice_us;
}
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;
@@ -794,4 +804,5 @@ void vgpu_init_fifo_ops(struct gpu_ops *gops)
gops->fifo.channel_set_timeslice = vgpu_channel_set_timeslice; gops->fifo.channel_set_timeslice = vgpu_channel_set_timeslice;
gops->fifo.force_reset_ch = vgpu_fifo_force_reset_ch; gops->fifo.force_reset_ch = vgpu_fifo_force_reset_ch;
gops->fifo.init_engine_info = vgpu_fifo_init_engine_info; gops->fifo.init_engine_info = vgpu_fifo_init_engine_info;
gops->fifo.default_timeslice_us = vgpu_fifo_default_timeslice_us;
} }

View File

@@ -457,6 +457,7 @@ struct tegra_vgpu_constants_params {
u16 gpc_tpc_mask[TEGRA_VGPU_MAX_GPC_COUNT]; u16 gpc_tpc_mask[TEGRA_VGPU_MAX_GPC_COUNT];
u32 hwpm_ctx_size; u32 hwpm_ctx_size;
u8 force_preempt_mode; u8 force_preempt_mode;
u32 default_timeslice_us;
}; };
struct tegra_vgpu_channel_cyclestats_snapshot_params { struct tegra_vgpu_channel_cyclestats_snapshot_params {

View File

@@ -968,11 +968,13 @@ struct nvgpu_gpu_set_event_filter_args {
_IOW(NVGPU_TSG_IOCTL_MAGIC, 8, struct nvgpu_runlist_interleave_args) _IOW(NVGPU_TSG_IOCTL_MAGIC, 8, struct nvgpu_runlist_interleave_args)
#define NVGPU_IOCTL_TSG_SET_TIMESLICE \ #define NVGPU_IOCTL_TSG_SET_TIMESLICE \
_IOW(NVGPU_TSG_IOCTL_MAGIC, 9, struct nvgpu_timeslice_args) _IOW(NVGPU_TSG_IOCTL_MAGIC, 9, struct nvgpu_timeslice_args)
#define NVGPU_IOCTL_TSG_GET_TIMESLICE \
_IOR(NVGPU_TSG_IOCTL_MAGIC, 10, struct nvgpu_timeslice_args)
#define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \ #define NVGPU_TSG_IOCTL_MAX_ARG_SIZE \
sizeof(struct nvgpu_event_id_ctrl_args) sizeof(struct nvgpu_event_id_ctrl_args)
#define NVGPU_TSG_IOCTL_LAST \ #define NVGPU_TSG_IOCTL_LAST \
_IOC_NR(NVGPU_IOCTL_TSG_SET_TIMESLICE) _IOC_NR(NVGPU_IOCTL_TSG_GET_TIMESLICE)
/* /*
@@ -1632,9 +1634,11 @@ struct nvgpu_boosted_ctx_args {
_IOW(NVGPU_IOCTL_MAGIC, 123, struct nvgpu_alloc_gpfifo_ex_args) _IOW(NVGPU_IOCTL_MAGIC, 123, struct nvgpu_alloc_gpfifo_ex_args)
#define NVGPU_IOCTL_CHANNEL_SET_BOOSTED_CTX \ #define NVGPU_IOCTL_CHANNEL_SET_BOOSTED_CTX \
_IOW(NVGPU_IOCTL_MAGIC, 124, struct nvgpu_boosted_ctx_args) _IOW(NVGPU_IOCTL_MAGIC, 124, struct nvgpu_boosted_ctx_args)
#define NVGPU_IOCTL_CHANNEL_GET_TIMESLICE \
_IOW(NVGPU_IOCTL_MAGIC, 125, struct nvgpu_timeslice_args)
#define NVGPU_IOCTL_CHANNEL_LAST \ #define NVGPU_IOCTL_CHANNEL_LAST \
_IOC_NR(NVGPU_IOCTL_CHANNEL_SET_BOOSTED_CTX) _IOC_NR(NVGPU_IOCTL_CHANNEL_GET_TIMESLICE)
#define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_alloc_gpfifo_ex_args) #define NVGPU_IOCTL_CHANNEL_MAX_ARG_SIZE sizeof(struct nvgpu_alloc_gpfifo_ex_args)
/* /*