gpu: nvgpu: allocate separate client managed syncpoint for User

We right now allocate a nvgpu managed syncpoint in c->sync and share
that with user space

But to avoid conflicts between user space and kernel space increments
allocate a separate "client managed" syncpoint for User space in c->user_sync

Add new API nvgpu_nvhost_get_syncpt_client_managed() to request a client managed
syncpoint from nvhost.
Note that nvhost/nvgpu do not keep track of MAX/threshold value of this syncpoint

Update gk20a_channel_syncpt_create() to receive a flag to indicate whether a
User space syncpoint is required or not

Unset NVGPU_SUPPORT_USER_SYNCPOINT for gp10b since we don't want to allocate
double syncpoints per channel on that platform

For gv11b, once we move to use user space submits, support for c->sync will be
dropped so we keep using only one syncpoint per channel

Bug 200326065
Jira NVGPU-179

Change-Id: I78d94de4276db1c897ea2a4fe4c2db8b2a179722
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1665828
Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Deepak Nibade
2018-02-28 03:56:36 -08:00
committed by mobile promotions
parent aa1da74a75
commit df2100018d
9 changed files with 41 additions and 17 deletions

View File

@@ -444,7 +444,7 @@ static int gk20a_submit_prepare_syncs(struct channel_gk20a *c,
if (g->aggressive_sync_destroy_thresh) { if (g->aggressive_sync_destroy_thresh) {
nvgpu_mutex_acquire(&c->sync_lock); nvgpu_mutex_acquire(&c->sync_lock);
if (!c->sync) { if (!c->sync) {
c->sync = gk20a_channel_sync_create(c); c->sync = gk20a_channel_sync_create(c, false);
if (!c->sync) { if (!c->sync) {
err = -ENOMEM; err = -ENOMEM;
nvgpu_mutex_release(&c->sync_lock); nvgpu_mutex_release(&c->sync_lock);

View File

@@ -972,11 +972,11 @@ static int nvgpu_ioctl_channel_get_user_syncpoint(struct channel_gk20a *ch,
} }
nvgpu_mutex_acquire(&ch->sync_lock); nvgpu_mutex_acquire(&ch->sync_lock);
if (ch->sync) { if (ch->user_sync) {
nvgpu_mutex_release(&ch->sync_lock); nvgpu_mutex_release(&ch->sync_lock);
} else { } else {
ch->sync = gk20a_channel_sync_create(ch); ch->user_sync = gk20a_channel_sync_create(ch, true);
if (!ch->sync) { if (!ch->user_sync) {
nvgpu_mutex_release(&ch->sync_lock); nvgpu_mutex_release(&ch->sync_lock);
return -ENOMEM; return -ENOMEM;
} }
@@ -989,11 +989,11 @@ static int nvgpu_ioctl_channel_get_user_syncpoint(struct channel_gk20a *ch,
} }
} }
args->syncpoint_id = ch->sync->syncpt_id(ch->sync); args->syncpoint_id = ch->user_sync->syncpt_id(ch->user_sync);
args->syncpoint_max = nvgpu_nvhost_syncpt_read_maxval(g->nvhost_dev, args->syncpoint_max = nvgpu_nvhost_syncpt_read_maxval(g->nvhost_dev,
args->syncpoint_id); args->syncpoint_id);
if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS)) if (nvgpu_is_enabled(g, NVGPU_SUPPORT_SYNCPOINT_ADDRESS))
args->gpu_va = ch->sync->syncpt_address(ch->sync); args->gpu_va = ch->user_sync->syncpt_address(ch->user_sync);
else else
args->gpu_va = 0; args->gpu_va = 0;

View File

@@ -138,6 +138,14 @@ u32 nvgpu_nvhost_get_syncpt_host_managed(
param, syncpt_name); param, syncpt_name);
} }
u32 nvgpu_nvhost_get_syncpt_client_managed(
struct nvgpu_nvhost_dev *nvhost_dev,
const char *syncpt_name)
{
return nvhost_get_syncpt_client_managed(nvhost_dev->host1x_pdev,
syncpt_name);
}
int nvgpu_nvhost_syncpt_wait_timeout_ext( int nvgpu_nvhost_syncpt_wait_timeout_ext(
struct nvgpu_nvhost_dev *nvhost_dev, u32 id, struct nvgpu_nvhost_dev *nvhost_dev, u32 id,
u32 thresh, u32 timeout, u32 *value, struct timespec *ts) u32 thresh, u32 timeout, u32 *value, struct timespec *ts)

View File

@@ -438,6 +438,10 @@ static void gk20a_free_channel(struct channel_gk20a *ch, bool force)
gk20a_channel_sync_destroy(ch->sync); gk20a_channel_sync_destroy(ch->sync);
ch->sync = NULL; ch->sync = NULL;
} }
if (ch->user_sync) {
gk20a_channel_sync_destroy(ch->user_sync);
ch->user_sync = NULL;
}
nvgpu_mutex_release(&ch->sync_lock); nvgpu_mutex_release(&ch->sync_lock);
/* /*
@@ -1147,7 +1151,7 @@ int gk20a_channel_alloc_gpfifo(struct channel_gk20a *c,
if (!g->aggressive_sync_destroy_thresh) { if (!g->aggressive_sync_destroy_thresh) {
nvgpu_mutex_acquire(&c->sync_lock); nvgpu_mutex_acquire(&c->sync_lock);
c->sync = gk20a_channel_sync_create(c); c->sync = gk20a_channel_sync_create(c, false);
if (!c->sync) { if (!c->sync) {
err = -ENOMEM; err = -ENOMEM;
nvgpu_mutex_release(&c->sync_lock); nvgpu_mutex_release(&c->sync_lock);

View File

@@ -226,6 +226,7 @@ struct channel_gk20a {
struct nvgpu_mutex sync_lock; struct nvgpu_mutex sync_lock;
struct gk20a_channel_sync *sync; struct gk20a_channel_sync *sync;
struct gk20a_channel_sync *user_sync;
#ifdef CONFIG_TEGRA_GR_VIRTUALIZATION #ifdef CONFIG_TEGRA_GR_VIRTUALIZATION
u64 virt_ctx; u64 virt_ctx;

View File

@@ -315,7 +315,7 @@ static void gk20a_channel_syncpt_destroy(struct gk20a_channel_sync *s)
} }
static struct gk20a_channel_sync * static struct gk20a_channel_sync *
gk20a_channel_syncpt_create(struct channel_gk20a *c) gk20a_channel_syncpt_create(struct channel_gk20a *c, bool user_managed)
{ {
struct gk20a_channel_syncpt *sp; struct gk20a_channel_syncpt *sp;
char syncpt_name[32]; char syncpt_name[32];
@@ -327,11 +327,19 @@ gk20a_channel_syncpt_create(struct channel_gk20a *c)
sp->c = c; sp->c = c;
sp->nvhost_dev = c->g->nvhost_dev; sp->nvhost_dev = c->g->nvhost_dev;
if (user_managed) {
snprintf(syncpt_name, sizeof(syncpt_name),
"%s_%d_user", c->g->name, c->chid);
sp->id = nvgpu_nvhost_get_syncpt_client_managed(sp->nvhost_dev,
syncpt_name);
} else {
snprintf(syncpt_name, sizeof(syncpt_name), snprintf(syncpt_name, sizeof(syncpt_name),
"%s_%d", c->g->name, c->chid); "%s_%d", c->g->name, c->chid);
sp->id = nvgpu_nvhost_get_syncpt_host_managed(sp->nvhost_dev, sp->id = nvgpu_nvhost_get_syncpt_host_managed(sp->nvhost_dev,
c->chid, syncpt_name); c->chid, syncpt_name);
}
if (!sp->id) { if (!sp->id) {
nvgpu_kfree(c->g, sp); nvgpu_kfree(c->g, sp);
nvgpu_err(c->g, "failed to get free syncpt"); nvgpu_err(c->g, "failed to get free syncpt");
@@ -892,7 +900,7 @@ static void gk20a_channel_semaphore_destroy(struct gk20a_channel_sync *s)
} }
static struct gk20a_channel_sync * static struct gk20a_channel_sync *
gk20a_channel_semaphore_create(struct channel_gk20a *c) gk20a_channel_semaphore_create(struct channel_gk20a *c, bool user_managed)
{ {
int asid = -1; int asid = -1;
struct gk20a_channel_semaphore *sema; struct gk20a_channel_semaphore *sema;
@@ -940,13 +948,14 @@ void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync)
sync->destroy(sync); sync->destroy(sync);
} }
struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c) struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c,
bool user_managed)
{ {
#ifdef CONFIG_TEGRA_GK20A_NVHOST #ifdef CONFIG_TEGRA_GK20A_NVHOST
if (gk20a_platform_has_syncpoints(c->g)) if (gk20a_platform_has_syncpoints(c->g))
return gk20a_channel_syncpt_create(c); return gk20a_channel_syncpt_create(c, user_managed);
#endif #endif
return gk20a_channel_semaphore_create(c); return gk20a_channel_semaphore_create(c, user_managed);
} }
bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g) bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g)

View File

@@ -110,7 +110,8 @@ struct gk20a_channel_sync {
}; };
void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync); void gk20a_channel_sync_destroy(struct gk20a_channel_sync *sync);
struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c); struct gk20a_channel_sync *gk20a_channel_sync_create(struct channel_gk20a *c,
bool user_managed);
bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g); bool gk20a_channel_sync_needs_sync_framework(struct gk20a *g);
#ifdef CONFIG_SYNC #ifdef CONFIG_SYNC

View File

@@ -116,6 +116,5 @@ int gp10b_init_gpu_characteristics(struct gk20a *g)
gk20a_init_gpu_characteristics(g); gk20a_init_gpu_characteristics(g);
gp10b_detect_ecc_enabled_units(g); gp10b_detect_ecc_enabled_units(g);
__nvgpu_set_enabled(g, NVGPU_SUPPORT_RESCHEDULE_RUNLIST, true); __nvgpu_set_enabled(g, NVGPU_SUPPORT_RESCHEDULE_RUNLIST, true);
__nvgpu_set_enabled(g, NVGPU_SUPPORT_USER_SYNCPOINT, true);
return 0; return 0;
} }

View File

@@ -65,6 +65,8 @@ void nvgpu_nvhost_syncpt_put_ref_ext(struct nvgpu_nvhost_dev *nvhost_dev,
u32 nvgpu_nvhost_get_syncpt_host_managed(struct nvgpu_nvhost_dev *nvhost_dev, u32 nvgpu_nvhost_get_syncpt_host_managed(struct nvgpu_nvhost_dev *nvhost_dev,
u32 param, u32 param,
const char *syncpt_name); const char *syncpt_name);
u32 nvgpu_nvhost_get_syncpt_client_managed(struct nvgpu_nvhost_dev *nvhost_dev,
const char *syncpt_name);
int nvgpu_nvhost_create_symlink(struct gk20a *g); int nvgpu_nvhost_create_symlink(struct gk20a *g);
void nvgpu_nvhost_remove_symlink(struct gk20a *g); void nvgpu_nvhost_remove_symlink(struct gk20a *g);