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
9struct ref_tracker;
10
11struct 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	char			name[32];
21#endif
22};
23
24#ifdef CONFIG_REF_TRACKER
25
26static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
27					unsigned int quarantine_count,
28					const char *name)
29{
30	INIT_LIST_HEAD(&dir->list);
31	INIT_LIST_HEAD(&dir->quarantine);
32	spin_lock_init(&dir->lock);
33	dir->quarantine_avail = quarantine_count;
34	dir->dead = false;
35	refcount_set(&dir->untracked, 1);
36	refcount_set(&dir->no_tracker, 1);
37	strscpy(dir->name, name, sizeof(dir->name));
38	stack_depot_init();
39}
40
41void ref_tracker_dir_exit(struct ref_tracker_dir *dir);
42
43void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
44				  unsigned int display_limit);
45
46void ref_tracker_dir_print(struct ref_tracker_dir *dir,
47			   unsigned int display_limit);
48
49int ref_tracker_dir_snprint(struct ref_tracker_dir *dir, char *buf, size_t size);
50
51int ref_tracker_alloc(struct ref_tracker_dir *dir,
52		      struct ref_tracker **trackerp, gfp_t gfp);
53
54int ref_tracker_free(struct ref_tracker_dir *dir,
55		     struct ref_tracker **trackerp);
56
57#else /* CONFIG_REF_TRACKER */
58
59static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
60					unsigned int quarantine_count,
61					const char *name)
62{
63}
64
65static inline void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
66{
67}
68
69static inline void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
70						unsigned int display_limit)
71{
72}
73
74static inline void ref_tracker_dir_print(struct ref_tracker_dir *dir,
75					 unsigned int display_limit)
76{
77}
78
79static inline int ref_tracker_dir_snprint(struct ref_tracker_dir *dir,
80					  char *buf, size_t size)
81{
82	return 0;
83}
84
85static inline int ref_tracker_alloc(struct ref_tracker_dir *dir,
86				    struct ref_tracker **trackerp,
87				    gfp_t gfp)
88{
89	return 0;
90}
91
92static inline int ref_tracker_free(struct ref_tracker_dir *dir,
93				   struct ref_tracker **trackerp)
94{
95	return 0;
96}
97
98#endif
99
100#endif /* _LINUX_REF_TRACKER_H */
101