summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/semaphore.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2018-03-08 07:51:26 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-03-09 11:53:19 -0500
commit4f9368522ea18e3734798d2032b21c58dbb93a04 (patch)
tree0d0b1dd96953d4f564821387452854d3ecafc441 /drivers/gpu/nvgpu/common/semaphore.c
parenta83c99ecb41c5fa0b287efafa22db0e9770ab3e4 (diff)
gpu: nvgpu: don't reset semaphores to 0 on init
With proper wrap-handling comparisons now supported, it's safe to not reset a kernel-managed semaphore to 0 when initializing it to be used by some channel; the value can be left unchanged, so that any pending waits on other channels for this sema can't get corrupted anymore. This makes semaphore values very similar to syncpoints, i.e., just monotonically increasing counters. Also clear the semaphore sea to values of 0xfffffff0 when allocating it. This way it takes 16 increments on each sema to wrap over the 32-bit integer range; such wrapping would eventually happen if the memory was initialized to zeros, so this way any bugs possibly caused by wrapping not taken into account would uncover quickly after boot. Jira NVGPU-514 Change-Id: I93f9b1d32d020a4c23824f5856bc463b1895b99d Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1652087 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> Reviewed-by: Alex Waterman <alexw@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>
Diffstat (limited to 'drivers/gpu/nvgpu/common/semaphore.c')
-rw-r--r--drivers/gpu/nvgpu/common/semaphore.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/common/semaphore.c b/drivers/gpu/nvgpu/common/semaphore.c
index e1e6c027..dfed3588 100644
--- a/drivers/gpu/nvgpu/common/semaphore.c
+++ b/drivers/gpu/nvgpu/common/semaphore.c
@@ -59,6 +59,7 @@ static int __nvgpu_semaphore_sea_grow(struct nvgpu_semaphore_sea *sea)
59{ 59{
60 int ret = 0; 60 int ret = 0;
61 struct gk20a *gk20a = sea->gk20a; 61 struct gk20a *gk20a = sea->gk20a;
62 u32 i;
62 63
63 __lock_sema_sea(sea); 64 __lock_sema_sea(sea);
64 65
@@ -71,6 +72,14 @@ static int __nvgpu_semaphore_sea_grow(struct nvgpu_semaphore_sea *sea)
71 sea->size = SEMAPHORE_POOL_COUNT; 72 sea->size = SEMAPHORE_POOL_COUNT;
72 sea->map_size = SEMAPHORE_POOL_COUNT * PAGE_SIZE; 73 sea->map_size = SEMAPHORE_POOL_COUNT * PAGE_SIZE;
73 74
75 /*
76 * Start the semaphores at values that will soon overflow the 32-bit
77 * integer range. This way any buggy comparisons would start to fail
78 * sooner rather than later.
79 */
80 for (i = 0; i < PAGE_SIZE * SEMAPHORE_POOL_COUNT; i += 4)
81 nvgpu_mem_wr(gk20a, &sea->sea_mem, i, 0xfffffff0);
82
74out: 83out:
75 __unlock_sema_sea(sea); 84 __unlock_sema_sea(sea);
76 return ret; 85 return ret;
@@ -345,6 +354,7 @@ static int __nvgpu_init_hw_sema(struct channel_gk20a *ch)
345 int ret = 0; 354 int ret = 0;
346 struct nvgpu_semaphore_int *hw_sema; 355 struct nvgpu_semaphore_int *hw_sema;
347 struct nvgpu_semaphore_pool *p = ch->vm->sema_pool; 356 struct nvgpu_semaphore_pool *p = ch->vm->sema_pool;
357 int current_value;
348 358
349 BUG_ON(!p); 359 BUG_ON(!p);
350 360
@@ -369,8 +379,8 @@ static int __nvgpu_init_hw_sema(struct channel_gk20a *ch)
369 hw_sema->p = p; 379 hw_sema->p = p;
370 hw_sema->idx = hw_sema_idx; 380 hw_sema->idx = hw_sema_idx;
371 hw_sema->offset = SEMAPHORE_SIZE * hw_sema_idx; 381 hw_sema->offset = SEMAPHORE_SIZE * hw_sema_idx;
372 nvgpu_atomic_set(&hw_sema->next_value, 0); 382 current_value = nvgpu_mem_rd(ch->g, &p->rw_mem, hw_sema->offset);
373 nvgpu_mem_wr(ch->g, &p->rw_mem, hw_sema->offset, 0); 383 nvgpu_atomic_set(&hw_sema->next_value, current_value);
374 384
375 nvgpu_mutex_release(&p->pool_lock); 385 nvgpu_mutex_release(&p->pool_lock);
376 386