VirtualBox

source: vbox/trunk/src/VBox/VMM/PDMAsyncCompletionFileInternal.h@ 27454

Last change on this file since 27454 was 27299, checked in by vboxsync, 15 years ago

AsyncCompletion: More configuration options

  • There are two manager types which can be selected with CFGM with the "IoMgr" key:

-- Async - I/O is done asynchronously using the capabilities on the host (Default)
-- Simple - Used as a fallback if "Async" doesn't work. Normally selected automatically

if the async type encounters an error

  • Two types for a file backend selected by the "FileBackend" CFGM key. (The I/O cache of VirtualBox is unaffected by this setting):

-- Buffered - The I/O goes through the host cache (Default on all hosts except Linux)
-- NonBuffered - The host cache is disabled

  • The following combinations of the two options are supported:

-- Async/NonBuffered
-- Simple/Buffered
-- Async/Buffered (not supported on Linux because of kernel limitations)

  • The Async/Buffered combination is optimized now (no need to align the transfer to sector boundaries)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.1 KB
Line 
1/* $Id: PDMAsyncCompletionFileInternal.h 27299 2010-03-11 19:19:59Z vboxsync $ */
2/** @file
3 * PDM Async I/O - Transport data asynchronous in R3 using EMT.
4 */
5
6/*
7 * Copyright (C) 2006-2008 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___PDMAsyncCompletionFileInternal_h
23#define ___PDMAsyncCompletionFileInternal_h
24
25#include <VBox/cfgm.h>
26#include <VBox/stam.h>
27#include <VBox/tm.h>
28#include <iprt/types.h>
29#include <iprt/file.h>
30#include <iprt/thread.h>
31#include <iprt/semaphore.h>
32#include <iprt/critsect.h>
33#include <iprt/avl.h>
34#include <iprt/list.h>
35#include <iprt/spinlock.h>
36#include <iprt/memcache.h>
37
38#include "PDMAsyncCompletionInternal.h"
39
40/** @todo: Revise the caching of tasks. We have currently four caches:
41 * Per endpoint task cache
42 * Per class cache
43 * Per endpoint task segment cache
44 * Per class task segment cache
45 *
46 * We could use the RT heap for this probably or extend MMR3Heap (uses RTMemAlloc
47 * instead of managing larger blocks) to have this global for the whole VM.
48 */
49
50RT_C_DECLS_BEGIN
51
52/**
53 * A few forward declerations.
54 */
55typedef struct PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
56/** Pointer to a request segment. */
57typedef struct PDMACTASKFILE *PPDMACTASKFILE;
58/** Pointer to the endpoint class data. */
59typedef struct PDMASYNCCOMPLETIONTASKFILE *PPDMASYNCCOMPLETIONTASKFILE;
60/** Pointer to a cache LRU list. */
61typedef struct PDMACFILELRULIST *PPDMACFILELRULIST;
62/** Pointer to the global cache structure. */
63typedef struct PDMACFILECACHEGLOBAL *PPDMACFILECACHEGLOBAL;
64/** Pointer to a task segment. */
65typedef struct PDMACFILETASKSEG *PPDMACFILETASKSEG;
66
67/**
68 * Blocking event types.
69 */
70typedef enum PDMACEPFILEAIOMGRBLOCKINGEVENT
71{
72 /** Invalid tye */
73 PDMACEPFILEAIOMGRBLOCKINGEVENT_INVALID = 0,
74 /** An endpoint is added to the manager. */
75 PDMACEPFILEAIOMGRBLOCKINGEVENT_ADD_ENDPOINT,
76 /** An endpoint is removed from the manager. */
77 PDMACEPFILEAIOMGRBLOCKINGEVENT_REMOVE_ENDPOINT,
78 /** An endpoint is about to be closed. */
79 PDMACEPFILEAIOMGRBLOCKINGEVENT_CLOSE_ENDPOINT,
80 /** The manager is requested to terminate */
81 PDMACEPFILEAIOMGRBLOCKINGEVENT_SHUTDOWN,
82 /** The manager is requested to suspend */
83 PDMACEPFILEAIOMGRBLOCKINGEVENT_SUSPEND,
84 /** The manager is requested to resume */
85 PDMACEPFILEAIOMGRBLOCKINGEVENT_RESUME,
86 /** 32bit hack */
87 PDMACEPFILEAIOMGRBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
88} PDMACEPFILEAIOMGRBLOCKINGEVENT;
89
90/**
91 * I/O manager type.
92 */
93typedef enum PDMACEPFILEMGRTYPE
94{
95 /** Simple aka failsafe */
96 PDMACEPFILEMGRTYPE_SIMPLE = 0,
97 /** Async I/O with host cache enabled. */
98 PDMACEPFILEMGRTYPE_ASYNC,
99 /** 32bit hack */
100 PDMACEPFILEMGRTYPE_32BIT_HACK = 0x7fffffff
101} PDMACEPFILEMGRTYPE;
102/** Pointer to a I/O manager type */
103typedef PDMACEPFILEMGRTYPE *PPDMACEPFILEMGRTYPE;
104
105/**
106 * States of the I/O manager.
107 */
108typedef enum PDMACEPFILEMGRSTATE
109{
110 /** Invalid state. */
111 PDMACEPFILEMGRSTATE_INVALID = 0,
112 /** Normal running state accepting new requests
113 * and processing them.
114 */
115 PDMACEPFILEMGRSTATE_RUNNING,
116 /** Fault state - not accepting new tasks for endpoints but waiting for
117 * remaining ones to finish.
118 */
119 PDMACEPFILEMGRSTATE_FAULT,
120 /** Suspending state - not accepting new tasks for endpoints but waiting
121 * for remaining ones to finish.
122 */
123 PDMACEPFILEMGRSTATE_SUSPENDING,
124 /** Shutdown state - not accepting new tasks for endpoints but waiting
125 * for remaining ones to finish.
126 */
127 PDMACEPFILEMGRSTATE_SHUTDOWN,
128 /** 32bit hack */
129 PDMACEPFILEMGRSTATE_32BIT_HACK = 0x7fffffff
130} PDMACEPFILEMGRSTATE;
131
132/**
133 * State of a async I/O manager.
134 */
135typedef struct PDMACEPFILEMGR
136{
137 /** Next Aio manager in the list. */
138 R3PTRTYPE(struct PDMACEPFILEMGR *) pNext;
139 /** Previous Aio manager in the list. */
140 R3PTRTYPE(struct PDMACEPFILEMGR *) pPrev;
141 /** Manager type */
142 PDMACEPFILEMGRTYPE enmMgrType;
143 /** Current state of the manager. */
144 PDMACEPFILEMGRSTATE enmState;
145 /** Event semaphore the manager sleeps on when waiting for new requests. */
146 RTSEMEVENT EventSem;
147 /** Flag whether the thread waits in the event semaphore. */
148 volatile bool fWaitingEventSem;
149 /** Thread data */
150 RTTHREAD Thread;
151 /** The async I/O context for this manager. */
152 RTFILEAIOCTX hAioCtx;
153 /** Flag whether the I/O manager was woken up. */
154 volatile bool fWokenUp;
155 /** List of endpoints assigned to this manager. */
156 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointsHead;
157 /** Number of endpoints assigned to the manager. */
158 unsigned cEndpoints;
159 /** Number of requests active currently. */
160 unsigned cRequestsActive;
161 /** Pointer to an array of free async I/O request handles. */
162 RTFILEAIOREQ *pahReqsFree;
163 /** Next free position for a free request handle. */
164 unsigned iFreeEntryNext;
165 /** Position of the next free task handle */
166 unsigned iFreeReqNext;
167 /** Size of the array. */
168 unsigned cReqEntries;
169 /** Flag whether at least one endpoint reached its bandwidth limit. */
170 bool fBwLimitReached;
171 /** Memory cache for file range locks. */
172 RTMEMCACHE hMemCacheRangeLocks;
173 /** Critical section protecting the blocking event handling. */
174 RTCRITSECT CritSectBlockingEvent;
175 /** Event sempahore for blocking external events.
176 * The caller waits on it until the async I/O manager
177 * finished processing the event. */
178 RTSEMEVENT EventSemBlock;
179 /** Flag whether a blocking event is pending and needs
180 * processing by the I/O manager. */
181 volatile bool fBlockingEventPending;
182 /** Blocking event type */
183 volatile PDMACEPFILEAIOMGRBLOCKINGEVENT enmBlockingEvent;
184 /** Event type data */
185 union
186 {
187 /** Add endpoint event. */
188 struct
189 {
190 /** The endpoint to be added */
191 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
192 } AddEndpoint;
193 /** Remove endpoint event. */
194 struct
195 {
196 /** The endpoint to be removed */
197 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
198 } RemoveEndpoint;
199 /** Close endpoint event. */
200 struct
201 {
202 /** The endpoint to be closed */
203 volatile PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
204 } CloseEndpoint;
205 } BlockingEventData;
206} PDMACEPFILEMGR;
207/** Pointer to a async I/O manager state. */
208typedef PDMACEPFILEMGR *PPDMACEPFILEMGR;
209/** Pointer to a async I/O manager state pointer. */
210typedef PPDMACEPFILEMGR *PPPDMACEPFILEMGR;
211
212/**
213 * Bandwidth control manager instance data
214 */
215typedef struct PDMACFILEBWMGR
216{
217 /** Maximum number of bytes the VM is allowed to transfer (Max is 4GB/s) */
218 uint32_t cbVMTransferPerSecMax;
219 /** Number of bytes we start with */
220 uint32_t cbVMTransferPerSecStart;
221 /** Step after each update */
222 uint32_t cbVMTransferPerSecStep;
223 /** Number of bytes we are allowed to transfer till the next update.
224 * Resetted by the refresh timer. */
225 volatile uint32_t cbVMTransferAllowed;
226 /** Timestamp of the last update */
227 volatile uint64_t tsUpdatedLast;
228 /** Reference counter - How many endpoints are associated with this manager. */
229 uint32_t cRefs;
230} PDMACFILEBWMGR;
231/** Pointer to a bandwidth control manager */
232typedef PDMACFILEBWMGR *PPDMACFILEBWMGR;
233/** Pointer to a bandwidth control manager pointer */
234typedef PPDMACFILEBWMGR *PPPDMACFILEBWMGR;
235
236/**
237 * A file access range lock.
238 */
239typedef struct PDMACFILERANGELOCK
240{
241 /** AVL node in the locked range tree of the endpoint. */
242 AVLRFOFFNODECORE Core;
243 /** How many tasks have locked this range. */
244 uint32_t cRefs;
245 /** Flag whether this is a read or write lock. */
246 bool fReadLock;
247 /** List of tasks which are waiting that the range gets unlocked. */
248 PPDMACTASKFILE pWaitingTasksHead;
249 /** List of tasks which are waiting that the range gets unlocked. */
250 PPDMACTASKFILE pWaitingTasksTail;
251} PDMACFILERANGELOCK, *PPDMACFILERANGELOCK;
252
253/**
254 * Data for one request segment waiting for cache entry.
255 */
256typedef struct PDMACFILETASKSEG
257{
258 /** Next task segment in the list. */
259 struct PDMACFILETASKSEG *pNext;
260 /** Task this segment is for. */
261 PPDMASYNCCOMPLETIONTASKFILE pTask;
262 /** Offset into the cache entry buffer to start reading from. */
263 uint32_t uBufOffset;
264 /** Number of bytes to transfer. */
265 size_t cbTransfer;
266 /** Pointer to the buffer. */
267 void *pvBuf;
268 /** Flag whether this entry writes data to the cache. */
269 bool fWrite;
270} PDMACFILETASKSEG;
271
272/**
273 * A cache entry
274 */
275typedef struct PDMACFILECACHEENTRY
276{
277 /** The AVL entry data. */
278 AVLRFOFFNODECORE Core;
279 /** Pointer to the previous element. Used in one of the LRU lists.*/
280 struct PDMACFILECACHEENTRY *pPrev;
281 /** Pointer to the next element. Used in one of the LRU lists.*/
282 struct PDMACFILECACHEENTRY *pNext;
283 /** Pointer to the list the entry is in. */
284 PPDMACFILELRULIST pList;
285 /** Pointer to the global cache structure. */
286 PPDMACFILECACHEGLOBAL pCache;
287 /** Endpoint the entry belongs to. */
288 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
289 /** Flags for this entry. Combinations of PDMACFILECACHE_* #defines */
290 volatile uint32_t fFlags;
291 /** Reference counter. Prevents eviction of the entry if > 0. */
292 volatile uint32_t cRefs;
293 /** Size of the entry. */
294 size_t cbData;
295 /** Pointer to the memory containing the data. */
296 uint8_t *pbData;
297 /** Pointer to the buffer replacing the current one
298 * if the deprecated flag is set. */
299 uint8_t *pbDataReplace;
300 /** Head of list of tasks waiting for this one to finish. */
301 PPDMACFILETASKSEG pWaitingHead;
302 /** Tail of list of tasks waiting for this one to finish. */
303 PPDMACFILETASKSEG pWaitingTail;
304 /** Node for dirty but not yet committed entries list per endpoint. */
305 RTLISTNODE NodeNotCommitted;
306} PDMACFILECACHEENTRY, *PPDMACFILECACHEENTRY;
307/** I/O is still in progress for this entry. This entry is not evictable. */
308#define PDMACFILECACHE_ENTRY_IO_IN_PROGRESS RT_BIT(0)
309/** Entry is locked and thus not evictable. */
310#define PDMACFILECACHE_ENTRY_LOCKED RT_BIT(1)
311/** Entry is dirty */
312#define PDMACFILECACHE_ENTRY_IS_DIRTY RT_BIT(2)
313/** The current buffer used for the entry is deprecated.
314 * The new one is available and will be replaced as soon as the file update
315 * completed.
316 */
317#define PDMACFILECACHE_ENTRY_IS_DEPRECATED RT_BIT(3)
318/** Entry is not evictable. */
319#define PDMACFILECACHE_NOT_EVICTABLE (PDMACFILECACHE_ENTRY_LOCKED | PDMACFILECACHE_ENTRY_IO_IN_PROGRESS | PDMACFILECACHE_ENTRY_IS_DIRTY)
320
321/**
322 * LRU list data
323 */
324typedef struct PDMACFILELRULIST
325{
326 /** Head of the list. */
327 PPDMACFILECACHEENTRY pHead;
328 /** Tail of the list. */
329 PPDMACFILECACHEENTRY pTail;
330 /** Number of bytes cached in the list. */
331 uint32_t cbCached;
332} PDMACFILELRULIST;
333
334/**
335 * Global cache data.
336 */
337typedef struct PDMACFILECACHEGLOBAL
338{
339 /** Maximum size of the cache in bytes. */
340 uint32_t cbMax;
341 /** Current size of the cache in bytes. */
342 uint32_t cbCached;
343 /** Critical section protecting the cache. */
344 RTCRITSECT CritSect;
345 /** Maximum number of bytes cached. */
346 uint32_t cbRecentlyUsedInMax;
347 /** Maximum number of bytes in the paged out list .*/
348 uint32_t cbRecentlyUsedOutMax;
349 /** Recently used cache entries list */
350 PDMACFILELRULIST LruRecentlyUsedIn;
351 /** Scorecard cache entry list. */
352 PDMACFILELRULIST LruRecentlyUsedOut;
353 /** List of frequently used cache entries */
354 PDMACFILELRULIST LruFrequentlyUsed;
355 /** Commit timeout in milli seconds */
356 uint32_t u32CommitTimeoutMs;
357 /** Number of dirty bytes needed to start a commit of the data to the disk. */
358 uint32_t cbCommitDirtyThreshold;
359 /** Current number of dirty bytes in the cache. */
360 volatile uint32_t cbDirty;
361 /** Flag whether a commit is currently in progress. */
362 volatile bool fCommitInProgress;
363 /** Commit interval timer */
364 PTMTIMERR3 pTimerCommit;
365 /** Number of endpoints using the cache. */
366 uint32_t cRefs;
367 /** List of all endpoints using this cache. */
368 RTLISTNODE ListEndpoints;
369#ifdef VBOX_WITH_STATISTICS
370 /** Hit counter. */
371 STAMCOUNTER cHits;
372 /** Partial hit counter. */
373 STAMCOUNTER cPartialHits;
374 /** Miss counter. */
375 STAMCOUNTER cMisses;
376 /** Bytes read from cache. */
377 STAMCOUNTER StatRead;
378 /** Bytes written to the cache. */
379 STAMCOUNTER StatWritten;
380 /** Time spend to get an entry in the AVL tree. */
381 STAMPROFILEADV StatTreeGet;
382 /** Time spend to insert an entry in the AVL tree. */
383 STAMPROFILEADV StatTreeInsert;
384 /** Time spend to remove an entry in the AVL tree. */
385 STAMPROFILEADV StatTreeRemove;
386 /** Number of times a buffer could be reused. */
387 STAMCOUNTER StatBuffersReused;
388#endif
389} PDMACFILECACHEGLOBAL;
390
391/**
392 * Per endpoint cache data.
393 */
394typedef struct PDMACFILEENDPOINTCACHE
395{
396 /** AVL tree managing cache entries. */
397 PAVLRFOFFTREE pTree;
398 /** R/W semaphore protecting cached entries for this endpoint. */
399 RTSEMRW SemRWEntries;
400 /** Pointer to the gobal cache data */
401 PPDMACFILECACHEGLOBAL pCache;
402 /** Number of writes outstanding. */
403 volatile uint32_t cWritesOutstanding;
404 /** Handle of the flush request if one is active */
405 volatile PPDMASYNCCOMPLETIONTASKFILE pTaskFlush;
406 /** Lock protecting the dirty entries list. */
407 RTSPINLOCK LockList;
408 /** List of dirty but not committed entries for this endpoint. */
409 RTLISTNODE ListDirtyNotCommitted;
410 /** Node of the cache endpoint list. */
411 RTLISTNODE NodeCacheEndpoint;
412#ifdef VBOX_WITH_STATISTICS
413 /** Number of times a write was deferred because the cache entry was still in progress */
414 STAMCOUNTER StatWriteDeferred;
415#endif
416} PDMACFILEENDPOINTCACHE, *PPDMACFILEENDPOINTCACHE;
417
418/**
419 * Backend type for the endpoint.
420 */
421typedef enum PDMACFILEEPBACKEND
422{
423 /** Non buffered. */
424 PDMACFILEEPBACKEND_NON_BUFFERED = 0,
425 /** Buffered (i.e host cache enabled) */
426 PDMACFILEEPBACKEND_BUFFERED,
427 /** 32bit hack */
428 PDMACFILEEPBACKEND_32BIT_HACK = 0x7fffffff
429} PDMACFILEEPBACKEND;
430/** Pointer to a backend type. */
431typedef PDMACFILEEPBACKEND *PPDMACFILEEPBACKEND;
432
433/**
434 * Global data for the file endpoint class.
435 */
436typedef struct PDMASYNCCOMPLETIONEPCLASSFILE
437{
438 /** Common data. */
439 PDMASYNCCOMPLETIONEPCLASS Core;
440 /** Override I/O manager type - set to SIMPLE after failure. */
441 PDMACEPFILEMGRTYPE enmMgrTypeOverride;
442 /** Default backend type for the endpoint. */
443 PDMACFILEEPBACKEND enmEpBackendDefault;
444 /** Flag whether the file data cache is enabled. */
445 bool fCacheEnabled;
446 /** Critical section protecting the list of async I/O managers. */
447 RTCRITSECT CritSect;
448 /** Pointer to the head of the async I/O managers. */
449 R3PTRTYPE(PPDMACEPFILEMGR) pAioMgrHead;
450 /** Number of async I/O managers currently running. */
451 unsigned cAioMgrs;
452 /** Maximum number of segments to cache per endpoint */
453 unsigned cTasksCacheMax;
454 /** Maximum number of simultaneous outstandingrequests. */
455 uint32_t cReqsOutstandingMax;
456 /** Bitmask for checking the alignment of a buffer. */
457 RTR3UINTPTR uBitmaskAlignment;
458 /** Global cache data. */
459 PDMACFILECACHEGLOBAL Cache;
460 /** Flag whether the out of resources warning was printed already. */
461 bool fOutOfResourcesWarningPrinted;
462 /** The global bandwidth control manager */
463 PPDMACFILEBWMGR pBwMgr;
464} PDMASYNCCOMPLETIONEPCLASSFILE;
465/** Pointer to the endpoint class data. */
466typedef PDMASYNCCOMPLETIONEPCLASSFILE *PPDMASYNCCOMPLETIONEPCLASSFILE;
467
468typedef enum PDMACEPFILEBLOCKINGEVENT
469{
470 /** The invalid event type */
471 PDMACEPFILEBLOCKINGEVENT_INVALID = 0,
472 /** A task is about to be canceled */
473 PDMACEPFILEBLOCKINGEVENT_CANCEL,
474 /** Usual 32bit hack */
475 PDMACEPFILEBLOCKINGEVENT_32BIT_HACK = 0x7fffffff
476} PDMACEPFILEBLOCKINGEVENT;
477
478/**
479 * States of the endpoint.
480 */
481typedef enum PDMASYNCCOMPLETIONENDPOINTFILESTATE
482{
483 /** Invalid state. */
484 PDMASYNCCOMPLETIONENDPOINTFILESTATE_INVALID = 0,
485 /** Normal running state accepting new requests
486 * and processing them.
487 */
488 PDMASYNCCOMPLETIONENDPOINTFILESTATE_ACTIVE,
489 /** The endpoint is about to be closed - not accepting new tasks for endpoints but waiting for
490 * remaining ones to finish.
491 */
492 PDMASYNCCOMPLETIONENDPOINTFILESTATE_CLOSING,
493 /** Removing from current I/O manager state - not processing new tasks for endpoints but waiting
494 * for remaining ones to finish.
495 */
496 PDMASYNCCOMPLETIONENDPOINTFILESTATE_REMOVING,
497 /** The current endpoint will be migrated to another I/O manager. */
498 PDMASYNCCOMPLETIONENDPOINTFILESTATE_MIGRATING,
499 /** 32bit hack */
500 PDMASYNCCOMPLETIONENDPOINTFILESTATE_32BIT_HACK = 0x7fffffff
501} PDMASYNCCOMPLETIONENDPOINTFILESTATE;
502
503/**
504 * Data for the file endpoint.
505 */
506typedef struct PDMASYNCCOMPLETIONENDPOINTFILE
507{
508 /** Common data. */
509 PDMASYNCCOMPLETIONENDPOINT Core;
510 /** Current state of the endpoint. */
511 PDMASYNCCOMPLETIONENDPOINTFILESTATE enmState;
512 /** The backend to use for this endpoint. */
513 PDMACFILEEPBACKEND enmBackendType;
514 /** async I/O manager this endpoint is assigned to. */
515 R3PTRTYPE(volatile PPDMACEPFILEMGR) pAioMgr;
516 /** Flags for opening the file. */
517 unsigned fFlags;
518 /** File handle. */
519 RTFILE File;
520 /** Size of the underlying file.
521 * Updated while data is appended. */
522 volatile uint64_t cbFile;
523 /** Flag whether caching is enabled for this file. */
524 bool fCaching;
525 /** Flag whether the file was opened readonly. */
526 bool fReadonly;
527 /** List of new tasks. */
528 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksNewHead;
529
530 /** Head of the small cache for allocated task segments for exclusive
531 * use by this endpoint. */
532 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeHead;
533 /** Tail of the small cache for allocated task segments for exclusive
534 * use by this endpoint. */
535 R3PTRTYPE(volatile PPDMACTASKFILE) pTasksFreeTail;
536 /** Number of elements in the cache. */
537 volatile uint32_t cTasksCached;
538
539 /** Cache of endpoint data. */
540 PDMACFILEENDPOINTCACHE DataCache;
541 /** Pointer to the associated bandwidth control manager */
542 PPDMACFILEBWMGR pBwMgr;
543
544 /** Flag whether a flush request is currently active */
545 PPDMACTASKFILE pFlushReq;
546
547 /** Event sempahore for blocking external events.
548 * The caller waits on it until the async I/O manager
549 * finished processing the event. */
550 RTSEMEVENT EventSemBlock;
551 /** Flag whether a blocking event is pending and needs
552 * processing by the I/O manager. */
553 bool fBlockingEventPending;
554 /** Blocking event type */
555 PDMACEPFILEBLOCKINGEVENT enmBlockingEvent;
556
557#ifdef VBOX_WITH_STATISTICS
558 /** Time spend in a read. */
559 STAMPROFILEADV StatRead;
560 /** Time spend in a write. */
561 STAMPROFILEADV StatWrite;
562#endif
563
564 /** Additional data needed for the event types. */
565 union
566 {
567 /** Cancelation event. */
568 struct
569 {
570 /** The task to cancel. */
571 PPDMACTASKFILE pTask;
572 } Cancel;
573 } BlockingEventData;
574 /** Data for exclusive use by the assigned async I/O manager. */
575 struct
576 {
577 /** Pointer to the next endpoint assigned to the manager. */
578 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointNext;
579 /** Pointer to the previous endpoint assigned to the manager. */
580 R3PTRTYPE(PPDMASYNCCOMPLETIONENDPOINTFILE) pEndpointPrev;
581 /** List of pending requests (not submitted due to usage restrictions
582 * or a pending flush request) */
583 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingHead;
584 /** Tail of pending requests. */
585 R3PTRTYPE(PPDMACTASKFILE) pReqsPendingTail;
586 /** Tree of currently locked ranges.
587 * If a write task is enqueued the range gets locked and any other
588 * task writing to that range has to wait until the task completes.
589 */
590 PAVLRFOFFTREE pTreeRangesLocked;
591 /** Number of requests currently being processed for this endpoint
592 * (excluded flush requests). */
593 unsigned cRequestsActive;
594 /** Number of requests processed during the last second. */
595 unsigned cReqsPerSec;
596 /** Current number of processed requests for the current update period. */
597 unsigned cReqsProcessed;
598 /** Flag whether the endpoint is about to be moved to another manager. */
599 bool fMoving;
600 /** Destination I/O manager. */
601 PPDMACEPFILEMGR pAioMgrDst;
602 } AioMgr;
603} PDMASYNCCOMPLETIONENDPOINTFILE;
604/** Pointer to the endpoint class data. */
605typedef PDMASYNCCOMPLETIONENDPOINTFILE *PPDMASYNCCOMPLETIONENDPOINTFILE;
606
607/** Request completion function */
608typedef DECLCALLBACK(void) FNPDMACTASKCOMPLETED(PPDMACTASKFILE pTask, void *pvUser);
609/** Pointer to a request completion function. */
610typedef FNPDMACTASKCOMPLETED *PFNPDMACTASKCOMPLETED;
611
612/**
613 * Transfer type.
614 */
615typedef enum PDMACTASKFILETRANSFER
616{
617 /** Invalid. */
618 PDMACTASKFILETRANSFER_INVALID = 0,
619 /** Read transfer. */
620 PDMACTASKFILETRANSFER_READ,
621 /** Write transfer. */
622 PDMACTASKFILETRANSFER_WRITE,
623 /** Flush transfer. */
624 PDMACTASKFILETRANSFER_FLUSH
625} PDMACTASKFILETRANSFER;
626
627/**
628 * Data of a request.
629 */
630typedef struct PDMACTASKFILE
631{
632 /** Pointer to the range lock we are waiting for */
633 PPDMACFILERANGELOCK pRangeLock;
634 /** Next task in the list. (Depending on the state) */
635 struct PDMACTASKFILE *pNext;
636 /** Endpoint */
637 PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint;
638 /** Transfer type. */
639 PDMACTASKFILETRANSFER enmTransferType;
640 /** Start offset */
641 RTFOFF Off;
642 /** Data segment. */
643 PDMDATASEG DataSeg;
644 /** Flag whether this segment uses a bounce buffer
645 * because the provided buffer doesn't meet host requirements. */
646 bool fBounceBuffer;
647 /** Pointer to the used bounce buffer if any. */
648 void *pvBounceBuffer;
649 /** Start offset in the bounce buffer to copy from. */
650 uint32_t uBounceBufOffset;
651 /** Flag whether this is a prefetch request. */
652 bool fPrefetch;
653 /** Completion function to call on completion. */
654 PFNPDMACTASKCOMPLETED pfnCompleted;
655 /** User data */
656 void *pvUser;
657} PDMACTASKFILE;
658
659/**
660 * Per task data.
661 */
662typedef struct PDMASYNCCOMPLETIONTASKFILE
663{
664 /** Common data. */
665 PDMASYNCCOMPLETIONTASK Core;
666 /** Number of bytes to transfer until this task completes. */
667 volatile int32_t cbTransferLeft;
668 /** Flag whether the task completed. */
669 volatile bool fCompleted;
670} PDMASYNCCOMPLETIONTASKFILE;
671
672int pdmacFileAioMgrFailsafe(RTTHREAD ThreadSelf, void *pvUser);
673int pdmacFileAioMgrNormal(RTTHREAD ThreadSelf, void *pvUser);
674
675int pdmacFileAioMgrNormalInit(PPDMACEPFILEMGR pAioMgr);
676void pdmacFileAioMgrNormalDestroy(PPDMACEPFILEMGR pAioMgr);
677
678int pdmacFileAioMgrCreate(PPDMASYNCCOMPLETIONEPCLASSFILE pEpClass, PPPDMACEPFILEMGR ppAioMgr, PDMACEPFILEMGRTYPE enmMgrType);
679
680int pdmacFileAioMgrAddEndpoint(PPDMACEPFILEMGR pAioMgr, PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
681
682PPDMACTASKFILE pdmacFileEpGetNewTasks(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
683PPDMACTASKFILE pdmacFileTaskAlloc(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
684void pdmacFileTaskFree(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint,
685 PPDMACTASKFILE pTask);
686
687int pdmacFileEpAddTask(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMACTASKFILE pTask);
688
689void pdmacFileEpTaskCompleted(PPDMACTASKFILE pTask, void *pvUser);
690
691bool pdmacFileBwMgrIsTransferAllowed(PPDMACFILEBWMGR pBwMgr, uint32_t cbTransfer);
692
693int pdmacFileCacheInit(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile, PCFGMNODE pCfgNode);
694void pdmacFileCacheDestroy(PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
695int pdmacFileEpCacheInit(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONEPCLASSFILE pClassFile);
696void pdmacFileEpCacheDestroy(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint);
697
698int pdmacFileEpCacheRead(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
699 RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
700 size_t cbRead);
701int pdmacFileEpCacheWrite(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask,
702 RTFOFF off, PCPDMDATASEG paSegments, size_t cSegments,
703 size_t cbWrite);
704int pdmacFileEpCacheFlush(PPDMASYNCCOMPLETIONENDPOINTFILE pEndpoint, PPDMASYNCCOMPLETIONTASKFILE pTask);
705
706RT_C_DECLS_END
707
708#endif
709
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