xref: /openbmc/linux/fs/fscache/internal.h (revision 52beb1fc)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /* Internal definitions for FS-Cache
3  *
4  * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5  * Written by David Howells (dhowells@redhat.com)
6  */
7 
8 #ifdef pr_fmt
9 #undef pr_fmt
10 #endif
11 
12 #define pr_fmt(fmt) "FS-Cache: " fmt
13 
14 #include <linux/slab.h>
15 #include <linux/fscache-cache.h>
16 #include <trace/events/fscache.h>
17 #include <linux/sched.h>
18 #include <linux/seq_file.h>
19 
20 /*
21  * cache.c
22  */
23 #ifdef CONFIG_PROC_FS
24 extern const struct seq_operations fscache_caches_seq_ops;
25 #endif
26 bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
27 void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
28 struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache);
29 void fscache_put_cache(struct fscache_cache *cache, enum fscache_cache_trace where);
30 
31 static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache)
32 {
33 	return smp_load_acquire(&cache->state);
34 }
35 
36 static inline bool fscache_cache_is_live(const struct fscache_cache *cache)
37 {
38 	return fscache_cache_state(cache) == FSCACHE_CACHE_IS_ACTIVE;
39 }
40 
41 static inline void fscache_set_cache_state(struct fscache_cache *cache,
42 					   enum fscache_cache_state new_state)
43 {
44 	smp_store_release(&cache->state, new_state);
45 
46 }
47 
48 static inline bool fscache_set_cache_state_maybe(struct fscache_cache *cache,
49 						 enum fscache_cache_state old_state,
50 						 enum fscache_cache_state new_state)
51 {
52 	return try_cmpxchg_release(&cache->state, &old_state, new_state);
53 }
54 
55 /*
56  * cookie.c
57  */
58 extern struct kmem_cache *fscache_cookie_jar;
59 extern const struct seq_operations fscache_cookies_seq_ops;
60 extern struct timer_list fscache_cookie_lru_timer;
61 
62 extern void fscache_print_cookie(struct fscache_cookie *cookie, char prefix);
63 extern bool fscache_begin_cookie_access(struct fscache_cookie *cookie,
64 					enum fscache_access_trace why);
65 
66 static inline void fscache_see_cookie(struct fscache_cookie *cookie,
67 				      enum fscache_cookie_trace where)
68 {
69 	trace_fscache_cookie(cookie->debug_id, refcount_read(&cookie->ref),
70 			     where);
71 }
72 
73 /*
74  * io.c
75  */
76 static inline void fscache_end_operation(struct netfs_cache_resources *cres)
77 {
78 	const struct netfs_cache_ops *ops = fscache_operation_valid(cres);
79 
80 	if (ops)
81 		ops->end_operation(cres);
82 }
83 
84 /*
85  * main.c
86  */
87 extern unsigned fscache_debug;
88 
89 extern unsigned int fscache_hash(unsigned int salt, const void *data, size_t len);
90 
91 /*
92  * proc.c
93  */
94 #ifdef CONFIG_PROC_FS
95 extern int __init fscache_proc_init(void);
96 extern void fscache_proc_cleanup(void);
97 #else
98 #define fscache_proc_init()	(0)
99 #define fscache_proc_cleanup()	do {} while (0)
100 #endif
101 
102 /*
103  * stats.c
104  */
105 #ifdef CONFIG_FSCACHE_STATS
106 extern atomic_t fscache_n_volumes;
107 extern atomic_t fscache_n_volumes_collision;
108 extern atomic_t fscache_n_volumes_nomem;
109 extern atomic_t fscache_n_cookies;
110 extern atomic_t fscache_n_cookies_lru;
111 extern atomic_t fscache_n_cookies_lru_expired;
112 extern atomic_t fscache_n_cookies_lru_removed;
113 extern atomic_t fscache_n_cookies_lru_dropped;
114 
115 extern atomic_t fscache_n_acquires;
116 extern atomic_t fscache_n_acquires_ok;
117 extern atomic_t fscache_n_acquires_oom;
118 
119 extern atomic_t fscache_n_invalidates;
120 
121 extern atomic_t fscache_n_relinquishes;
122 extern atomic_t fscache_n_relinquishes_retire;
123 extern atomic_t fscache_n_relinquishes_dropped;
124 
125 extern atomic_t fscache_n_resizes;
126 extern atomic_t fscache_n_resizes_null;
127 
128 static inline void fscache_stat(atomic_t *stat)
129 {
130 	atomic_inc(stat);
131 }
132 
133 static inline void fscache_stat_d(atomic_t *stat)
134 {
135 	atomic_dec(stat);
136 }
137 
138 #define __fscache_stat(stat) (stat)
139 
140 int fscache_stats_show(struct seq_file *m, void *v);
141 #else
142 
143 #define __fscache_stat(stat) (NULL)
144 #define fscache_stat(stat) do {} while (0)
145 #define fscache_stat_d(stat) do {} while (0)
146 #endif
147 
148 /*
149  * volume.c
150  */
151 extern const struct seq_operations fscache_volumes_seq_ops;
152 
153 struct fscache_volume *fscache_get_volume(struct fscache_volume *volume,
154 					  enum fscache_volume_trace where);
155 void fscache_put_volume(struct fscache_volume *volume,
156 			enum fscache_volume_trace where);
157 bool fscache_begin_volume_access(struct fscache_volume *volume,
158 				 struct fscache_cookie *cookie,
159 				 enum fscache_access_trace why);
160 void fscache_create_volume(struct fscache_volume *volume, bool wait);
161 
162 
163 /*****************************************************************************/
164 /*
165  * debug tracing
166  */
167 #define dbgprintk(FMT, ...) \
168 	printk("[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
169 
170 #define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
171 #define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
172 #define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
173 
174 #define kjournal(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
175 
176 #ifdef __KDEBUG
177 #define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
178 #define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
179 #define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
180 
181 #elif defined(CONFIG_FSCACHE_DEBUG)
182 #define _enter(FMT, ...)			\
183 do {						\
184 	if (__do_kdebug(ENTER))			\
185 		kenter(FMT, ##__VA_ARGS__);	\
186 } while (0)
187 
188 #define _leave(FMT, ...)			\
189 do {						\
190 	if (__do_kdebug(LEAVE))			\
191 		kleave(FMT, ##__VA_ARGS__);	\
192 } while (0)
193 
194 #define _debug(FMT, ...)			\
195 do {						\
196 	if (__do_kdebug(DEBUG))			\
197 		kdebug(FMT, ##__VA_ARGS__);	\
198 } while (0)
199 
200 #else
201 #define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
202 #define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
203 #define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
204 #endif
205 
206 /*
207  * determine whether a particular optional debugging point should be logged
208  * - we need to go through three steps to persuade cpp to correctly join the
209  *   shorthand in FSCACHE_DEBUG_LEVEL with its prefix
210  */
211 #define ____do_kdebug(LEVEL, POINT) \
212 	unlikely((fscache_debug & \
213 		  (FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3))))
214 #define ___do_kdebug(LEVEL, POINT) \
215 	____do_kdebug(LEVEL, POINT)
216 #define __do_kdebug(POINT) \
217 	___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT)
218 
219 #define FSCACHE_DEBUG_CACHE	0
220 #define FSCACHE_DEBUG_COOKIE	1
221 #define FSCACHE_DEBUG_OBJECT	2
222 #define FSCACHE_DEBUG_OPERATION	3
223 
224 #define FSCACHE_POINT_ENTER	1
225 #define FSCACHE_POINT_LEAVE	2
226 #define FSCACHE_POINT_DEBUG	4
227 
228 #ifndef FSCACHE_DEBUG_LEVEL
229 #define FSCACHE_DEBUG_LEVEL CACHE
230 #endif
231 
232 /*
233  * assertions
234  */
235 #if 1 /* defined(__KDEBUGALL) */
236 
237 #define ASSERT(X)							\
238 do {									\
239 	if (unlikely(!(X))) {						\
240 		pr_err("\n");					\
241 		pr_err("Assertion failed\n");	\
242 		BUG();							\
243 	}								\
244 } while (0)
245 
246 #define ASSERTCMP(X, OP, Y)						\
247 do {									\
248 	if (unlikely(!((X) OP (Y)))) {					\
249 		pr_err("\n");					\
250 		pr_err("Assertion failed\n");	\
251 		pr_err("%lx " #OP " %lx is false\n",		\
252 		       (unsigned long)(X), (unsigned long)(Y));		\
253 		BUG();							\
254 	}								\
255 } while (0)
256 
257 #define ASSERTIF(C, X)							\
258 do {									\
259 	if (unlikely((C) && !(X))) {					\
260 		pr_err("\n");					\
261 		pr_err("Assertion failed\n");	\
262 		BUG();							\
263 	}								\
264 } while (0)
265 
266 #define ASSERTIFCMP(C, X, OP, Y)					\
267 do {									\
268 	if (unlikely((C) && !((X) OP (Y)))) {				\
269 		pr_err("\n");					\
270 		pr_err("Assertion failed\n");	\
271 		pr_err("%lx " #OP " %lx is false\n",		\
272 		       (unsigned long)(X), (unsigned long)(Y));		\
273 		BUG();							\
274 	}								\
275 } while (0)
276 
277 #else
278 
279 #define ASSERT(X)			do {} while (0)
280 #define ASSERTCMP(X, OP, Y)		do {} while (0)
281 #define ASSERTIF(C, X)			do {} while (0)
282 #define ASSERTIFCMP(C, X, OP, Y)	do {} while (0)
283 
284 #endif /* assert or not */
285