1 /*
2 * Copyright (c) 2019 The Linux Foundation. All rights reserved.
3 * Copyright (c) 2021, 2023 Qualcomm Innovation Center, Inc. All rights reserved.
4 *
5 *
6 * Permission to use, copy, modify, and/or distribute this software for
7 * any purpose with or without fee is hereby granted, provided that the
8 * above copyright notice and this permission notice appear in all
9 * copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
12 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
13 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
14 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
15 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
16 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
17 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
18 * PERFORMANCE OF THIS SOFTWARE.
19 */
20
21 #ifndef __QDF_TRACKER_H
22 #define __QDF_TRACKER_H
23
24 #include "qdf_lock.h"
25 #include "qdf_ptr_hash.h"
26 #include "qdf_status.h"
27 #include "qdf_types.h"
28
29 #define QDF_TRACKER_FUNC_SIZE 48
30
31 /**
32 * struct qdf_tracker - a generic type for tracking resources
33 * @leak_title: the string title to use when logging leaks
34 * @track_title: the string title to use when logging double tracking issues
35 * @untrack_title: the string title to use when logging double untracking issues
36 * @lock: lock for simultaneous access to @ht
37 * @ht: the hashtable used for storing tracking information
38 */
39 struct qdf_tracker {
40 const char *leak_title;
41 const char *track_title;
42 const char *untrack_title;
43 struct qdf_spinlock lock;
44 struct qdf_ptr_hash *ht;
45 };
46
47 /**
48 * qdf_tracker_declare() - statically declare a qdf_tacker instance
49 * @name: C identifier to use for the new qdf_tracker
50 * @bits: the number of bits to use for hashing the resource pointers
51 * @_leak_title: the string title to use when logging leaks
52 * @_track_title: the string title to use when logging double tracking issues
53 * @_untrack_title: the string title to use when logging double untracking issues
54 */
55 #define qdf_tracker_declare(name, bits, _leak_title, \
56 _track_title, _untrack_title) \
57 qdf_ptr_hash_declare(name ## _ht, bits); \
58 struct qdf_tracker name = { \
59 .leak_title = _leak_title, \
60 .track_title = _track_title, \
61 .untrack_title = _untrack_title, \
62 .ht = qdf_ptr_hash_ptr(name ## _ht), \
63 }
64
65 #ifdef CONFIG_LEAK_DETECTION
66 /**
67 * qdf_tracker_init() - initialize a qdf_tracker
68 * @tracker: the qdf_tracker to initialize
69 *
70 * Return: None
71 */
72 void qdf_tracker_init(struct qdf_tracker *tracker);
73
74 /**
75 * qdf_tracker_deinit() - de-initialize a qdf_tracker
76 * @tracker: the qdf_tracker to de-initialize
77 *
78 * Return: None
79 */
80 void qdf_tracker_deinit(struct qdf_tracker *tracker);
81
82 /**
83 * qdf_tracker_track() - track a resource with @tracker
84 * @tracker: the qdf_tracker to track with
85 * @ptr: an opaque pointer to the resource to track
86 * @func: name of the caller function operating on @ptr
87 * @line: line number of the call site operating on @ptr
88 *
89 * Return: QDF_STATUS
90 */
91 qdf_must_check QDF_STATUS
92 qdf_tracker_track(struct qdf_tracker *tracker, void *ptr,
93 const char *func, uint32_t line);
94
95 /**
96 * qdf_tracker_untrack() - untrack a resource with @tracker
97 * @tracker: the qdf_tracker used to track @ptr
98 * @ptr: an opaque pointer to the resource to untrack
99 * @func: name of the caller function operating on @ptr
100 * @line: line number of the call site operating on @ptr
101 *
102 * Return: None
103 */
104 void qdf_tracker_untrack(struct qdf_tracker *tracker, void *ptr,
105 const char *func, uint32_t line);
106
107 /**
108 * qdf_tracker_check_for_leaks() - assert @tracker has no tracked resources
109 * for the current debug domain
110 * @tracker: the qdf_tracker to check
111 *
112 * Return: None
113 */
114 void qdf_tracker_check_for_leaks(struct qdf_tracker *tracker);
115
116 /**
117 * qdf_tracker_lookup() - query tracking information for @ptr
118 * @tracker: the qdf_tracker to check
119 * @ptr: the opaque pointer of the resource to lookup
120 * @out_func: function name provided when @ptr was tracked, populated on success
121 * @out_line: line number provided when @ptr was tracked, populated on success
122 *
123 * Note: @out_func is assumed to be sizeof(QDF_TRACKER_FUNC_SIZE).
124 *
125 * Return: true if @tracker is tracking @ptr
126 */
127 qdf_must_check bool
128 qdf_tracker_lookup(struct qdf_tracker *tracker, void *ptr,
129 char (*out_func)[QDF_TRACKER_FUNC_SIZE],
130 uint32_t *out_line);
131 #else
132 static inline
qdf_tracker_init(struct qdf_tracker * tracker)133 void qdf_tracker_init(struct qdf_tracker *tracker)
134 {
135 }
136
137 static inline
qdf_tracker_deinit(struct qdf_tracker * tracker)138 void qdf_tracker_deinit(struct qdf_tracker *tracker)
139 {
140 }
141
142 static inline qdf_must_check QDF_STATUS
qdf_tracker_track(struct qdf_tracker * tracker,void * ptr,const char * func,uint32_t line)143 qdf_tracker_track(struct qdf_tracker *tracker, void *ptr,
144 const char *func, uint32_t line)
145 {
146 return QDF_STATUS_SUCCESS;
147 }
148
149 static inline
qdf_tracker_untrack(struct qdf_tracker * tracker,void * ptr,const char * func,uint32_t line)150 void qdf_tracker_untrack(struct qdf_tracker *tracker, void *ptr,
151 const char *func, uint32_t line)
152 {
153 }
154
155 static inline
qdf_tracker_check_for_leaks(struct qdf_tracker * tracker)156 void qdf_tracker_check_for_leaks(struct qdf_tracker *tracker)
157 {
158 }
159
160 static inline qdf_must_check bool
qdf_tracker_lookup(struct qdf_tracker * tracker,void * ptr,char (* out_func)[QDF_TRACKER_FUNC_SIZE],uint32_t * out_line)161 qdf_tracker_lookup(struct qdf_tracker *tracker, void *ptr,
162 char (*out_func)[QDF_TRACKER_FUNC_SIZE],
163 uint32_t *out_line)
164 {
165 return false;
166 }
167 #endif
168 #endif /* __QDF_TRACKER_H */
169
170