VirtualBox

source: vbox/trunk/src/VBox/VMM/include/PDMBlkCacheInternal.h@ 74442

Last change on this file since 74442 was 70778, checked in by vboxsync, 7 years ago

VMM/PDMBlkCache: Commit some debug code for tracing I/O requests I had lying around for debug purposes (disabled by default)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.5 KB
Line 
1/* $Id: PDMBlkCacheInternal.h 70778 2018-01-28 22:09:24Z vboxsync $ */
2/** @file
3 * PDM Block Cache.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___PDMBlkCacheInternal_h
19#define ___PDMBlkCacheInternal_h
20
21#include <VBox/vmm/cfgm.h>
22#include <VBox/vmm/stam.h>
23#include <VBox/vmm/tm.h>
24#include <VBox/vmm/pdmblkcache.h>
25#include <iprt/types.h>
26#include <iprt/file.h>
27#include <iprt/thread.h>
28#include <iprt/semaphore.h>
29#include <iprt/critsect.h>
30#include <iprt/avl.h>
31#include <iprt/list.h>
32#include <iprt/spinlock.h>
33#include <iprt/memcache.h>
34
35RT_C_DECLS_BEGIN
36
37/**
38 * A few forward declarations.
39 */
40/** Pointer to a cache LRU list. */
41typedef struct PDMBLKLRULIST *PPDMBLKLRULIST;
42/** Pointer to the global cache structure. */
43typedef struct PDMBLKCACHEGLOBAL *PPDMBLKCACHEGLOBAL;
44/** Pointer to a cache entry waiter structure. */
45typedef struct PDMBLKCACHEWAITER *PPDMBLKCACHEWAITER;
46
47/**
48 * A cache entry
49 */
50typedef struct PDMBLKCACHEENTRY
51{
52 /** The AVL entry data. */
53 AVLRU64NODECORE Core;
54 /** Pointer to the previous element. Used in one of the LRU lists.*/
55 struct PDMBLKCACHEENTRY *pPrev;
56 /** Pointer to the next element. Used in one of the LRU lists.*/
57 struct PDMBLKCACHEENTRY *pNext;
58 /** Pointer to the list the entry is in. */
59 PPDMBLKLRULIST pList;
60 /** Cache the entry belongs to. */
61 PPDMBLKCACHE pBlkCache;
62 /** Flags for this entry. Combinations of PDMACFILECACHE_* \#defines */
63 volatile uint32_t fFlags;
64 /** Reference counter. Prevents eviction of the entry if > 0. */
65 volatile uint32_t cRefs;
66 /** Size of the entry. */
67 uint32_t cbData;
68 /** Pointer to the memory containing the data. */
69 uint8_t *pbData;
70 /** Head of list of tasks waiting for this one to finish. */
71 PPDMBLKCACHEWAITER pWaitingHead;
72 /** Tail of list of tasks waiting for this one to finish. */
73 PPDMBLKCACHEWAITER pWaitingTail;
74 /** Node for dirty but not yet committed entries list per endpoint. */
75 RTLISTNODE NodeNotCommitted;
76} PDMBLKCACHEENTRY, *PPDMBLKCACHEENTRY;
77/** I/O is still in progress for this entry. This entry is not evictable. */
78#define PDMBLKCACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
79/** Entry is locked and thus not evictable. */
80#define PDMBLKCACHE_ENTRY_LOCKED RT_BIT(1)
81/** Entry is dirty */
82#define PDMBLKCACHE_ENTRY_IS_DIRTY RT_BIT(2)
83/** Entry is not evictable. */
84#define PDMBLKCACHE_NOT_EVICTABLE (PDMBLKCACHE_ENTRY_LOCKED | PDMBLKCACHE_ENTRY_IO_IN_PROGRESS | PDMBLKCACHE_ENTRY_IS_DIRTY)
85
86/**
87 * LRU list data
88 */
89typedef struct PDMBLKLRULIST
90{
91 /** Head of the list. */
92 PPDMBLKCACHEENTRY pHead;
93 /** Tail of the list. */
94 PPDMBLKCACHEENTRY pTail;
95 /** Number of bytes cached in the list. */
96 uint32_t cbCached;
97} PDMBLKLRULIST;
98
99/**
100 * Global cache data.
101 */
102typedef struct PDMBLKCACHEGLOBAL
103{
104 /** Pointer to the owning VM instance. */
105 PVM pVM;
106 /** Maximum size of the cache in bytes. */
107 uint32_t cbMax;
108 /** Current size of the cache in bytes. */
109 uint32_t cbCached;
110 /** Critical section protecting the cache. */
111 RTCRITSECT CritSect;
112 /** Maximum number of bytes cached. */
113 uint32_t cbRecentlyUsedInMax;
114 /** Maximum number of bytes in the paged out list .*/
115 uint32_t cbRecentlyUsedOutMax;
116 /** Recently used cache entries list */
117 PDMBLKLRULIST LruRecentlyUsedIn;
118 /** Scorecard cache entry list. */
119 PDMBLKLRULIST LruRecentlyUsedOut;
120 /** List of frequently used cache entries */
121 PDMBLKLRULIST LruFrequentlyUsed;
122 /** Commit timeout in milli seconds */
123 uint32_t u32CommitTimeoutMs;
124 /** Number of dirty bytes needed to start a commit of the data to the disk. */
125 uint32_t cbCommitDirtyThreshold;
126 /** Current number of dirty bytes in the cache. */
127 volatile uint32_t cbDirty;
128 /** Flag whether the VM was suspended becaus of an I/O error. */
129 volatile bool fIoErrorVmSuspended;
130 /** Flag whether a commit is currently in progress. */
131 volatile bool fCommitInProgress;
132 /** Commit interval timer */
133 PTMTIMERR3 pTimerCommit;
134 /** Number of endpoints using the cache. */
135 uint32_t cRefs;
136 /** List of all users of this cache. */
137 RTLISTANCHOR ListUsers;
138#ifdef VBOX_WITH_STATISTICS
139 /** Hit counter. */
140 STAMCOUNTER cHits;
141 /** Partial hit counter. */
142 STAMCOUNTER cPartialHits;
143 /** Miss counter. */
144 STAMCOUNTER cMisses;
145 /** Bytes read from cache. */
146 STAMCOUNTER StatRead;
147 /** Bytes written to the cache. */
148 STAMCOUNTER StatWritten;
149 /** Time spend to get an entry in the AVL tree. */
150 STAMPROFILEADV StatTreeGet;
151 /** Time spend to insert an entry in the AVL tree. */
152 STAMPROFILEADV StatTreeInsert;
153 /** Time spend to remove an entry in the AVL tree. */
154 STAMPROFILEADV StatTreeRemove;
155 /** Number of times a buffer could be reused. */
156 STAMCOUNTER StatBuffersReused;
157#endif
158} PDMBLKCACHEGLOBAL;
159#ifdef VBOX_WITH_STATISTICS
160AssertCompileMemberAlignment(PDMBLKCACHEGLOBAL, cHits, sizeof(uint64_t));
161#endif
162
163/**
164 * Block cache type.
165 */
166typedef enum PDMBLKCACHETYPE
167{
168 /** Device . */
169 PDMBLKCACHETYPE_DEV = 1,
170 /** Driver consumer. */
171 PDMBLKCACHETYPE_DRV,
172 /** Internal consumer. */
173 PDMBLKCACHETYPE_INTERNAL,
174 /** Usb consumer. */
175 PDMBLKCACHETYPE_USB
176} PDMBLKCACHETYPE;
177
178/**
179 * Per user cache data.
180 */
181typedef struct PDMBLKCACHE
182{
183 /** Pointer to the id for the cache. */
184 char *pszId;
185 /** AVL tree managing cache entries. */
186 PAVLRU64TREE pTree;
187 /** R/W semaphore protecting cached entries for this endpoint. */
188 RTSEMRW SemRWEntries;
189 /** Pointer to the gobal cache data */
190 PPDMBLKCACHEGLOBAL pCache;
191 /** Lock protecting the dirty entries list. */
192 RTSPINLOCK LockList;
193 /** List of dirty but not committed entries for this endpoint. */
194 RTLISTANCHOR ListDirtyNotCommitted;
195 /** Node of the cache user list. */
196 RTLISTNODE NodeCacheUser;
197 /** Block cache type. */
198 PDMBLKCACHETYPE enmType;
199 /** Type specific data. */
200 union
201 {
202 /** PDMASYNCCOMPLETIONTEMPLATETYPE_DEV */
203 struct
204 {
205 /** Pointer to the device instance owning the block cache. */
206 R3PTRTYPE(PPDMDEVINS) pDevIns;
207 /** Complete callback to the user. */
208 R3PTRTYPE(PFNPDMBLKCACHEXFERCOMPLETEDEV) pfnXferComplete;
209 /** I/O enqueue callback. */
210 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDEV) pfnXferEnqueue;
211 /** Discard enqueue callback. */
212 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDISCARDDEV) pfnXferEnqueueDiscard;
213 } Dev;
214 /** PDMASYNCCOMPLETIONTEMPLATETYPE_DRV */
215 struct
216 {
217 /** Pointer to the driver instance owning the block cache. */
218 R3PTRTYPE(PPDMDRVINS) pDrvIns;
219 /** Complete callback to the user. */
220 R3PTRTYPE(PFNPDMBLKCACHEXFERCOMPLETEDRV) pfnXferComplete;
221 /** I/O enqueue callback. */
222 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDRV) pfnXferEnqueue;
223 /** Discard enqueue callback. */
224 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDISCARDDRV) pfnXferEnqueueDiscard;
225 } Drv;
226 /** PDMASYNCCOMPLETIONTEMPLATETYPE_INTERNAL */
227 struct
228 {
229 /** Pointer to user data. */
230 R3PTRTYPE(void *) pvUser;
231 /** Complete callback to the user. */
232 R3PTRTYPE(PFNPDMBLKCACHEXFERCOMPLETEINT) pfnXferComplete;
233 /** I/O enqueue callback. */
234 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEINT) pfnXferEnqueue;
235 /** Discard enqueue callback. */
236 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDISCARDINT) pfnXferEnqueueDiscard;
237 } Int;
238 /** PDMASYNCCOMPLETIONTEMPLATETYPE_USB */
239 struct
240 {
241 /** Pointer to the usb instance owning the template. */
242 R3PTRTYPE(PPDMUSBINS) pUsbIns;
243 /** Complete callback to the user. */
244 R3PTRTYPE(PFNPDMBLKCACHEXFERCOMPLETEUSB) pfnXferComplete;
245 /** I/O enqueue callback. */
246 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEUSB) pfnXferEnqueue;
247 /** Discard enqueue callback. */
248 R3PTRTYPE(PFNPDMBLKCACHEXFERENQUEUEDISCARDUSB) pfnXferEnqueueDiscard;
249 } Usb;
250 } u;
251
252#ifdef VBOX_WITH_STATISTICS
253
254#if HC_ARCH_BITS == 64
255 uint32_t u32Alignment;
256#endif
257 /** Number of times a write was deferred because the cache entry was still in progress */
258 STAMCOUNTER StatWriteDeferred;
259 /** Number appended cache entries. */
260 STAMCOUNTER StatAppendedWrites;
261#endif
262
263 /** Flag whether the cache was suspended. */
264 volatile bool fSuspended;
265 /** Number of outstanding I/O transfers. */
266 volatile uint32_t cIoXfersActive;
267
268} PDMBLKCACHE, *PPDMBLKCACHE;
269#ifdef VBOX_WITH_STATISTICS
270AssertCompileMemberAlignment(PDMBLKCACHE, StatWriteDeferred, sizeof(uint64_t));
271#endif
272
273/**
274 * I/O task.
275 */
276typedef struct PDMBLKCACHEREQ
277{
278 /** Opaque user data returned on completion. */
279 void *pvUser;
280 /** Number of pending transfers (waiting for a cache entry and passed through). */
281 volatile uint32_t cXfersPending;
282 /** Status code. */
283 volatile int rcReq;
284} PDMBLKCACHEREQ, *PPDMBLKCACHEREQ;
285
286/**
287 * I/O transfer from the cache to the underlying medium.
288 */
289typedef struct PDMBLKCACHEIOXFER
290{
291 /** Flag whether the I/O xfer updates a cache entry or updates the request directly. */
292 bool fIoCache;
293 /** Type dependent data. */
294 union
295 {
296 /** Pointer to the entry the transfer updates. */
297 PPDMBLKCACHEENTRY pEntry;
298 /** Pointer to the request the transfer updates. */
299 PPDMBLKCACHEREQ pReq;
300 };
301 /** Transfer direction. */
302 PDMBLKCACHEXFERDIR enmXferDir;
303 /** Segment used if a cache entry is updated. */
304 RTSGSEG SgSeg;
305 /** S/G buffer. */
306 RTSGBUF SgBuf;
307} PDMBLKCACHEIOXFER;
308
309/**
310 * Cache waiter
311 */
312typedef struct PDMBLKCACHEWAITER
313{
314 /* Next waiter in the list. */
315 struct PDMBLKCACHEWAITER *pNext;
316 /** S/G buffer holding or receiving data. */
317 RTSGBUF SgBuf;
318 /** Offset into the cache entry to start the transfer. */
319 uint32_t offCacheEntry;
320 /** How many bytes to transfer. */
321 size_t cbTransfer;
322 /** Flag whether the task wants to read or write into the entry. */
323 bool fWrite;
324 /** Task the waiter is for. */
325 PPDMBLKCACHEREQ pReq;
326} PDMBLKCACHEWAITER;
327
328RT_C_DECLS_END
329
330#endif
331
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette