xref: /haiku/headers/private/kernel/vm/VMCache.h (revision 4e2b49bc0ca2550a538c5f12d893e208b909217a)
1e50cf876SIngo Weinhold /*
2be7328a9SIngo Weinhold  * Copyright 2008-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3e50cf876SIngo Weinhold  * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de.
4e50cf876SIngo Weinhold  * Distributed under the terms of the MIT License.
5e50cf876SIngo Weinhold  *
6e50cf876SIngo Weinhold  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7e50cf876SIngo Weinhold  * Distributed under the terms of the NewOS License.
8e50cf876SIngo Weinhold  */
9e50cf876SIngo Weinhold #ifndef _KERNEL_VM_VM_CACHE_H
10e50cf876SIngo Weinhold #define _KERNEL_VM_VM_CACHE_H
11e50cf876SIngo Weinhold 
12e50cf876SIngo Weinhold 
13355dc6beSIngo Weinhold #include <debug.h>
14e50cf876SIngo Weinhold #include <kernel.h>
15f8154d17SIngo Weinhold #include <util/DoublyLinkedList.h>
16e50cf876SIngo Weinhold #include <vm/vm.h>
17be7328a9SIngo Weinhold #include <vm/vm_types.h>
18be7328a9SIngo Weinhold 
19be7328a9SIngo Weinhold #include "kernel_debug_config.h"
20e50cf876SIngo Weinhold 
21e50cf876SIngo Weinhold 
22e50cf876SIngo Weinhold struct kernel_args;
2330c9d3c0SAugustin Cavalier struct ObjectCache;
24e50cf876SIngo Weinhold 
25e50cf876SIngo Weinhold 
26be7328a9SIngo Weinhold enum {
27be7328a9SIngo Weinhold 	CACHE_TYPE_RAM = 0,
28be7328a9SIngo Weinhold 	CACHE_TYPE_VNODE,
29be7328a9SIngo Weinhold 	CACHE_TYPE_DEVICE,
30be7328a9SIngo Weinhold 	CACHE_TYPE_NULL
31be7328a9SIngo Weinhold };
32be7328a9SIngo Weinhold 
33522c2f19SIngo Weinhold enum {
34522c2f19SIngo Weinhold 	PAGE_EVENT_NOT_BUSY	= 0x01		// page not busy anymore
35522c2f19SIngo Weinhold };
36522c2f19SIngo Weinhold 
37522c2f19SIngo Weinhold 
38f8154d17SIngo Weinhold extern ObjectCache* gCacheRefObjectCache;
39f8154d17SIngo Weinhold extern ObjectCache* gAnonymousCacheObjectCache;
40f8154d17SIngo Weinhold extern ObjectCache* gAnonymousNoSwapCacheObjectCache;
41f8154d17SIngo Weinhold extern ObjectCache* gVnodeCacheObjectCache;
42f8154d17SIngo Weinhold extern ObjectCache* gDeviceCacheObjectCache;
43f8154d17SIngo Weinhold extern ObjectCache* gNullCacheObjectCache;
44f8154d17SIngo Weinhold 
45f8154d17SIngo Weinhold 
46be7328a9SIngo Weinhold struct VMCachePagesTreeDefinition {
47be7328a9SIngo Weinhold 	typedef page_num_t KeyType;
48be7328a9SIngo Weinhold 	typedef	vm_page NodeType;
49be7328a9SIngo Weinhold 
50be7328a9SIngo Weinhold 	static page_num_t GetKey(const NodeType* node)
51be7328a9SIngo Weinhold 	{
52be7328a9SIngo Weinhold 		return node->cache_offset;
53be7328a9SIngo Weinhold 	}
54be7328a9SIngo Weinhold 
55be7328a9SIngo Weinhold 	static SplayTreeLink<NodeType>* GetLink(NodeType* node)
56be7328a9SIngo Weinhold 	{
57be7328a9SIngo Weinhold 		return &node->cache_link;
58be7328a9SIngo Weinhold 	}
59be7328a9SIngo Weinhold 
60be7328a9SIngo Weinhold 	static int Compare(page_num_t key, const NodeType* node)
61be7328a9SIngo Weinhold 	{
62be7328a9SIngo Weinhold 		return key == node->cache_offset ? 0
63be7328a9SIngo Weinhold 			: (key < node->cache_offset ? -1 : 1);
64be7328a9SIngo Weinhold 	}
65be7328a9SIngo Weinhold 
66be7328a9SIngo Weinhold 	static NodeType** GetListLink(NodeType* node)
67be7328a9SIngo Weinhold 	{
68be7328a9SIngo Weinhold 		return &node->cache_next;
69be7328a9SIngo Weinhold 	}
70be7328a9SIngo Weinhold };
71be7328a9SIngo Weinhold 
72be7328a9SIngo Weinhold typedef IteratableSplayTree<VMCachePagesTreeDefinition> VMCachePagesTree;
73be7328a9SIngo Weinhold 
746379e53eSIngo Weinhold 
75f8154d17SIngo Weinhold struct VMCache : public DoublyLinkedListLinkImpl<VMCache> {
76f8154d17SIngo Weinhold public:
77f8154d17SIngo Weinhold 	typedef DoublyLinkedList<VMCache> ConsumerList;
78f8154d17SIngo Weinhold 
79be7328a9SIngo Weinhold public:
80be7328a9SIngo Weinhold 								VMCache();
81be7328a9SIngo Weinhold 	virtual						~VMCache();
82be7328a9SIngo Weinhold 
83deee8524SIngo Weinhold 			status_t			Init(uint32 cacheType, uint32 allocationFlags);
84be7328a9SIngo Weinhold 
85be7328a9SIngo Weinhold 	virtual	void				Delete();
86be7328a9SIngo Weinhold 
87355dc6beSIngo Weinhold 	inline	bool				Lock();
88355dc6beSIngo Weinhold 	inline	bool				TryLock();
89355dc6beSIngo Weinhold 	inline	bool				SwitchLock(mutex* from);
9077690f28SIngo Weinhold 	inline	bool				SwitchFromReadLock(rw_lock* from);
913632eeedSIngo Weinhold 			void				Unlock(bool consumerLocked = false);
92355dc6beSIngo Weinhold 	inline	void				AssertLocked();
93be7328a9SIngo Weinhold 
94355dc6beSIngo Weinhold 	inline	void				AcquireRefLocked();
95355dc6beSIngo Weinhold 	inline	void				AcquireRef();
96355dc6beSIngo Weinhold 	inline	void				ReleaseRefLocked();
97355dc6beSIngo Weinhold 	inline	void				ReleaseRef();
983632eeedSIngo Weinhold 	inline	void				ReleaseRefAndUnlock(
993632eeedSIngo Weinhold 									bool consumerLocked = false);
100be7328a9SIngo Weinhold 
101cf99b9abSIngo Weinhold 	inline	VMCacheRef*			CacheRef() const	{ return fCacheRef; }
102cf99b9abSIngo Weinhold 
103522c2f19SIngo Weinhold 			void				WaitForPageEvents(vm_page* page, uint32 events,
104522c2f19SIngo Weinhold 									bool relock);
105522c2f19SIngo Weinhold 			void				NotifyPageEvents(vm_page* page, uint32 events)
106522c2f19SIngo Weinhold 									{ if (fPageEventWaiters != NULL)
107522c2f19SIngo Weinhold 										_NotifyPageEvents(page, events); }
10872382fa6SIngo Weinhold 	inline	void				MarkPageUnbusy(vm_page* page);
109522c2f19SIngo Weinhold 
110be7328a9SIngo Weinhold 			vm_page*			LookupPage(off_t offset);
111be7328a9SIngo Weinhold 			void				InsertPage(vm_page* page, off_t offset);
112be7328a9SIngo Weinhold 			void				RemovePage(vm_page* page);
113c6657ffeSHamish Morrison 			void				MovePage(vm_page* page, off_t offset);
114eb8dc1ebSIngo Weinhold 			void				MovePage(vm_page* page);
115eb8dc1ebSIngo Weinhold 			void				MoveAllPages(VMCache* fromCache);
116be7328a9SIngo Weinhold 
117b9447668SIngo Weinhold 	inline	page_num_t			WiredPagesCount() const;
118b9447668SIngo Weinhold 	inline	void				IncrementWiredPagesCount();
119b9447668SIngo Weinhold 	inline	void				DecrementWiredPagesCount();
120b9447668SIngo Weinhold 
121d1f280c8SHamish Morrison 	virtual	int32				GuardSize()	{ return 0; }
122d1f280c8SHamish Morrison 
123be7328a9SIngo Weinhold 			void				AddConsumer(VMCache* consumer);
124be7328a9SIngo Weinhold 
125be7328a9SIngo Weinhold 			status_t			InsertAreaLocked(VMArea* area);
126be7328a9SIngo Weinhold 			status_t			RemoveArea(VMArea* area);
1272e74d74fSIngo Weinhold 			void				TransferAreas(VMCache* fromCache);
1282e74d74fSIngo Weinhold 			uint32				CountWritableAreas(VMArea* ignoreArea) const;
129be7328a9SIngo Weinhold 
130be7328a9SIngo Weinhold 			status_t			WriteModified();
131cff6e9e4SIngo Weinhold 			status_t			SetMinimalCommitment(off_t commitment,
132cff6e9e4SIngo Weinhold 									int priority);
133efeca209SIngo Weinhold 	virtual	status_t			Resize(off_t newSize, int priority);
134c6657ffeSHamish Morrison 	virtual	status_t			Rebase(off_t newBase, int priority);
135*4e2b49bcSMichael Lotz 	virtual	status_t			Adopt(VMCache* source, off_t offset, off_t size,
136*4e2b49bcSMichael Lotz 									off_t newOffset);
137be7328a9SIngo Weinhold 
138be7328a9SIngo Weinhold 			status_t			FlushAndRemoveAllPages();
139be7328a9SIngo Weinhold 
1403632eeedSIngo Weinhold 			void*				UserData()	{ return fUserData; }
1413632eeedSIngo Weinhold 			void				SetUserData(void* data)	{ fUserData = data; }
1423632eeedSIngo Weinhold 									// Settable by the lock owner and valid as
1433632eeedSIngo Weinhold 									// long as the lock is owned.
1443632eeedSIngo Weinhold 
145be7328a9SIngo Weinhold 			// for debugging only
146be7328a9SIngo Weinhold 			int32				RefCount() const
147be7328a9SIngo Weinhold 									{ return fRefCount; }
148be7328a9SIngo Weinhold 
149be7328a9SIngo Weinhold 	// backing store operations
150cff6e9e4SIngo Weinhold 	virtual	status_t			Commit(off_t size, int priority);
151be7328a9SIngo Weinhold 	virtual	bool				HasPage(off_t offset);
152be7328a9SIngo Weinhold 
153435c43f5SIngo Weinhold 	virtual	status_t			Read(off_t offset, const generic_io_vec *vecs,
1546440406aSIngo Weinhold 									size_t count, uint32 flags,
155435c43f5SIngo Weinhold 									generic_size_t *_numBytes);
156435c43f5SIngo Weinhold 	virtual	status_t			Write(off_t offset, const generic_io_vec *vecs,
157435c43f5SIngo Weinhold 									size_t count, uint32 flags,
158435c43f5SIngo Weinhold 									generic_size_t *_numBytes);
159435c43f5SIngo Weinhold 	virtual	status_t			WriteAsync(off_t offset,
160435c43f5SIngo Weinhold 									const generic_io_vec* vecs, size_t count,
161435c43f5SIngo Weinhold 									generic_size_t numBytes, uint32 flags,
162be7328a9SIngo Weinhold 									AsyncIOCallback* callback);
163be7328a9SIngo Weinhold 	virtual	bool				CanWritePage(off_t offset);
164be7328a9SIngo Weinhold 
165be7328a9SIngo Weinhold 	virtual	int32				MaxPagesPerWrite() const
166be7328a9SIngo Weinhold 									{ return -1; } // no restriction
167be7328a9SIngo Weinhold 	virtual	int32				MaxPagesPerAsyncWrite() const
168be7328a9SIngo Weinhold 									{ return -1; } // no restriction
169be7328a9SIngo Weinhold 
170be7328a9SIngo Weinhold 	virtual	status_t			Fault(struct VMAddressSpace *aspace,
171be7328a9SIngo Weinhold 									off_t offset);
172be7328a9SIngo Weinhold 
173be7328a9SIngo Weinhold 	virtual	void				Merge(VMCache* source);
174be7328a9SIngo Weinhold 
175be7328a9SIngo Weinhold 	virtual	status_t			AcquireUnreferencedStoreRef();
176be7328a9SIngo Weinhold 	virtual	void				AcquireStoreRef();
177be7328a9SIngo Weinhold 	virtual	void				ReleaseStoreRef();
178be7328a9SIngo Weinhold 
17986875ad9SIngo Weinhold 	virtual	bool				DebugHasPage(off_t offset);
18086875ad9SIngo Weinhold 			vm_page*			DebugLookupPage(off_t offset);
18186875ad9SIngo Weinhold 
182f8e263c1SIngo Weinhold 	virtual	void				Dump(bool showPages) const;
183f8e263c1SIngo Weinhold 
184f8154d17SIngo Weinhold protected:
185f8154d17SIngo Weinhold 	virtual	void				DeleteObject() = 0;
186f8154d17SIngo Weinhold 
187be7328a9SIngo Weinhold public:
1886440406aSIngo Weinhold 			VMArea*				areas;
189f8154d17SIngo Weinhold 			ConsumerList		consumers;
190be7328a9SIngo Weinhold 				// list of caches that use this cache as a source
191be7328a9SIngo Weinhold 			VMCachePagesTree	pages;
192be7328a9SIngo Weinhold 			VMCache*			source;
193be7328a9SIngo Weinhold 			off_t				virtual_base;
194be7328a9SIngo Weinhold 			off_t				virtual_end;
195be7328a9SIngo Weinhold 			off_t				committed_size;
196be7328a9SIngo Weinhold 				// TODO: Remove!
197be7328a9SIngo Weinhold 			uint32				page_count;
198be7328a9SIngo Weinhold 			uint32				temporary : 1;
199be7328a9SIngo Weinhold 			uint32				type : 6;
200be7328a9SIngo Weinhold 
201be7328a9SIngo Weinhold #if DEBUG_CACHE_LIST
2026440406aSIngo Weinhold 			VMCache*			debug_previous;
2036440406aSIngo Weinhold 			VMCache*			debug_next;
204be7328a9SIngo Weinhold #endif
205be7328a9SIngo Weinhold 
206be7328a9SIngo Weinhold private:
207522c2f19SIngo Weinhold 			struct PageEventWaiter;
2086379e53eSIngo Weinhold 			friend struct VMCacheRef;
209522c2f19SIngo Weinhold 
210522c2f19SIngo Weinhold private:
211522c2f19SIngo Weinhold 			void				_NotifyPageEvents(vm_page* page, uint32 events);
212522c2f19SIngo Weinhold 
2136440406aSIngo Weinhold 	inline	bool				_IsMergeable() const;
2146440406aSIngo Weinhold 
215a0d93d14SIngo Weinhold 			void				_MergeWithOnlyConsumer();
2166440406aSIngo Weinhold 			void				_RemoveConsumer(VMCache* consumer);
2176440406aSIngo Weinhold 
2186440406aSIngo Weinhold private:
219be7328a9SIngo Weinhold 			int32				fRefCount;
220be7328a9SIngo Weinhold 			mutex				fLock;
221522c2f19SIngo Weinhold 			PageEventWaiter*	fPageEventWaiters;
2223632eeedSIngo Weinhold 			void*				fUserData;
2236379e53eSIngo Weinhold 			VMCacheRef*			fCacheRef;
224b9447668SIngo Weinhold 			page_num_t			fWiredPagesCount;
225be7328a9SIngo Weinhold };
226be7328a9SIngo Weinhold 
227be7328a9SIngo Weinhold 
228be7328a9SIngo Weinhold #if DEBUG_CACHE_LIST
229be7328a9SIngo Weinhold extern VMCache* gDebugCacheList;
230be7328a9SIngo Weinhold #endif
231be7328a9SIngo Weinhold 
232be7328a9SIngo Weinhold 
233be7328a9SIngo Weinhold class VMCacheFactory {
234be7328a9SIngo Weinhold public:
235be7328a9SIngo Weinhold 	static	status_t		CreateAnonymousCache(VMCache*& cache,
236be7328a9SIngo Weinhold 								bool canOvercommit, int32 numPrecommittedPages,
237cff6e9e4SIngo Weinhold 								int32 numGuardPages, bool swappable,
238cff6e9e4SIngo Weinhold 								int priority);
239be7328a9SIngo Weinhold 	static	status_t		CreateVnodeCache(VMCache*& cache,
240be7328a9SIngo Weinhold 								struct vnode* vnode);
241be7328a9SIngo Weinhold 	static	status_t		CreateDeviceCache(VMCache*& cache,
242be7328a9SIngo Weinhold 								addr_t baseAddress);
243cff6e9e4SIngo Weinhold 	static	status_t		CreateNullCache(int priority, VMCache*& cache);
244be7328a9SIngo Weinhold };
245be7328a9SIngo Weinhold 
246be7328a9SIngo Weinhold 
247355dc6beSIngo Weinhold 
248355dc6beSIngo Weinhold bool
249355dc6beSIngo Weinhold VMCache::Lock()
250355dc6beSIngo Weinhold {
251355dc6beSIngo Weinhold 	return mutex_lock(&fLock) == B_OK;
252355dc6beSIngo Weinhold }
253355dc6beSIngo Weinhold 
254355dc6beSIngo Weinhold 
255355dc6beSIngo Weinhold bool
256355dc6beSIngo Weinhold VMCache::TryLock()
257355dc6beSIngo Weinhold {
258355dc6beSIngo Weinhold 	return mutex_trylock(&fLock) == B_OK;
259355dc6beSIngo Weinhold }
260355dc6beSIngo Weinhold 
261355dc6beSIngo Weinhold 
262355dc6beSIngo Weinhold bool
263355dc6beSIngo Weinhold VMCache::SwitchLock(mutex* from)
264355dc6beSIngo Weinhold {
265355dc6beSIngo Weinhold 	return mutex_switch_lock(from, &fLock) == B_OK;
266355dc6beSIngo Weinhold }
267355dc6beSIngo Weinhold 
268355dc6beSIngo Weinhold 
26977690f28SIngo Weinhold bool
27077690f28SIngo Weinhold VMCache::SwitchFromReadLock(rw_lock* from)
27177690f28SIngo Weinhold {
27277690f28SIngo Weinhold 	return mutex_switch_from_read_lock(from, &fLock) == B_OK;
27377690f28SIngo Weinhold }
27477690f28SIngo Weinhold 
27577690f28SIngo Weinhold 
276355dc6beSIngo Weinhold void
277355dc6beSIngo Weinhold VMCache::AssertLocked()
278355dc6beSIngo Weinhold {
279355dc6beSIngo Weinhold 	ASSERT_LOCKED_MUTEX(&fLock);
280355dc6beSIngo Weinhold }
281355dc6beSIngo Weinhold 
282355dc6beSIngo Weinhold 
283355dc6beSIngo Weinhold void
284355dc6beSIngo Weinhold VMCache::AcquireRefLocked()
285355dc6beSIngo Weinhold {
286355dc6beSIngo Weinhold 	ASSERT_LOCKED_MUTEX(&fLock);
287355dc6beSIngo Weinhold 
288355dc6beSIngo Weinhold 	fRefCount++;
289355dc6beSIngo Weinhold }
290355dc6beSIngo Weinhold 
291355dc6beSIngo Weinhold 
292355dc6beSIngo Weinhold void
293355dc6beSIngo Weinhold VMCache::AcquireRef()
294355dc6beSIngo Weinhold {
295355dc6beSIngo Weinhold 	Lock();
296355dc6beSIngo Weinhold 	fRefCount++;
297355dc6beSIngo Weinhold 	Unlock();
298355dc6beSIngo Weinhold }
299355dc6beSIngo Weinhold 
300355dc6beSIngo Weinhold 
301355dc6beSIngo Weinhold void
302355dc6beSIngo Weinhold VMCache::ReleaseRefLocked()
303355dc6beSIngo Weinhold {
304355dc6beSIngo Weinhold 	ASSERT_LOCKED_MUTEX(&fLock);
305355dc6beSIngo Weinhold 
306355dc6beSIngo Weinhold 	fRefCount--;
307355dc6beSIngo Weinhold }
308355dc6beSIngo Weinhold 
309355dc6beSIngo Weinhold 
310355dc6beSIngo Weinhold void
311355dc6beSIngo Weinhold VMCache::ReleaseRef()
312355dc6beSIngo Weinhold {
313355dc6beSIngo Weinhold 	Lock();
314355dc6beSIngo Weinhold 	fRefCount--;
315355dc6beSIngo Weinhold 	Unlock();
316355dc6beSIngo Weinhold }
317355dc6beSIngo Weinhold 
318355dc6beSIngo Weinhold 
319355dc6beSIngo Weinhold void
3203632eeedSIngo Weinhold VMCache::ReleaseRefAndUnlock(bool consumerLocked)
321355dc6beSIngo Weinhold {
322355dc6beSIngo Weinhold 	ReleaseRefLocked();
3233632eeedSIngo Weinhold 	Unlock(consumerLocked);
324355dc6beSIngo Weinhold }
325355dc6beSIngo Weinhold 
326355dc6beSIngo Weinhold 
32772382fa6SIngo Weinhold void
32872382fa6SIngo Weinhold VMCache::MarkPageUnbusy(vm_page* page)
32972382fa6SIngo Weinhold {
3304bb4f793SIngo Weinhold 	ASSERT(page->busy);
33172382fa6SIngo Weinhold 	page->busy = false;
33272382fa6SIngo Weinhold 	NotifyPageEvents(page, PAGE_EVENT_NOT_BUSY);
33372382fa6SIngo Weinhold }
33472382fa6SIngo Weinhold 
33572382fa6SIngo Weinhold 
336b9447668SIngo Weinhold page_num_t
337b9447668SIngo Weinhold VMCache::WiredPagesCount() const
338b9447668SIngo Weinhold {
339b9447668SIngo Weinhold 	return fWiredPagesCount;
340b9447668SIngo Weinhold }
341b9447668SIngo Weinhold 
342b9447668SIngo Weinhold 
343b9447668SIngo Weinhold void
344b9447668SIngo Weinhold VMCache::IncrementWiredPagesCount()
345b9447668SIngo Weinhold {
346b9447668SIngo Weinhold 	ASSERT(fWiredPagesCount < page_count);
347b9447668SIngo Weinhold 
348b9447668SIngo Weinhold 	fWiredPagesCount++;
349b9447668SIngo Weinhold }
350b9447668SIngo Weinhold 
351b9447668SIngo Weinhold 
352b9447668SIngo Weinhold void
353b9447668SIngo Weinhold VMCache::DecrementWiredPagesCount()
354b9447668SIngo Weinhold {
355b9447668SIngo Weinhold 	ASSERT(fWiredPagesCount > 0);
356b9447668SIngo Weinhold 
357b9447668SIngo Weinhold 	fWiredPagesCount--;
358b9447668SIngo Weinhold }
359b9447668SIngo Weinhold 
360b9447668SIngo Weinhold 
361b9447668SIngo Weinhold // vm_page methods implemented here to avoid VMCache.h inclusion in vm_types.h
362b9447668SIngo Weinhold 
363b9447668SIngo Weinhold inline void
364b9447668SIngo Weinhold vm_page::IncrementWiredCount()
365b9447668SIngo Weinhold {
366b9447668SIngo Weinhold 	if (fWiredCount++ == 0)
367b9447668SIngo Weinhold 		cache_ref->cache->IncrementWiredPagesCount();
368b9447668SIngo Weinhold }
369b9447668SIngo Weinhold 
370b9447668SIngo Weinhold 
371b9447668SIngo Weinhold inline void
372b9447668SIngo Weinhold vm_page::DecrementWiredCount()
373b9447668SIngo Weinhold {
3742cdd33d4SMichael Lotz 	ASSERT(fWiredCount > 0);
3752cdd33d4SMichael Lotz 
376b9447668SIngo Weinhold 	if (--fWiredCount == 0)
377b9447668SIngo Weinhold 		cache_ref->cache->DecrementWiredPagesCount();
378b9447668SIngo Weinhold }
379b9447668SIngo Weinhold 
380b9447668SIngo Weinhold 
381e50cf876SIngo Weinhold #ifdef __cplusplus
382e50cf876SIngo Weinhold extern "C" {
383e50cf876SIngo Weinhold #endif
384e50cf876SIngo Weinhold 
385e50cf876SIngo Weinhold status_t vm_cache_init(struct kernel_args *args);
3862e74d74fSIngo Weinhold void vm_cache_init_post_heap();
387e50cf876SIngo Weinhold struct VMCache *vm_cache_acquire_locked_page_cache(struct vm_page *page,
388e50cf876SIngo Weinhold 	bool dontWait);
389e50cf876SIngo Weinhold 
390e50cf876SIngo Weinhold #ifdef __cplusplus
391e50cf876SIngo Weinhold }
392e50cf876SIngo Weinhold #endif
393e50cf876SIngo Weinhold 
394be7328a9SIngo Weinhold 
395e50cf876SIngo Weinhold #endif	/* _KERNEL_VM_VM_CACHE_H */
396