summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2017-06-13 09:15:47 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-06-19 05:15:53 -0400
commit9d2e7730515acf3114f7d1354277db81b5b022b0 (patch)
treee0214d6d40ac0785536c66495d7e03c2c14625a3 /drivers/gpu/nvgpu/common
parent741e5c45179db066ddf5bed0be6f36e4d0d4010e (diff)
gpu: nvgpu: mark thread stopped when it independently quits
It's technically possible for a thread to exit without first calling nvgpu_thread_stop() in another, so mark the thread exit status from the thread after it has finished instead of in nvgpu_thread_stop(). Do this by starting the thread as a proxy function which calls the actual thread function and then sets the flag. Also, add a new flag to actually signify the running state because the thread->task going null abruptly would break nvgpu_thread_stop(). This does not guarantee that the kernel thread itself has stopped, but the function which can be considered as an "nvgpu thread" will be. Change-Id: Ib911b02bd51342ddeb8e6b9533ef7943f2606d2d Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1501571 Reviewed-by: Mahantesh Kumbar <mkumbar@nvidia.com> Reviewed-by: Alex Waterman <alexw@nvidia.com> Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common')
-rw-r--r--drivers/gpu/nvgpu/common/linux/thread.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/thread.c b/drivers/gpu/nvgpu/common/linux/thread.c
index ef783bbe..fe3906eb 100644
--- a/drivers/gpu/nvgpu/common/linux/thread.c
+++ b/drivers/gpu/nvgpu/common/linux/thread.c
@@ -18,15 +18,28 @@
18 18
19#include <nvgpu/thread.h> 19#include <nvgpu/thread.h>
20 20
21int nvgpu_thread_proxy(void *threaddata)
22{
23 struct nvgpu_thread *thread = threaddata;
24 int ret = thread->fn(thread->data);
25
26 thread->running = false;
27 return ret;
28}
29
21int nvgpu_thread_create(struct nvgpu_thread *thread, 30int nvgpu_thread_create(struct nvgpu_thread *thread,
22 void *data, 31 void *data,
23 int (*threadfn)(void *data), const char *name) 32 int (*threadfn)(void *data), const char *name)
24{ 33{
25 struct task_struct *task = kthread_create(threadfn, data, name); 34 struct task_struct *task = kthread_create(nvgpu_thread_proxy,
35 thread, name);
26 if (IS_ERR(task)) 36 if (IS_ERR(task))
27 return PTR_ERR(task); 37 return PTR_ERR(task);
28 38
29 thread->task = task; 39 thread->task = task;
40 thread->fn = threadfn;
41 thread->data = data;
42 thread->running = true;
30 wake_up_process(task); 43 wake_up_process(task);
31 return 0; 44 return 0;
32}; 45};
@@ -44,5 +57,5 @@ bool nvgpu_thread_should_stop(struct nvgpu_thread *thread)
44 57
45bool nvgpu_thread_is_running(struct nvgpu_thread *thread) 58bool nvgpu_thread_is_running(struct nvgpu_thread *thread)
46{ 59{
47 return thread->task != NULL; 60 return ACCESS_ONCE(thread->running);
48}; 61};