xref: /linux-6.15/include/linux/ref_tracker.h (revision 227c6c83)
14e66934eSEric Dumazet // SPDX-License-Identifier: GPL-2.0-or-later
24e66934eSEric Dumazet #ifndef _LINUX_REF_TRACKER_H
34e66934eSEric Dumazet #define _LINUX_REF_TRACKER_H
44e66934eSEric Dumazet #include <linux/refcount.h>
54e66934eSEric Dumazet #include <linux/types.h>
64e66934eSEric Dumazet #include <linux/spinlock.h>
72dba5eb1SVlastimil Babka #include <linux/stackdepot.h>
84e66934eSEric Dumazet 
94e66934eSEric Dumazet struct ref_tracker;
104e66934eSEric Dumazet 
114e66934eSEric Dumazet struct ref_tracker_dir {
124e66934eSEric Dumazet #ifdef CONFIG_REF_TRACKER
134e66934eSEric Dumazet 	spinlock_t		lock;
144e66934eSEric Dumazet 	unsigned int		quarantine_avail;
154e66934eSEric Dumazet 	refcount_t		untracked;
168fd5522fSEric Dumazet 	refcount_t		no_tracker;
17e3ececfeSEric Dumazet 	bool			dead;
184e66934eSEric Dumazet 	struct list_head	list; /* List of active trackers */
194e66934eSEric Dumazet 	struct list_head	quarantine; /* List of dead trackers */
20b6d7c0ebSAndrzej Hajda 	char			name[32];
214e66934eSEric Dumazet #endif
224e66934eSEric Dumazet };
234e66934eSEric Dumazet 
244e66934eSEric Dumazet #ifdef CONFIG_REF_TRACKER
25b6d7c0ebSAndrzej Hajda 
ref_tracker_dir_init(struct ref_tracker_dir * dir,unsigned int quarantine_count,const char * name)264e66934eSEric Dumazet static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
27b6d7c0ebSAndrzej Hajda 					unsigned int quarantine_count,
28b6d7c0ebSAndrzej Hajda 					const char *name)
294e66934eSEric Dumazet {
304e66934eSEric Dumazet 	INIT_LIST_HEAD(&dir->list);
314e66934eSEric Dumazet 	INIT_LIST_HEAD(&dir->quarantine);
324e66934eSEric Dumazet 	spin_lock_init(&dir->lock);
334e66934eSEric Dumazet 	dir->quarantine_avail = quarantine_count;
34e3ececfeSEric Dumazet 	dir->dead = false;
354e66934eSEric Dumazet 	refcount_set(&dir->untracked, 1);
368fd5522fSEric Dumazet 	refcount_set(&dir->no_tracker, 1);
37b6d7c0ebSAndrzej Hajda 	strscpy(dir->name, name, sizeof(dir->name));
382dba5eb1SVlastimil Babka 	stack_depot_init();
394e66934eSEric Dumazet }
404e66934eSEric Dumazet 
414e66934eSEric Dumazet void ref_tracker_dir_exit(struct ref_tracker_dir *dir);
424e66934eSEric Dumazet 
437a113ff6SAndrzej Hajda void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
447a113ff6SAndrzej Hajda 				  unsigned int display_limit);
457a113ff6SAndrzej Hajda 
464e66934eSEric Dumazet void ref_tracker_dir_print(struct ref_tracker_dir *dir,
474e66934eSEric Dumazet 			   unsigned int display_limit);
484e66934eSEric Dumazet 
49*227c6c83SAndrzej Hajda int ref_tracker_dir_snprint(struct ref_tracker_dir *dir, char *buf, size_t size);
50*227c6c83SAndrzej Hajda 
514e66934eSEric Dumazet int ref_tracker_alloc(struct ref_tracker_dir *dir,
524e66934eSEric Dumazet 		      struct ref_tracker **trackerp, gfp_t gfp);
534e66934eSEric Dumazet 
544e66934eSEric Dumazet int ref_tracker_free(struct ref_tracker_dir *dir,
554e66934eSEric Dumazet 		     struct ref_tracker **trackerp);
564e66934eSEric Dumazet 
574e66934eSEric Dumazet #else /* CONFIG_REF_TRACKER */
584e66934eSEric Dumazet 
ref_tracker_dir_init(struct ref_tracker_dir * dir,unsigned int quarantine_count,const char * name)594e66934eSEric Dumazet static inline void ref_tracker_dir_init(struct ref_tracker_dir *dir,
60b6d7c0ebSAndrzej Hajda 					unsigned int quarantine_count,
61b6d7c0ebSAndrzej Hajda 					const char *name)
624e66934eSEric Dumazet {
634e66934eSEric Dumazet }
644e66934eSEric Dumazet 
ref_tracker_dir_exit(struct ref_tracker_dir * dir)654e66934eSEric Dumazet static inline void ref_tracker_dir_exit(struct ref_tracker_dir *dir)
664e66934eSEric Dumazet {
674e66934eSEric Dumazet }
684e66934eSEric Dumazet 
ref_tracker_dir_print_locked(struct ref_tracker_dir * dir,unsigned int display_limit)697a113ff6SAndrzej Hajda static inline void ref_tracker_dir_print_locked(struct ref_tracker_dir *dir,
707a113ff6SAndrzej Hajda 						unsigned int display_limit)
717a113ff6SAndrzej Hajda {
727a113ff6SAndrzej Hajda }
737a113ff6SAndrzej Hajda 
ref_tracker_dir_print(struct ref_tracker_dir * dir,unsigned int display_limit)744e66934eSEric Dumazet static inline void ref_tracker_dir_print(struct ref_tracker_dir *dir,
754e66934eSEric Dumazet 					 unsigned int display_limit)
764e66934eSEric Dumazet {
774e66934eSEric Dumazet }
784e66934eSEric Dumazet 
ref_tracker_dir_snprint(struct ref_tracker_dir * dir,char * buf,size_t size)79*227c6c83SAndrzej Hajda static inline int ref_tracker_dir_snprint(struct ref_tracker_dir *dir,
80*227c6c83SAndrzej Hajda 					  char *buf, size_t size)
81*227c6c83SAndrzej Hajda {
82*227c6c83SAndrzej Hajda 	return 0;
83*227c6c83SAndrzej Hajda }
84*227c6c83SAndrzej Hajda 
ref_tracker_alloc(struct ref_tracker_dir * dir,struct ref_tracker ** trackerp,gfp_t gfp)854e66934eSEric Dumazet static inline int ref_tracker_alloc(struct ref_tracker_dir *dir,
864e66934eSEric Dumazet 				    struct ref_tracker **trackerp,
874e66934eSEric Dumazet 				    gfp_t gfp)
884e66934eSEric Dumazet {
894e66934eSEric Dumazet 	return 0;
904e66934eSEric Dumazet }
914e66934eSEric Dumazet 
ref_tracker_free(struct ref_tracker_dir * dir,struct ref_tracker ** trackerp)924e66934eSEric Dumazet static inline int ref_tracker_free(struct ref_tracker_dir *dir,
934e66934eSEric Dumazet 				   struct ref_tracker **trackerp)
944e66934eSEric Dumazet {
954e66934eSEric Dumazet 	return 0;
964e66934eSEric Dumazet }
974e66934eSEric Dumazet 
984e66934eSEric Dumazet #endif
994e66934eSEric Dumazet 
1004e66934eSEric Dumazet #endif /* _LINUX_REF_TRACKER_H */
101