From 4f9368522ea18e3734798d2032b21c58dbb93a04 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Thu, 8 Mar 2018 14:51:26 +0200 Subject: 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 Reviewed-on: https://git-master.nvidia.com/r/1652087 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: svc-mobile-coverity Reviewed-by: Alex Waterman GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/semaphore.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu') 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) { int ret = 0; struct gk20a *gk20a = sea->gk20a; + u32 i; __lock_sema_sea(sea); @@ -71,6 +72,14 @@ static int __nvgpu_semaphore_sea_grow(struct nvgpu_semaphore_sea *sea) sea->size = SEMAPHORE_POOL_COUNT; sea->map_size = SEMAPHORE_POOL_COUNT * PAGE_SIZE; + /* + * Start the semaphores at values that will soon overflow the 32-bit + * integer range. This way any buggy comparisons would start to fail + * sooner rather than later. + */ + for (i = 0; i < PAGE_SIZE * SEMAPHORE_POOL_COUNT; i += 4) + nvgpu_mem_wr(gk20a, &sea->sea_mem, i, 0xfffffff0); + out: __unlock_sema_sea(sea); return ret; @@ -345,6 +354,7 @@ static int __nvgpu_init_hw_sema(struct channel_gk20a *ch) int ret = 0; struct nvgpu_semaphore_int *hw_sema; struct nvgpu_semaphore_pool *p = ch->vm->sema_pool; + int current_value; BUG_ON(!p); @@ -369,8 +379,8 @@ static int __nvgpu_init_hw_sema(struct channel_gk20a *ch) hw_sema->p = p; hw_sema->idx = hw_sema_idx; hw_sema->offset = SEMAPHORE_SIZE * hw_sema_idx; - nvgpu_atomic_set(&hw_sema->next_value, 0); - nvgpu_mem_wr(ch->g, &p->rw_mem, hw_sema->offset, 0); + current_value = nvgpu_mem_rd(ch->g, &p->rw_mem, hw_sema->offset); + nvgpu_atomic_set(&hw_sema->next_value, current_value); nvgpu_mutex_release(&p->pool_lock); -- cgit v1.2.2