summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2017-01-04 13:59:01 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-01-11 12:13:43 -0500
commit5e68c6e971d98fc9d4beaf69c5ca58f39f8db1a7 (patch)
tree6b67a949668f21858a27f0546068659ff680cc46 /drivers/gpu/nvgpu/gk20a/channel_gk20a.h
parent318524ee2f8bc117db25608d432bcc60d92d8c08 (diff)
gpu: nvgpu: add support for refcount tracking
If enabled, track actions (gets and puts) on channel reference counters. Dump the most recent actions to syslog when gk20a_wait_until_counter_is_N gets stuck when closing a channel. GK20A_CHANNEL_REFCOUNT_TRACKING specifies the size of the action history. Default is to disable completely, as this has some runtime overhead. Bug 1826754 Change-Id: I880b0efe8881044d02ae224c243a51cb6c2db8c1 Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1262424 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.h48
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
index 697d1603..44a989da 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * GK20A graphics channel 2 * GK20A graphics channel
3 * 3 *
4 * Copyright (c) 2011-2016, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -24,6 +24,7 @@
24#include <linux/semaphore.h> 24#include <linux/semaphore.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/stacktrace.h>
27#include <linux/wait.h> 28#include <linux/wait.h>
28#include <uapi/linux/nvgpu.h> 29#include <uapi/linux/nvgpu.h>
29 30
@@ -115,6 +116,40 @@ struct channel_gk20a_clean_up {
115 struct delayed_work wq; 116 struct delayed_work wq;
116}; 117};
117 118
119/*
120 * 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
122 * should be enough to track moderately hard problems from the start.
123 */
124#define GK20A_CHANNEL_REFCOUNT_TRACKING 0
125/* Stack depth for the saved actions. */
126#define GK20A_CHANNEL_REFCOUNT_TRACKING_STACKLEN 8
127
128/*
129 * Because the puts and gets are not linked together explicitly (although they
130 * should always come in pairs), it's not possible to tell which ref holder to
131 * delete from the list when doing a put. So, just store some number of most
132 * recent gets and puts in a ring buffer, to obtain a history.
133 *
134 * These are zeroed when a channel is closed, so a new one starts fresh.
135 */
136
137enum channel_gk20a_ref_action_type {
138 channel_gk20a_ref_action_get,
139 channel_gk20a_ref_action_put
140};
141
142struct channel_gk20a_ref_action {
143 enum channel_gk20a_ref_action_type type;
144 unsigned long jiffies;
145 /*
146 * Many of these traces will be similar. Simpler to just capture
147 * duplicates than to have a separate database for the entries.
148 */
149 struct stack_trace trace;
150 unsigned long trace_entries[GK20A_CHANNEL_REFCOUNT_TRACKING_STACKLEN];
151};
152
118/* this is the priv element of struct nvhost_channel */ 153/* this is the priv element of struct nvhost_channel */
119struct channel_gk20a { 154struct channel_gk20a {
120 struct gk20a *g; /* set only when channel is active */ 155 struct gk20a *g; /* set only when channel is active */
@@ -125,6 +160,17 @@ struct channel_gk20a {
125 bool referenceable; 160 bool referenceable;
126 atomic_t ref_count; 161 atomic_t ref_count;
127 wait_queue_head_t ref_count_dec_wq; 162 wait_queue_head_t ref_count_dec_wq;
163#if GK20A_CHANNEL_REFCOUNT_TRACKING
164 /*
165 * Ring buffer for most recent refcount gets and puts. Protected by
166 * ref_actions_lock when getting or putting refs (i.e., adding
167 * entries), and when reading entries.
168 */
169 struct channel_gk20a_ref_action ref_actions[
170 GK20A_CHANNEL_REFCOUNT_TRACKING];
171 size_t ref_actions_put; /* index of next write */
172 spinlock_t ref_actions_lock;
173#endif
128 174
129 struct gk20a_semaphore_int *hw_sema; 175 struct gk20a_semaphore_int *hw_sema;
130 176