mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-23 18:16:01 +03:00
gpu: nvgpu: add usermode submission interface HAL
The patch adds the HAL interfaces for handling the usermode submission, particularly allocating channel specific usermode userd. These interfaces are currently implemented only on QNX, and are created accordingly. As and when linux adds the usermode submission support, we can revisit them if any further changes are needed. Change-Id: I790e0ebdfaedcdc5f6bb624652b1af4549b7b062 Signed-off-by: Sourab Gupta <sourabg@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1683392 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com> 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
03b8768902
commit
abd5f68eef
@@ -376,6 +376,13 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
|
|||||||
if(g->ops.fifo.free_channel_ctx_header)
|
if(g->ops.fifo.free_channel_ctx_header)
|
||||||
g->ops.fifo.free_channel_ctx_header(ch);
|
g->ops.fifo.free_channel_ctx_header(ch);
|
||||||
|
|
||||||
|
if (ch->usermode_submit_enabled) {
|
||||||
|
gk20a_channel_free_usermode_buffers(ch);
|
||||||
|
ch->userd_iova = nvgpu_mem_get_addr(g, &f->userd) +
|
||||||
|
ch->chid * f->userd_entry_size;
|
||||||
|
ch->usermode_submit_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
gk20a_gr_flush_channel_tlb(gr);
|
gk20a_gr_flush_channel_tlb(gr);
|
||||||
|
|
||||||
nvgpu_dma_unmap_free(ch_vm, &ch->gpfifo.mem);
|
nvgpu_dma_unmap_free(ch_vm, &ch->gpfifo.mem);
|
||||||
@@ -1086,12 +1093,30 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
|
|||||||
goto clean_up_idle;
|
goto clean_up_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gpfifo_args->flags & NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT) {
|
||||||
|
if (g->ops.fifo.alloc_usermode_buffers) {
|
||||||
|
err = g->ops.fifo.alloc_usermode_buffers(c,
|
||||||
|
gpfifo_args);
|
||||||
|
if (err) {
|
||||||
|
nvgpu_err(g, "Usermode buffer alloc failed");
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
c->userd_iova = nvgpu_mem_get_addr(g,
|
||||||
|
&c->usermode_userd);
|
||||||
|
c->usermode_submit_enabled = true;
|
||||||
|
} else {
|
||||||
|
nvgpu_err(g, "Usermode submit not supported");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = nvgpu_dma_alloc_map_sys(ch_vm,
|
err = nvgpu_dma_alloc_map_sys(ch_vm,
|
||||||
gpfifo_size * gpfifo_entry_size,
|
gpfifo_size * gpfifo_entry_size,
|
||||||
&c->gpfifo.mem);
|
&c->gpfifo.mem);
|
||||||
if (err) {
|
if (err) {
|
||||||
nvgpu_err(g, "%s: memory allocation failed", __func__);
|
nvgpu_err(g, "%s: memory allocation failed", __func__);
|
||||||
goto clean_up;
|
goto clean_up_usermode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->gpfifo.mem.aperture == APERTURE_VIDMEM || g->mm.force_pramin) {
|
if (c->gpfifo.mem.aperture == APERTURE_VIDMEM || g->mm.force_pramin) {
|
||||||
@@ -1174,6 +1199,13 @@ clean_up_sync:
|
|||||||
clean_up_unmap:
|
clean_up_unmap:
|
||||||
nvgpu_big_free(g, c->gpfifo.pipe);
|
nvgpu_big_free(g, c->gpfifo.pipe);
|
||||||
nvgpu_dma_unmap_free(ch_vm, &c->gpfifo.mem);
|
nvgpu_dma_unmap_free(ch_vm, &c->gpfifo.mem);
|
||||||
|
clean_up_usermode:
|
||||||
|
if (c->usermode_submit_enabled) {
|
||||||
|
gk20a_channel_free_usermode_buffers(c);
|
||||||
|
c->userd_iova = nvgpu_mem_get_addr(g, &g->fifo.userd) +
|
||||||
|
c->chid * g->fifo.userd_entry_size;
|
||||||
|
c->usermode_submit_enabled = false;
|
||||||
|
}
|
||||||
clean_up:
|
clean_up:
|
||||||
memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
|
memset(&c->gpfifo, 0, sizeof(struct gpfifo_desc));
|
||||||
clean_up_idle:
|
clean_up_idle:
|
||||||
@@ -1187,6 +1219,12 @@ clean_up_idle:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c)
|
||||||
|
{
|
||||||
|
if (nvgpu_mem_is_valid(&c->usermode_userd))
|
||||||
|
nvgpu_dma_free(c->g, &c->usermode_userd);
|
||||||
|
}
|
||||||
|
|
||||||
/* Update with this periodically to determine how the gpfifo is draining. */
|
/* Update with this periodically to determine how the gpfifo is draining. */
|
||||||
static inline u32 update_gp_get(struct gk20a *g,
|
static inline u32 update_gp_get(struct gk20a *g,
|
||||||
struct channel_gk20a *c)
|
struct channel_gk20a *c)
|
||||||
|
|||||||
@@ -45,10 +45,14 @@ struct fifo_profile_gk20a;
|
|||||||
#define NVGPU_GPFIFO_FLAGS_SUPPORT_VPR (1 << 0)
|
#define NVGPU_GPFIFO_FLAGS_SUPPORT_VPR (1 << 0)
|
||||||
#define NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC (1 << 1)
|
#define NVGPU_GPFIFO_FLAGS_SUPPORT_DETERMINISTIC (1 << 1)
|
||||||
#define NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE (1 << 2)
|
#define NVGPU_GPFIFO_FLAGS_REPLAYABLE_FAULTS_ENABLE (1 << 2)
|
||||||
|
#define NVGPU_GPFIFO_FLAGS_USERMODE_SUPPORT (1 << 3)
|
||||||
|
|
||||||
struct nvgpu_gpfifo_args {
|
struct nvgpu_gpfifo_args {
|
||||||
u32 num_entries;
|
u32 num_entries;
|
||||||
u32 num_inflight_jobs;
|
u32 num_inflight_jobs;
|
||||||
|
u32 userd_dmabuf_fd;
|
||||||
|
u32 gpfifo_dmabuf_fd;
|
||||||
|
u32 work_submit_token;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -184,6 +188,7 @@ struct channel_gk20a {
|
|||||||
/* deterministic, but explicitly idle and submits disallowed */
|
/* deterministic, but explicitly idle and submits disallowed */
|
||||||
bool deterministic_railgate_allowed;
|
bool deterministic_railgate_allowed;
|
||||||
bool cde;
|
bool cde;
|
||||||
|
bool usermode_submit_enabled;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
pid_t tgid;
|
pid_t tgid;
|
||||||
struct nvgpu_mutex ioctl_lock;
|
struct nvgpu_mutex ioctl_lock;
|
||||||
@@ -198,6 +203,7 @@ struct channel_gk20a {
|
|||||||
|
|
||||||
struct gpfifo_desc gpfifo;
|
struct gpfifo_desc gpfifo;
|
||||||
|
|
||||||
|
struct nvgpu_mem usermode_userd; /* Used for Usermode Submission */
|
||||||
struct nvgpu_mem inst_block;
|
struct nvgpu_mem inst_block;
|
||||||
|
|
||||||
u64 userd_iova;
|
u64 userd_iova;
|
||||||
@@ -361,6 +367,7 @@ void free_priv_cmdbuf(struct channel_gk20a *c,
|
|||||||
void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
|
void gk20a_channel_clean_up_jobs(struct channel_gk20a *c,
|
||||||
bool clean_all);
|
bool clean_all);
|
||||||
|
|
||||||
|
void gk20a_channel_free_usermode_buffers(struct channel_gk20a *c);
|
||||||
u32 nvgpu_get_gpfifo_entry_size(void);
|
u32 nvgpu_get_gpfifo_entry_size(void);
|
||||||
|
|
||||||
#endif /* CHANNEL_GK20A_H */
|
#endif /* CHANNEL_GK20A_H */
|
||||||
|
|||||||
@@ -3916,11 +3916,19 @@ void gk20a_fifo_setup_ramfc_for_privileged_channel(struct channel_gk20a *c)
|
|||||||
int gk20a_fifo_setup_userd(struct channel_gk20a *c)
|
int gk20a_fifo_setup_userd(struct channel_gk20a *c)
|
||||||
{
|
{
|
||||||
struct gk20a *g = c->g;
|
struct gk20a *g = c->g;
|
||||||
struct nvgpu_mem *mem = &g->fifo.userd;
|
struct nvgpu_mem *mem;
|
||||||
u32 offset = c->chid * g->fifo.userd_entry_size / sizeof(u32);
|
u32 offset;
|
||||||
|
|
||||||
gk20a_dbg_fn("");
|
gk20a_dbg_fn("");
|
||||||
|
|
||||||
|
if (nvgpu_mem_is_valid(&c->usermode_userd)) {
|
||||||
|
mem = &c->usermode_userd;
|
||||||
|
offset = 0;
|
||||||
|
} else {
|
||||||
|
mem = &g->fifo.userd;
|
||||||
|
offset = c->chid * g->fifo.userd_entry_size / sizeof(u32);
|
||||||
|
}
|
||||||
|
|
||||||
nvgpu_mem_wr32(g, mem, offset + ram_userd_put_w(), 0);
|
nvgpu_mem_wr32(g, mem, offset + ram_userd_put_w(), 0);
|
||||||
nvgpu_mem_wr32(g, mem, offset + ram_userd_get_w(), 0);
|
nvgpu_mem_wr32(g, mem, offset + ram_userd_get_w(), 0);
|
||||||
nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_w(), 0);
|
nvgpu_mem_wr32(g, mem, offset + ram_userd_ref_w(), 0);
|
||||||
|
|||||||
@@ -637,6 +637,8 @@ struct gpu_ops {
|
|||||||
int (*channel_suspend)(struct gk20a *g);
|
int (*channel_suspend)(struct gk20a *g);
|
||||||
int (*channel_resume)(struct gk20a *g);
|
int (*channel_resume)(struct gk20a *g);
|
||||||
void (*set_error_notifier)(struct channel_gk20a *ch, u32 error);
|
void (*set_error_notifier)(struct channel_gk20a *ch, u32 error);
|
||||||
|
int (*alloc_usermode_buffers)(struct channel_gk20a *c,
|
||||||
|
struct nvgpu_gpfifo_args *gpfifo_args);
|
||||||
#ifdef CONFIG_TEGRA_GK20A_NVHOST
|
#ifdef CONFIG_TEGRA_GK20A_NVHOST
|
||||||
int (*alloc_syncpt_buf)(struct channel_gk20a *c,
|
int (*alloc_syncpt_buf)(struct channel_gk20a *c,
|
||||||
u32 syncpt_id, struct nvgpu_mem *syncpt_buf);
|
u32 syncpt_id, struct nvgpu_mem *syncpt_buf);
|
||||||
|
|||||||
Reference in New Issue
Block a user