xref: /openbmc/linux/fs/fscache/internal.h (revision 19517e53)
11e1236b8SDavid Howells /* SPDX-License-Identifier: GPL-2.0-or-later */
21e1236b8SDavid Howells /* Internal definitions for FS-Cache
31e1236b8SDavid Howells  *
41e1236b8SDavid Howells  * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
51e1236b8SDavid Howells  * Written by David Howells (dhowells@redhat.com)
61e1236b8SDavid Howells  */
71e1236b8SDavid Howells 
81e1236b8SDavid Howells #ifdef pr_fmt
91e1236b8SDavid Howells #undef pr_fmt
101e1236b8SDavid Howells #endif
111e1236b8SDavid Howells 
121e1236b8SDavid Howells #define pr_fmt(fmt) "FS-Cache: " fmt
131e1236b8SDavid Howells 
141e1236b8SDavid Howells #include <linux/slab.h>
151e1236b8SDavid Howells #include <linux/fscache-cache.h>
161e1236b8SDavid Howells #include <trace/events/fscache.h>
171e1236b8SDavid Howells #include <linux/sched.h>
181e1236b8SDavid Howells #include <linux/seq_file.h>
191e1236b8SDavid Howells 
201e1236b8SDavid Howells /*
219549332dSDavid Howells  * cache.c
229549332dSDavid Howells  */
239549332dSDavid Howells #ifdef CONFIG_PROC_FS
249549332dSDavid Howells extern const struct seq_operations fscache_caches_seq_ops;
259549332dSDavid Howells #endif
2623e12e28SDavid Howells bool fscache_begin_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
2723e12e28SDavid Howells void fscache_end_cache_access(struct fscache_cache *cache, enum fscache_access_trace why);
289549332dSDavid Howells struct fscache_cache *fscache_lookup_cache(const char *name, bool is_cache);
299549332dSDavid Howells void fscache_put_cache(struct fscache_cache *cache, enum fscache_cache_trace where);
309549332dSDavid Howells 
fscache_cache_state(const struct fscache_cache * cache)319549332dSDavid Howells static inline enum fscache_cache_state fscache_cache_state(const struct fscache_cache *cache)
329549332dSDavid Howells {
339549332dSDavid Howells 	return smp_load_acquire(&cache->state);
349549332dSDavid Howells }
359549332dSDavid Howells 
fscache_cache_is_live(const struct fscache_cache * cache)369549332dSDavid Howells static inline bool fscache_cache_is_live(const struct fscache_cache *cache)
379549332dSDavid Howells {
389549332dSDavid Howells 	return fscache_cache_state(cache) == FSCACHE_CACHE_IS_ACTIVE;
399549332dSDavid Howells }
409549332dSDavid Howells 
fscache_set_cache_state(struct fscache_cache * cache,enum fscache_cache_state new_state)419549332dSDavid Howells static inline void fscache_set_cache_state(struct fscache_cache *cache,
429549332dSDavid Howells 					   enum fscache_cache_state new_state)
439549332dSDavid Howells {
449549332dSDavid Howells 	smp_store_release(&cache->state, new_state);
459549332dSDavid Howells 
469549332dSDavid Howells }
479549332dSDavid Howells 
fscache_set_cache_state_maybe(struct fscache_cache * cache,enum fscache_cache_state old_state,enum fscache_cache_state new_state)489549332dSDavid Howells static inline bool fscache_set_cache_state_maybe(struct fscache_cache *cache,
499549332dSDavid Howells 						 enum fscache_cache_state old_state,
509549332dSDavid Howells 						 enum fscache_cache_state new_state)
519549332dSDavid Howells {
529549332dSDavid Howells 	return try_cmpxchg_release(&cache->state, &old_state, new_state);
539549332dSDavid Howells }
549549332dSDavid Howells 
559549332dSDavid Howells /*
567f3283abSDavid Howells  * cookie.c
577f3283abSDavid Howells  */
587f3283abSDavid Howells extern struct kmem_cache *fscache_cookie_jar;
59*19517e53SYue Hu #ifdef CONFIG_PROC_FS
607f3283abSDavid Howells extern const struct seq_operations fscache_cookies_seq_ops;
61*19517e53SYue Hu #endif
6212bb21a2SDavid Howells extern struct timer_list fscache_cookie_lru_timer;
637f3283abSDavid Howells 
647f3283abSDavid Howells extern void fscache_print_cookie(struct fscache_cookie *cookie, char prefix);
65a7733fb6SDavid Howells extern bool fscache_begin_cookie_access(struct fscache_cookie *cookie,
66a7733fb6SDavid Howells 					enum fscache_access_trace why);
67a7733fb6SDavid Howells 
fscache_see_cookie(struct fscache_cookie * cookie,enum fscache_cookie_trace where)687f3283abSDavid Howells static inline void fscache_see_cookie(struct fscache_cookie *cookie,
697f3283abSDavid Howells 				      enum fscache_cookie_trace where)
707f3283abSDavid Howells {
717f3283abSDavid Howells 	trace_fscache_cookie(cookie->debug_id, refcount_read(&cookie->ref),
727f3283abSDavid Howells 			     where);
737f3283abSDavid Howells }
747f3283abSDavid Howells 
757f3283abSDavid Howells /*
761e1236b8SDavid Howells  * main.c
771e1236b8SDavid Howells  */
781e1236b8SDavid Howells extern unsigned fscache_debug;
791e1236b8SDavid Howells 
80e8a07c9dSDavid Howells extern unsigned int fscache_hash(unsigned int salt, const void *data, size_t len);
81e8a07c9dSDavid Howells 
821e1236b8SDavid Howells /*
831e1236b8SDavid Howells  * proc.c
841e1236b8SDavid Howells  */
851e1236b8SDavid Howells #ifdef CONFIG_PROC_FS
861e1236b8SDavid Howells extern int __init fscache_proc_init(void);
871e1236b8SDavid Howells extern void fscache_proc_cleanup(void);
881e1236b8SDavid Howells #else
891e1236b8SDavid Howells #define fscache_proc_init()	(0)
901e1236b8SDavid Howells #define fscache_proc_cleanup()	do {} while (0)
911e1236b8SDavid Howells #endif
921e1236b8SDavid Howells 
931e1236b8SDavid Howells /*
941e1236b8SDavid Howells  * stats.c
951e1236b8SDavid Howells  */
961e1236b8SDavid Howells #ifdef CONFIG_FSCACHE_STATS
9762ab6335SDavid Howells extern atomic_t fscache_n_volumes;
9862ab6335SDavid Howells extern atomic_t fscache_n_volumes_collision;
9962ab6335SDavid Howells extern atomic_t fscache_n_volumes_nomem;
1007f3283abSDavid Howells extern atomic_t fscache_n_cookies;
10112bb21a2SDavid Howells extern atomic_t fscache_n_cookies_lru;
10212bb21a2SDavid Howells extern atomic_t fscache_n_cookies_lru_expired;
10312bb21a2SDavid Howells extern atomic_t fscache_n_cookies_lru_removed;
10412bb21a2SDavid Howells extern atomic_t fscache_n_cookies_lru_dropped;
1057f3283abSDavid Howells 
1067f3283abSDavid Howells extern atomic_t fscache_n_acquires;
1077f3283abSDavid Howells extern atomic_t fscache_n_acquires_ok;
1087f3283abSDavid Howells extern atomic_t fscache_n_acquires_oom;
1097f3283abSDavid Howells 
110d24af13eSDavid Howells extern atomic_t fscache_n_invalidates;
111d24af13eSDavid Howells 
1127f3283abSDavid Howells extern atomic_t fscache_n_relinquishes;
1137f3283abSDavid Howells extern atomic_t fscache_n_relinquishes_retire;
1147f3283abSDavid Howells extern atomic_t fscache_n_relinquishes_dropped;
1151e1236b8SDavid Howells 
11616a96bdfSDavid Howells extern atomic_t fscache_n_resizes;
11716a96bdfSDavid Howells extern atomic_t fscache_n_resizes_null;
11816a96bdfSDavid Howells 
fscache_stat(atomic_t * stat)1191e1236b8SDavid Howells static inline void fscache_stat(atomic_t *stat)
1201e1236b8SDavid Howells {
1211e1236b8SDavid Howells 	atomic_inc(stat);
1221e1236b8SDavid Howells }
1231e1236b8SDavid Howells 
fscache_stat_d(atomic_t * stat)1241e1236b8SDavid Howells static inline void fscache_stat_d(atomic_t *stat)
1251e1236b8SDavid Howells {
1261e1236b8SDavid Howells 	atomic_dec(stat);
1271e1236b8SDavid Howells }
1281e1236b8SDavid Howells 
1291e1236b8SDavid Howells #define __fscache_stat(stat) (stat)
1301e1236b8SDavid Howells 
1311e1236b8SDavid Howells int fscache_stats_show(struct seq_file *m, void *v);
1321e1236b8SDavid Howells #else
1331e1236b8SDavid Howells 
1341e1236b8SDavid Howells #define __fscache_stat(stat) (NULL)
1351e1236b8SDavid Howells #define fscache_stat(stat) do {} while (0)
1361e1236b8SDavid Howells #define fscache_stat_d(stat) do {} while (0)
1371e1236b8SDavid Howells #endif
1381e1236b8SDavid Howells 
13962ab6335SDavid Howells /*
14062ab6335SDavid Howells  * volume.c
14162ab6335SDavid Howells  */
142*19517e53SYue Hu #ifdef CONFIG_PROC_FS
14362ab6335SDavid Howells extern const struct seq_operations fscache_volumes_seq_ops;
144*19517e53SYue Hu #endif
14562ab6335SDavid Howells 
14662ab6335SDavid Howells struct fscache_volume *fscache_get_volume(struct fscache_volume *volume,
14762ab6335SDavid Howells 					  enum fscache_volume_trace where);
14862ab6335SDavid Howells void fscache_put_volume(struct fscache_volume *volume,
14962ab6335SDavid Howells 			enum fscache_volume_trace where);
150e6acd329SDavid Howells bool fscache_begin_volume_access(struct fscache_volume *volume,
151e6acd329SDavid Howells 				 struct fscache_cookie *cookie,
152e6acd329SDavid Howells 				 enum fscache_access_trace why);
15362ab6335SDavid Howells void fscache_create_volume(struct fscache_volume *volume, bool wait);
15462ab6335SDavid Howells 
1551e1236b8SDavid Howells 
1561e1236b8SDavid Howells /*****************************************************************************/
1571e1236b8SDavid Howells /*
1581e1236b8SDavid Howells  * debug tracing
1591e1236b8SDavid Howells  */
1601e1236b8SDavid Howells #define dbgprintk(FMT, ...) \
1611e1236b8SDavid Howells 	printk("[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
1621e1236b8SDavid Howells 
1631e1236b8SDavid Howells #define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
1641e1236b8SDavid Howells #define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
1651e1236b8SDavid Howells #define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
1661e1236b8SDavid Howells 
1671e1236b8SDavid Howells #define kjournal(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
1681e1236b8SDavid Howells 
1691e1236b8SDavid Howells #ifdef __KDEBUG
1701e1236b8SDavid Howells #define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
1711e1236b8SDavid Howells #define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
1721e1236b8SDavid Howells #define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
1731e1236b8SDavid Howells 
1741e1236b8SDavid Howells #elif defined(CONFIG_FSCACHE_DEBUG)
1751e1236b8SDavid Howells #define _enter(FMT, ...)			\
1761e1236b8SDavid Howells do {						\
1771e1236b8SDavid Howells 	if (__do_kdebug(ENTER))			\
1781e1236b8SDavid Howells 		kenter(FMT, ##__VA_ARGS__);	\
1791e1236b8SDavid Howells } while (0)
1801e1236b8SDavid Howells 
1811e1236b8SDavid Howells #define _leave(FMT, ...)			\
1821e1236b8SDavid Howells do {						\
1831e1236b8SDavid Howells 	if (__do_kdebug(LEAVE))			\
1841e1236b8SDavid Howells 		kleave(FMT, ##__VA_ARGS__);	\
1851e1236b8SDavid Howells } while (0)
1861e1236b8SDavid Howells 
1871e1236b8SDavid Howells #define _debug(FMT, ...)			\
1881e1236b8SDavid Howells do {						\
1891e1236b8SDavid Howells 	if (__do_kdebug(DEBUG))			\
1901e1236b8SDavid Howells 		kdebug(FMT, ##__VA_ARGS__);	\
1911e1236b8SDavid Howells } while (0)
1921e1236b8SDavid Howells 
1931e1236b8SDavid Howells #else
1941e1236b8SDavid Howells #define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
1951e1236b8SDavid Howells #define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
1961e1236b8SDavid Howells #define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
1971e1236b8SDavid Howells #endif
1981e1236b8SDavid Howells 
1991e1236b8SDavid Howells /*
2001e1236b8SDavid Howells  * determine whether a particular optional debugging point should be logged
2011e1236b8SDavid Howells  * - we need to go through three steps to persuade cpp to correctly join the
2021e1236b8SDavid Howells  *   shorthand in FSCACHE_DEBUG_LEVEL with its prefix
2031e1236b8SDavid Howells  */
2041e1236b8SDavid Howells #define ____do_kdebug(LEVEL, POINT) \
2051e1236b8SDavid Howells 	unlikely((fscache_debug & \
2061e1236b8SDavid Howells 		  (FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3))))
2071e1236b8SDavid Howells #define ___do_kdebug(LEVEL, POINT) \
2081e1236b8SDavid Howells 	____do_kdebug(LEVEL, POINT)
2091e1236b8SDavid Howells #define __do_kdebug(POINT) \
2101e1236b8SDavid Howells 	___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT)
2111e1236b8SDavid Howells 
2121e1236b8SDavid Howells #define FSCACHE_DEBUG_CACHE	0
2131e1236b8SDavid Howells #define FSCACHE_DEBUG_COOKIE	1
2141e1236b8SDavid Howells #define FSCACHE_DEBUG_OBJECT	2
2151e1236b8SDavid Howells #define FSCACHE_DEBUG_OPERATION	3
2161e1236b8SDavid Howells 
2171e1236b8SDavid Howells #define FSCACHE_POINT_ENTER	1
2181e1236b8SDavid Howells #define FSCACHE_POINT_LEAVE	2
2191e1236b8SDavid Howells #define FSCACHE_POINT_DEBUG	4
2201e1236b8SDavid Howells 
2211e1236b8SDavid Howells #ifndef FSCACHE_DEBUG_LEVEL
2221e1236b8SDavid Howells #define FSCACHE_DEBUG_LEVEL CACHE
2231e1236b8SDavid Howells #endif
2241e1236b8SDavid Howells 
2251e1236b8SDavid Howells /*
2261e1236b8SDavid Howells  * assertions
2271e1236b8SDavid Howells  */
2281e1236b8SDavid Howells #if 1 /* defined(__KDEBUGALL) */
2291e1236b8SDavid Howells 
2301e1236b8SDavid Howells #define ASSERT(X)							\
2311e1236b8SDavid Howells do {									\
2321e1236b8SDavid Howells 	if (unlikely(!(X))) {						\
2331e1236b8SDavid Howells 		pr_err("\n");					\
2341e1236b8SDavid Howells 		pr_err("Assertion failed\n");	\
2351e1236b8SDavid Howells 		BUG();							\
2361e1236b8SDavid Howells 	}								\
2371e1236b8SDavid Howells } while (0)
2381e1236b8SDavid Howells 
2391e1236b8SDavid Howells #define ASSERTCMP(X, OP, Y)						\
2401e1236b8SDavid Howells do {									\
2411e1236b8SDavid Howells 	if (unlikely(!((X) OP (Y)))) {					\
2421e1236b8SDavid Howells 		pr_err("\n");					\
2431e1236b8SDavid Howells 		pr_err("Assertion failed\n");	\
2441e1236b8SDavid Howells 		pr_err("%lx " #OP " %lx is false\n",		\
2451e1236b8SDavid Howells 		       (unsigned long)(X), (unsigned long)(Y));		\
2461e1236b8SDavid Howells 		BUG();							\
2471e1236b8SDavid Howells 	}								\
2481e1236b8SDavid Howells } while (0)
2491e1236b8SDavid Howells 
2501e1236b8SDavid Howells #define ASSERTIF(C, X)							\
2511e1236b8SDavid Howells do {									\
2521e1236b8SDavid Howells 	if (unlikely((C) && !(X))) {					\
2531e1236b8SDavid Howells 		pr_err("\n");					\
2541e1236b8SDavid Howells 		pr_err("Assertion failed\n");	\
2551e1236b8SDavid Howells 		BUG();							\
2561e1236b8SDavid Howells 	}								\
2571e1236b8SDavid Howells } while (0)
2581e1236b8SDavid Howells 
2591e1236b8SDavid Howells #define ASSERTIFCMP(C, X, OP, Y)					\
2601e1236b8SDavid Howells do {									\
2611e1236b8SDavid Howells 	if (unlikely((C) && !((X) OP (Y)))) {				\
2621e1236b8SDavid Howells 		pr_err("\n");					\
2631e1236b8SDavid Howells 		pr_err("Assertion failed\n");	\
2641e1236b8SDavid Howells 		pr_err("%lx " #OP " %lx is false\n",		\
2651e1236b8SDavid Howells 		       (unsigned long)(X), (unsigned long)(Y));		\
2661e1236b8SDavid Howells 		BUG();							\
2671e1236b8SDavid Howells 	}								\
2681e1236b8SDavid Howells } while (0)
2691e1236b8SDavid Howells 
2701e1236b8SDavid Howells #else
2711e1236b8SDavid Howells 
2721e1236b8SDavid Howells #define ASSERT(X)			do {} while (0)
2731e1236b8SDavid Howells #define ASSERTCMP(X, OP, Y)		do {} while (0)
2741e1236b8SDavid Howells #define ASSERTIF(C, X)			do {} while (0)
2751e1236b8SDavid Howells #define ASSERTIFCMP(C, X, OP, Y)	do {} while (0)
2761e1236b8SDavid Howells 
2771e1236b8SDavid Howells #endif /* assert or not */
278