summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2017-02-01 03:28:38 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-03-02 20:51:03 -0500
commitf1072a28be09dc7f5433b5e1013a76d8a87c2505 (patch)
tree68d1a5b5123834859f8ae8c4481b886b49364811 /drivers/gpu/nvgpu/gk20a/channel_gk20a.h
parent0c155313e75a82a409d3438cc982ee30bb453d16 (diff)
gpu: nvgpu: add worker for watchdog and job cleanup
Implement a worker thread to replace the delayed works in channel watchdog and job cleanups. Watchdog runs by polling the channel states periodically, and job cleanup is performed on channels that are appended on a work queue consumed by the worker thread. Handling both of these two in the same thread makes it impossible for them to cause a deadlock, as has previously happened. The watchdog takes references to channels during checking and possibly recovering channels. Jobs in the cleanup queue have an additional reference taken which is released after the channel is processed. The worker is woken up from periodic sleep when channels are added to the queue. Currently, the queue is only used for job cleanups, but it is extendable for other per-channel works too. The worker can also process other periodic actions dependent on channels. Neither the semantics of timeout handling or of job cleanups are yet significantly changed - this patch only serializes them into one background thread. Each job that needs cleanup is tracked and holds a reference to its channel and a power reference, and timeouts can only be processed on channels that are tracked, so the thread will always be idle if the system is going to be suspended, so there is currently no need to explicitly suspend or stop it. Bug 1848834 Bug 1851689 Bug 1814773 Bug 200270332 Jira NVGPU-21 Change-Id: I355101802f50841ea9bd8042a017f91c931d2dc7 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1297183 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/channel_gk20a.h')
-rw-r--r--drivers/gpu/nvgpu/gk20a/channel_gk20a.h33
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 14ee9f69..d9913cd7 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -27,6 +27,7 @@
27#include <uapi/linux/nvgpu.h> 27#include <uapi/linux/nvgpu.h>
28 28
29#include <nvgpu/lock.h> 29#include <nvgpu/lock.h>
30#include <nvgpu/timers.h>
30 31
31struct gk20a; 32struct gk20a;
32struct gr_gk20a; 33struct gr_gk20a;
@@ -87,12 +88,19 @@ struct channel_gk20a_joblist {
87 struct list_head jobs; 88 struct list_head jobs;
88 struct nvgpu_spinlock lock; 89 struct nvgpu_spinlock lock;
89 } dynamic; 90 } dynamic;
91
92 /*
93 * Synchronize abort cleanup (when closing a channel) and job cleanup
94 * (asynchronously from worker) - protect from concurrent access when
95 * job resources are being freed.
96 */
97 struct nvgpu_mutex cleanup_lock;
90}; 98};
91 99
92struct channel_gk20a_timeout { 100struct channel_gk20a_timeout {
93 struct delayed_work wq;
94 struct nvgpu_raw_spinlock lock; 101 struct nvgpu_raw_spinlock lock;
95 bool initialized; 102 struct nvgpu_timeout timer;
103 bool running;
96 u32 gp_get; 104 u32 gp_get;
97}; 105};
98 106
@@ -110,12 +118,6 @@ struct gk20a_event_id_data {
110 struct list_head event_id_node; 118 struct list_head event_id_node;
111}; 119};
112 120
113struct channel_gk20a_clean_up {
114 struct nvgpu_mutex lock;
115 bool scheduled;
116 struct delayed_work wq;
117};
118
119/* 121/*
120 * Track refcount actions, saving their stack traces. This number specifies how 122 * Track refcount actions, saving their stack traces. This number specifies how
121 * many most recent actions are stored in a buffer. Set to 0 to disable. 128 123 * many most recent actions are stored in a buffer. Set to 0 to disable. 128
@@ -214,7 +216,8 @@ struct channel_gk20a {
214 u32 timeout_gpfifo_get; 216 u32 timeout_gpfifo_get;
215 217
216 struct channel_gk20a_timeout timeout; 218 struct channel_gk20a_timeout timeout;
217 struct channel_gk20a_clean_up clean_up; 219 /* for job cleanup handling in the background worker */
220 struct list_head worker_item;
218 221
219#if defined(CONFIG_GK20A_CYCLE_STATS) 222#if defined(CONFIG_GK20A_CYCLE_STATS)
220 struct { 223 struct {
@@ -250,8 +253,11 @@ struct channel_gk20a {
250 u64 virt_ctx; 253 u64 virt_ctx;
251#endif 254#endif
252 255
253 /* signal channel owner via a callback, if set, in gk20a_channel_update 256 /*
254 * via schedule_work */ 257 * Signal channel owner via a callback, if set, in job cleanup with
258 * schedule_work. Means that something finished on the channel (perhaps
259 * more than one job).
260 */
255 void (*update_fn)(struct channel_gk20a *, void *); 261 void (*update_fn)(struct channel_gk20a *, void *);
256 void *update_fn_data; 262 void *update_fn_data;
257 struct nvgpu_spinlock update_fn_lock; /* make access to the two above atomic */ 263 struct nvgpu_spinlock update_fn_lock; /* make access to the two above atomic */
@@ -293,6 +299,9 @@ int gk20a_disable_channel_tsg(struct gk20a *g, struct channel_gk20a *ch);
293int gk20a_channel_suspend(struct gk20a *g); 299int gk20a_channel_suspend(struct gk20a *g);
294int gk20a_channel_resume(struct gk20a *g); 300int gk20a_channel_resume(struct gk20a *g);
295 301
302int nvgpu_channel_worker_init(struct gk20a *g);
303void nvgpu_channel_worker_deinit(struct gk20a *g);
304
296/* Channel file operations */ 305/* Channel file operations */
297int gk20a_channel_open(struct inode *inode, struct file *filp); 306int gk20a_channel_open(struct inode *inode, struct file *filp);
298int gk20a_channel_open_ioctl(struct gk20a *g, 307int gk20a_channel_open_ioctl(struct gk20a *g,
@@ -302,7 +311,7 @@ long gk20a_channel_ioctl(struct file *filp,
302 unsigned long arg); 311 unsigned long arg);
303int gk20a_channel_release(struct inode *inode, struct file *filp); 312int gk20a_channel_release(struct inode *inode, struct file *filp);
304struct channel_gk20a *gk20a_get_channel_from_file(int fd); 313struct channel_gk20a *gk20a_get_channel_from_file(int fd);
305void gk20a_channel_update(struct channel_gk20a *c, int nr_completed); 314void gk20a_channel_update(struct channel_gk20a *c);
306 315
307void gk20a_init_channel(struct gpu_ops *gops); 316void gk20a_init_channel(struct gpu_ops *gops);
308 317