From 9d2e7730515acf3114f7d1354277db81b5b022b0 Mon Sep 17 00:00:00 2001 From: Konsta Holtta Date: Tue, 13 Jun 2017 16:15:47 +0300 Subject: 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 Reviewed-on: http://git-master/r/1501571 Reviewed-by: Mahantesh Kumbar Reviewed-by: Alex Waterman Reviewed-by: svccoveritychecker GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu --- drivers/gpu/nvgpu/common/linux/thread.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/nvgpu/common') 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 @@ #include +int nvgpu_thread_proxy(void *threaddata) +{ + struct nvgpu_thread *thread = threaddata; + int ret = thread->fn(thread->data); + + thread->running = false; + return ret; +} + int nvgpu_thread_create(struct nvgpu_thread *thread, void *data, int (*threadfn)(void *data), const char *name) { - struct task_struct *task = kthread_create(threadfn, data, name); + struct task_struct *task = kthread_create(nvgpu_thread_proxy, + thread, name); if (IS_ERR(task)) return PTR_ERR(task); thread->task = task; + thread->fn = threadfn; + thread->data = data; + thread->running = true; wake_up_process(task); return 0; }; @@ -44,5 +57,5 @@ bool nvgpu_thread_should_stop(struct nvgpu_thread *thread) bool nvgpu_thread_is_running(struct nvgpu_thread *thread) { - return thread->task != NULL; + return ACCESS_ONCE(thread->running); }; -- cgit v1.2.2