diff options
author | Konsta Holtta <kholtta@nvidia.com> | 2017-06-13 09:15:47 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2017-06-19 05:15:53 -0400 |
commit | 9d2e7730515acf3114f7d1354277db81b5b022b0 (patch) | |
tree | e0214d6d40ac0785536c66495d7e03c2c14625a3 /drivers/gpu/nvgpu/common | |
parent | 741e5c45179db066ddf5bed0be6f36e4d0d4010e (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.c | 17 |
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 | ||
21 | int 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 | |||
21 | int nvgpu_thread_create(struct nvgpu_thread *thread, | 30 | int 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 | ||
45 | bool nvgpu_thread_is_running(struct nvgpu_thread *thread) | 58 | bool nvgpu_thread_is_running(struct nvgpu_thread *thread) |
46 | { | 59 | { |
47 | return thread->task != NULL; | 60 | return ACCESS_ONCE(thread->running); |
48 | }; | 61 | }; |