Merge tag 'for-linus-hexagon-6.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel...
[linux.git] / mm / zpdesc.h
blobfa47fece22372e9a283ec2f7b8aba30b9904c6dd
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* zpdesc.h: zswap.zpool memory descriptor
4 * Written by Alex Shi <alexs@kernel.org>
5 * Hyeonggon Yoo <42.hyeyoo@gmail.com>
6 */
7 #ifndef __MM_ZPDESC_H__
8 #define __MM_ZPDESC_H__
11 * struct zpdesc - Memory descriptor for zpool memory.
12 * @flags: Page flags, mostly unused by zsmalloc.
13 * @lru: Indirectly used by page migration.
14 * @movable_ops: Used by page migration.
15 * @next: Next zpdesc in a zspage in zsmalloc zpool.
16 * @handle: For huge zspage in zsmalloc zpool.
17 * @zspage: Points to the zspage this zpdesc is a part of.
18 * @first_obj_offset: First object offset in zsmalloc zpool.
19 * @_refcount: The number of references to this zpdesc.
21 * This struct overlays struct page for now. Do not modify without a good
22 * understanding of the issues. In particular, do not expand into the overlap
23 * with memcg_data.
25 * Page flags used:
26 * * PG_private identifies the first component page.
27 * * PG_locked is used by page migration code.
29 struct zpdesc {
30 unsigned long flags;
31 struct list_head lru;
32 unsigned long movable_ops;
33 union {
34 struct zpdesc *next;
35 unsigned long handle;
37 struct zspage *zspage;
39 * Only the lower 24 bits are available for offset, limiting a page
40 * to 16 MiB. The upper 8 bits are reserved for PGTY_zsmalloc.
42 * Do not access this field directly.
43 * Instead, use {get,set}_first_obj_offset() helpers.
45 unsigned int first_obj_offset;
46 atomic_t _refcount;
48 #define ZPDESC_MATCH(pg, zp) \
49 static_assert(offsetof(struct page, pg) == offsetof(struct zpdesc, zp))
51 ZPDESC_MATCH(flags, flags);
52 ZPDESC_MATCH(lru, lru);
53 ZPDESC_MATCH(mapping, movable_ops);
54 ZPDESC_MATCH(index, next);
55 ZPDESC_MATCH(index, handle);
56 ZPDESC_MATCH(private, zspage);
57 ZPDESC_MATCH(page_type, first_obj_offset);
58 ZPDESC_MATCH(_refcount, _refcount);
59 #undef ZPDESC_MATCH
60 static_assert(sizeof(struct zpdesc) <= sizeof(struct page));
63 * zpdesc_page - The first struct page allocated for a zpdesc
64 * @zp: The zpdesc.
66 * A convenience wrapper for converting zpdesc to the first struct page of the
67 * underlying folio, to communicate with code not yet converted to folio or
68 * struct zpdesc.
71 #define zpdesc_page(zp) (_Generic((zp), \
72 const struct zpdesc *: (const struct page *)(zp), \
73 struct zpdesc *: (struct page *)(zp)))
75 /**
76 * zpdesc_folio - The folio allocated for a zpdesc
77 * @zp: The zpdesc.
79 * Zpdescs are descriptors for zpool memory. The zpool memory itself is
80 * allocated as folios that contain the zpool objects, and zpdesc uses specific
81 * fields in the first struct page of the folio - those fields are now accessed
82 * by struct zpdesc.
84 * It is occasionally necessary convert to back to a folio in order to
85 * communicate with the rest of the mm. Please use this helper function
86 * instead of casting yourself, as the implementation may change in the future.
88 #define zpdesc_folio(zp) (_Generic((zp), \
89 const struct zpdesc *: (const struct folio *)(zp), \
90 struct zpdesc *: (struct folio *)(zp)))
91 /**
92 * page_zpdesc - Converts from first struct page to zpdesc.
93 * @p: The first (either head of compound or single) page of zpdesc.
95 * A temporary wrapper to convert struct page to struct zpdesc in situations
96 * where we know the page is the compound head, or single order-0 page.
98 * Long-term ideally everything would work with struct zpdesc directly or go
99 * through folio to struct zpdesc.
101 * Return: The zpdesc which contains this page
103 #define page_zpdesc(p) (_Generic((p), \
104 const struct page *: (const struct zpdesc *)(p), \
105 struct page *: (struct zpdesc *)(p)))
107 static inline void zpdesc_lock(struct zpdesc *zpdesc)
109 folio_lock(zpdesc_folio(zpdesc));
112 static inline bool zpdesc_trylock(struct zpdesc *zpdesc)
114 return folio_trylock(zpdesc_folio(zpdesc));
117 static inline void zpdesc_unlock(struct zpdesc *zpdesc)
119 folio_unlock(zpdesc_folio(zpdesc));
122 static inline void zpdesc_wait_locked(struct zpdesc *zpdesc)
124 folio_wait_locked(zpdesc_folio(zpdesc));
127 static inline void zpdesc_get(struct zpdesc *zpdesc)
129 folio_get(zpdesc_folio(zpdesc));
132 static inline void zpdesc_put(struct zpdesc *zpdesc)
134 folio_put(zpdesc_folio(zpdesc));
137 static inline void *kmap_local_zpdesc(struct zpdesc *zpdesc)
139 return kmap_local_page(zpdesc_page(zpdesc));
142 static inline unsigned long zpdesc_pfn(struct zpdesc *zpdesc)
144 return page_to_pfn(zpdesc_page(zpdesc));
147 static inline struct zpdesc *pfn_zpdesc(unsigned long pfn)
149 return page_zpdesc(pfn_to_page(pfn));
152 static inline void __zpdesc_set_movable(struct zpdesc *zpdesc,
153 const struct movable_operations *mops)
155 __SetPageMovable(zpdesc_page(zpdesc), mops);
158 static inline void __zpdesc_set_zsmalloc(struct zpdesc *zpdesc)
160 __SetPageZsmalloc(zpdesc_page(zpdesc));
163 static inline void __zpdesc_clear_zsmalloc(struct zpdesc *zpdesc)
165 __ClearPageZsmalloc(zpdesc_page(zpdesc));
168 static inline bool zpdesc_is_isolated(struct zpdesc *zpdesc)
170 return PageIsolated(zpdesc_page(zpdesc));
173 static inline struct zone *zpdesc_zone(struct zpdesc *zpdesc)
175 return page_zone(zpdesc_page(zpdesc));
178 static inline bool zpdesc_is_locked(struct zpdesc *zpdesc)
180 return folio_test_locked(zpdesc_folio(zpdesc));
182 #endif