diff options
author | Deepak Nibade <dnibade@nvidia.com> | 2016-04-19 07:27:49 -0400 |
---|---|---|
committer | Terje Bergstrom <tbergstrom@nvidia.com> | 2016-05-09 16:16:29 -0400 |
commit | d868b654419cfa096f563c9281a2a5cc067c23db (patch) | |
tree | a11fc30ab435c6e2a4c54b97455d3f5c177ad507 /drivers/gpu/nvgpu | |
parent | f14152c081d94710dbde843b8dcd9b3981afb831 (diff) |
gpu: nvgpu: separate IOCTL to set preemption mode
Add separate IOCTL NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE
to allow setting preemption modes from UMD
Define preemption modes in nvgpu.h and use them everywhere
Remove mode definitions from mm_gk20a.h
Also, we support setting only one preemption mode in a channel
But it is possible to have multiple preemption modes (one from
graphics and one from compute) set simultaneously
Hence, update struct gr_ctx_desc to include two separate
preemption modes (graphics_preempt_mode and compute_preempt_mode)
API NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE also supports
setting two separate preemption modes i.e. one for graphics
and one for compute
Make necessary changes in code to support two preemption
modes
Bug 1646259
Change-Id: Ia1dea19e609ba8cc0de2f39ab6c0c4cd6b0a752c
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/1131805
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/channel_gk20a.c | 17 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | 8 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.h | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gr_gk20a.h | 21 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/gr_gm20b.c | 4 |
6 files changed, 45 insertions, 17 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c index 189ec330..990972e4 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c | |||
@@ -3208,6 +3208,23 @@ long gk20a_channel_ioctl(struct file *filp, | |||
3208 | 3208 | ||
3209 | trace_gk20a_channel_set_timeslice(GK20A_TP_ARGS_SCHED(ch)); | 3209 | trace_gk20a_channel_set_timeslice(GK20A_TP_ARGS_SCHED(ch)); |
3210 | break; | 3210 | break; |
3211 | case NVGPU_IOCTL_CHANNEL_SET_PREEMPTION_MODE: | ||
3212 | if (ch->g->ops.gr.set_preemption_mode) { | ||
3213 | err = gk20a_busy(dev); | ||
3214 | if (err) { | ||
3215 | dev_err(dev, | ||
3216 | "%s: failed to host gk20a for ioctl cmd: 0x%x", | ||
3217 | __func__, cmd); | ||
3218 | break; | ||
3219 | } | ||
3220 | err = ch->g->ops.gr.set_preemption_mode(ch, | ||
3221 | ((struct nvgpu_preemption_mode_args *)buf)->graphics_preempt_mode, | ||
3222 | ((struct nvgpu_preemption_mode_args *)buf)->compute_preempt_mode); | ||
3223 | gk20a_idle(dev); | ||
3224 | } else { | ||
3225 | err = -EINVAL; | ||
3226 | } | ||
3227 | break; | ||
3211 | default: | 3228 | default: |
3212 | dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd); | 3229 | dev_dbg(dev, "unrecognized ioctl cmd: 0x%x", cmd); |
3213 | err = -ENOTTY; | 3230 | err = -ENOTTY; |
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c index eccea4d4..dc3debf2 100644 --- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c | |||
@@ -2599,7 +2599,7 @@ static int gk20a_fifo_sched_debugfs_seq_show( | |||
2599 | runlist = &f->runlist_info[runlist_id]; | 2599 | runlist = &f->runlist_info[runlist_id]; |
2600 | 2600 | ||
2601 | if (ch == f->channel) { | 2601 | if (ch == f->channel) { |
2602 | seq_puts(s, "chid tsgid pid timeslice timeout interleave preempt\n"); | 2602 | seq_puts(s, "chid tsgid pid timeslice timeout interleave graphics_preempt compute_preempt\n"); |
2603 | seq_puts(s, " (usecs) (msecs)\n"); | 2603 | seq_puts(s, " (usecs) (msecs)\n"); |
2604 | ret = 0; | 2604 | ret = 0; |
2605 | } | 2605 | } |
@@ -2611,15 +2611,15 @@ static int gk20a_fifo_sched_debugfs_seq_show( | |||
2611 | if (gk20a_is_channel_marked_as_tsg(ch)) | 2611 | if (gk20a_is_channel_marked_as_tsg(ch)) |
2612 | tsg = &f->tsg[ch->tsgid]; | 2612 | tsg = &f->tsg[ch->tsgid]; |
2613 | 2613 | ||
2614 | seq_printf(s, "%-8d %-8d %-8d %-9d %-8d %-10d %-8d\n", | 2614 | seq_printf(s, "%-8d %-8d %-8d %-9d %-8d %-10d %-8d %-8d\n", |
2615 | ch->hw_chid, | 2615 | ch->hw_chid, |
2616 | ch->tsgid, | 2616 | ch->tsgid, |
2617 | ch->pid, | 2617 | ch->pid, |
2618 | tsg ? tsg->timeslice_us : ch->timeslice_us, | 2618 | tsg ? tsg->timeslice_us : ch->timeslice_us, |
2619 | ch->timeout_ms_max, | 2619 | ch->timeout_ms_max, |
2620 | ch->interleave_level, | 2620 | ch->interleave_level, |
2621 | ch->ch_ctx.gr_ctx ? | 2621 | ch->ch_ctx.gr_ctx ? ch->ch_ctx.gr_ctx->graphics_preempt_mode : -1, |
2622 | ch->ch_ctx.gr_ctx->preempt_mode : -1); | 2622 | ch->ch_ctx.gr_ctx ? ch->ch_ctx.gr_ctx->compute_preempt_mode : -1); |
2623 | gk20a_channel_put(ch); | 2623 | gk20a_channel_put(ch); |
2624 | } | 2624 | } |
2625 | return 0; | 2625 | return 0; |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index ebc18d5d..64e410db 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h | |||
@@ -254,6 +254,9 @@ struct gpu_ops { | |||
254 | int (*suspend_contexts)(struct gk20a *g, | 254 | int (*suspend_contexts)(struct gk20a *g, |
255 | struct dbg_session_gk20a *dbg_s, | 255 | struct dbg_session_gk20a *dbg_s, |
256 | int *ctx_resident_ch_fd); | 256 | int *ctx_resident_ch_fd); |
257 | int (*set_preemption_mode)(struct channel_gk20a *ch, | ||
258 | u32 graphics_preempt_mode, | ||
259 | u32 compute_preempt_mode); | ||
257 | } gr; | 260 | } gr; |
258 | const char *name; | 261 | const char *name; |
259 | struct { | 262 | struct { |
@@ -1098,7 +1101,9 @@ static inline struct tsg_gk20a *tsg_gk20a_from_ch(struct channel_gk20a *ch) | |||
1098 | tsg_gk20a_from_ch(ch)->timeslice_us : ch->timeslice_us, \ | 1101 | tsg_gk20a_from_ch(ch)->timeslice_us : ch->timeslice_us, \ |
1099 | ch->timeout_ms_max, \ | 1102 | ch->timeout_ms_max, \ |
1100 | gk20a_fifo_interleave_level_name(ch->interleave_level), \ | 1103 | gk20a_fifo_interleave_level_name(ch->interleave_level), \ |
1101 | gr_gk20a_preempt_mode_name(ch->ch_ctx.gr_ctx ? \ | 1104 | gr_gk20a_graphics_preempt_mode_name(ch->ch_ctx.gr_ctx ? \ |
1102 | ch->ch_ctx.gr_ctx->preempt_mode : 0) | 1105 | ch->ch_ctx.gr_ctx->graphics_preempt_mode : 0), \ |
1106 | gr_gk20a_compute_preempt_mode_name(ch->ch_ctx.gr_ctx ? \ | ||
1107 | ch->ch_ctx.gr_ctx->compute_preempt_mode : 0) | ||
1103 | 1108 | ||
1104 | #endif /* GK20A_H */ | 1109 | #endif /* GK20A_H */ |
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h index 24123eea..10997c17 100644 --- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.h | |||
@@ -628,18 +628,23 @@ int gr_gk20a_resume_contexts(struct gk20a *g, | |||
628 | struct dbg_session_gk20a *dbg_s, | 628 | struct dbg_session_gk20a *dbg_s, |
629 | int *ctx_resident_ch_fd); | 629 | int *ctx_resident_ch_fd); |
630 | 630 | ||
631 | #define NVGPU_GR_PREEMPTION_MODE_WFI 0 | 631 | static inline const char *gr_gk20a_graphics_preempt_mode_name(u32 graphics_preempt_mode) |
632 | #define NVGPU_GR_PREEMPTION_MODE_CTA 2 | ||
633 | |||
634 | static inline const char *gr_gk20a_preempt_mode_name(u32 preempt_mode) | ||
635 | { | 632 | { |
636 | switch (preempt_mode) { | 633 | switch (graphics_preempt_mode) { |
637 | case NVGPU_GR_PREEMPTION_MODE_WFI: | 634 | case NVGPU_GRAPHICS_PREEMPTION_MODE_WFI: |
638 | return "WFI"; | 635 | return "WFI"; |
636 | default: | ||
637 | return "?"; | ||
638 | } | ||
639 | } | ||
639 | 640 | ||
640 | case NVGPU_GR_PREEMPTION_MODE_CTA: | 641 | static inline const char *gr_gk20a_compute_preempt_mode_name(u32 compute_preempt_mode) |
642 | { | ||
643 | switch (compute_preempt_mode) { | ||
644 | case NVGPU_COMPUTE_PREEMPTION_MODE_WFI: | ||
645 | return "WFI"; | ||
646 | case NVGPU_COMPUTE_PREEMPTION_MODE_CTA: | ||
641 | return "CTA"; | 647 | return "CTA"; |
642 | |||
643 | default: | 648 | default: |
644 | return "?"; | 649 | return "?"; |
645 | } | 650 | } |
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 29f32d8f..7fa0b7fb 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h | |||
@@ -94,7 +94,8 @@ struct gr_ctx_buffer_desc { | |||
94 | struct gr_ctx_desc { | 94 | struct gr_ctx_desc { |
95 | struct mem_desc mem; | 95 | struct mem_desc mem; |
96 | 96 | ||
97 | int preempt_mode; | 97 | int graphics_preempt_mode; |
98 | int compute_preempt_mode; | ||
98 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC | 99 | #ifdef CONFIG_ARCH_TEGRA_18x_SOC |
99 | struct gr_ctx_desc_t18x t18x; | 100 | struct gr_ctx_desc_t18x t18x; |
100 | #endif | 101 | #endif |
diff --git a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c index 35bbe70c..dbe30f00 100644 --- a/drivers/gpu/nvgpu/gm20b/gr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/gr_gm20b.c | |||
@@ -824,7 +824,7 @@ static int gr_gm20b_alloc_gr_ctx(struct gk20a *g, | |||
824 | return err; | 824 | return err; |
825 | 825 | ||
826 | if (class == MAXWELL_COMPUTE_B) | 826 | if (class == MAXWELL_COMPUTE_B) |
827 | (*gr_ctx)->preempt_mode = NVGPU_GR_PREEMPTION_MODE_CTA; | 827 | (*gr_ctx)->compute_preempt_mode = NVGPU_COMPUTE_PREEMPTION_MODE_CTA; |
828 | 828 | ||
829 | gk20a_dbg_fn("done"); | 829 | gk20a_dbg_fn("done"); |
830 | 830 | ||
@@ -841,7 +841,7 @@ static void gr_gm20b_update_ctxsw_preemption_mode(struct gk20a *g, | |||
841 | 841 | ||
842 | gk20a_dbg_fn(""); | 842 | gk20a_dbg_fn(""); |
843 | 843 | ||
844 | if (gr_ctx->preempt_mode == NVGPU_GR_PREEMPTION_MODE_CTA) { | 844 | if (gr_ctx->compute_preempt_mode == NVGPU_COMPUTE_PREEMPTION_MODE_CTA) { |
845 | gk20a_dbg_info("CTA: %x", cta_preempt_option); | 845 | gk20a_dbg_info("CTA: %x", cta_preempt_option); |
846 | gk20a_mem_wr32(ctx_ptr + ctxsw_prog_main_image_preemption_options_o(), 0, | 846 | gk20a_mem_wr32(ctx_ptr + ctxsw_prog_main_image_preemption_options_o(), 0, |
847 | cta_preempt_option); | 847 | cta_preempt_option); |