1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #ifndef _LINUX_REF_TRACKER_H
3 #define _LINUX_REF_TRACKER_H
4 #include <linux/refcount.h>
5 #include <linux/types.h>
6 #include <linux/spinlock.h>
7 #include <linux/stackdepot.h>
8 
9 struct ref_tracker;
10 
11 struct ref_tracker_dir {
12 #ifdef CONFIG_REF_TRACKER
13 	spinlock_t		lock;
14 	unsigned int		quarantine_avail;
15 	refcount_t		untracked;
16 	refcount_t		no_tracker;
17 	bool			dead;
18 	struct list_head	list; /* List of active trackers */
19 	struct list_head	quarantine; /* List of dead trackers */
20 #endif
21 };
22 
23 #ifdef CONFIG_REF_TRACKER
ref_tracker_dir_init(struct ref_tracker_dir * dir,unsigned int quarantine_count)24 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
25 					unsigned int quarantine_count)
26 {
27 	INIT_LIST_HEAD(&dir->list);
28 	INIT_LIST_HEAD(&dir->quarantine);
29 	spin_lock_init(&dir->lock);
30 	dir->quarantine_avail = quarantine_count;
31 	dir->dead = false;
32 	refcount_set(&dir->untracked, 1);
33 	refcount_set(&dir->no_tracker, 1);
34 	stack_depot_init();
35 }
36 
37 void ref_tracker_dir_exit(struct ref_tracker_dir *dir);
38 
39 void ref_tracker_dir_print(struct ref_tracker_dir *dir,
40 			   unsigned int display_limit);
41 
42 int ref_tracker_alloc(struct ref_tracker_dir *dir,
43 		      struct ref_tracker **trackerp, gfp_t gfp);
44 
45 int ref_tracker_free(struct ref_tracker_dir *dir,
46 		     struct ref_tracker **trackerp);
47 
48 #else /* CONFIG_REF_TRACKER */
49 
ref_tracker_dir_init(struct ref_tracker_dir * dir,unsigned int quarantine_count)50 static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
51 					unsigned int quarantine_count)
52 {
53 }
54 
ref_tracker_dir_exit(struct ref_tracker_dir * dir)55 static inline void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
56 {
57 }
58 
ref_tracker_dir_print(struct ref_tracker_dir * dir,unsigned int display_limit)59 static inline void ref_tracker_dir_print(struct ref_tracker_dir *dir,
60 					 unsigned int display_limit)
61 {
62 }
63 
ref_tracker_alloc(struct ref_tracker_dir * dir,struct ref_tracker ** trackerp,gfp_t gfp)64 static inline int ref_tracker_alloc(struct ref_tracker_dir *dir,
65 				    struct ref_tracker **trackerp,
66 				    gfp_t gfp)
67 {
68 	return 0;
69 }
70 
ref_tracker_free(struct ref_tracker_dir * dir,struct ref_tracker ** trackerp)71 static inline int ref_tracker_free(struct ref_tracker_dir *dir,
72 				   struct ref_tracker **trackerp)
73 {
74 	return 0;
75 }
76 
77 #endif
78 
79 #endif /* _LINUX_REF_TRACKER_H */
80