VirtualBox

Ignore:
Timestamp:
May 20, 2019 11:04:08 PM (6 years ago)
Author:
vboxsync
Message:

winnt/vboxsf: Don't flush and purge the cache twice on newer systems, instead do a library trick to redirect relevant imports from write.obj and read.obj to our wrappers that uses CcCoherencyFlushAndPurgeCache when possible to get better coherency between mmap regions and file content when writing and reading normally. This comes at a cost when the file has been mmapped at some point previously (or currently) and we may need to purge stuff. bugref:9172

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/SharedFolders/driver/file.cpp

    r78585 r78608  
    3030/** How many pages we should try transfer in one I/O request (read/write). */
    3131#define VBSF_MAX_IO_PAGES   RT_MIN(_16K / sizeof(RTGCPHYS64) /* => 8MB buffer */, VMMDEV_MAX_HGCM_DATA_SIZE >> PAGE_SHIFT)
     32
     33
     34
     35
     36/** @name Hacks for using the better CcCoherencyFlushAndPurgeCache when
     37 *        available (>= Windows 7) and avoid flushing+puring twice.
     38 *
     39 * We change the cache flushing and purging related imports from  the write.obj
     40 * and read.obj files in the rdbsslib.lib to import so these gets redirected
     41 * here instead of going directly to ntoskrnl.  We will use
     42 * CcCoherencyFlushAndPurgeCache when present, and on older systems there will
     43 * be no change.  This does however save us from doing double flushing and
     44 * purging on newer systems.
     45 *
     46 * See VBoxEditCoffLib and the Makefile.kmk for the rest of the puzzle.
     47 *
     48 * @{
     49 */
     50
     51static VOID NTAPI vbsfNtReadCcFlushCache(PSECTION_OBJECT_POINTERS pSectObjPtrs, PLARGE_INTEGER poffFlush, ULONG cbFlush,
     52                                         PIO_STATUS_BLOCK pIos)
     53{
     54    if (g_pfnCcCoherencyFlushAndPurgeCache)
     55        g_pfnCcCoherencyFlushAndPurgeCache(pSectObjPtrs, poffFlush, cbFlush, pIos, CC_FLUSH_AND_PURGE_NO_PURGE);
     56    else
     57        CcFlushCache(pSectObjPtrs, poffFlush, cbFlush, pIos);
     58}
     59
     60static VOID NTAPI vbsfNtWriteCcFlushCache(PSECTION_OBJECT_POINTERS pSectObjPtrs, PLARGE_INTEGER poffFlush, ULONG cbFlush,
     61                                          PIO_STATUS_BLOCK pIos)
     62{
     63    if (g_pfnCcCoherencyFlushAndPurgeCache)
     64        g_pfnCcCoherencyFlushAndPurgeCache(pSectObjPtrs, poffFlush, cbFlush, pIos, 0 /*fFlags*/);
     65    else
     66        CcFlushCache(pSectObjPtrs, poffFlush, cbFlush, pIos);
     67}
     68
     69
     70static BOOLEAN NTAPI vbsfNtWriteCcPurgeCacheSection(PSECTION_OBJECT_POINTERS pSectObjPtrs, PLARGE_INTEGER poffPurge,ULONG cbPurge,
     71#if (NTDDI_VERSION >= NTDDI_VISTA)
     72                                                    ULONG fUninitializeCacheMaps)
     73#else
     74                                                    BOOLEAN fUninitializeCacheMaps)
     75#endif
     76{
     77#if (NTDDI_VERSION >= NTDDI_VISTA)
     78    fUninitializeCacheMaps &= 0xff; /* Used to be BOOLEAN before Vista. */
     79#endif
     80    Assert(fUninitializeCacheMaps == 0);
     81    BOOLEAN fRet;
     82    if (g_pfnCcCoherencyFlushAndPurgeCache)
     83        fRet = TRUE;
     84    else
     85        fRet = CcPurgeCacheSection(pSectObjPtrs, poffPurge, cbPurge, fUninitializeCacheMaps);
     86    return fRet;
     87}
     88
     89extern "C" {
     90decltype(CcFlushCache)        *g_pfnRdFlushCache        = vbsfNtReadCcFlushCache;
     91decltype(CcFlushCache)        *g_pfnWrFlushCache        = vbsfNtWriteCcFlushCache;
     92decltype(CcPurgeCacheSection) *g_pfnWrPurgeCacheSection = vbsfNtWriteCcPurgeCacheSection;
     93}
     94
     95/** @} */
     96
    3297
    3398
     
    115180            pReq->PgLst.offFirstPage = offPage;
    116181
     182#if 0 /* Instead we hook into read.obj's import function pointers to do this more efficiently. */
    117183            /*
    118184             * Flush dirty cache content before we try read it from the host.  RDBSS calls
     
    135201                {   RxReleasePagingIoResource(NULL, capFcb); /* requires {} */ }
    136202            }
     203#endif
    137204
    138205            /*
     
    377444            pReq->PgLst.offFirstPage = offPage;
    378445
     446#if 0 /* Instead we hook into write.obj's import function pointers to do this more efficiently. */
    379447            /*
    380448             * Flush and purge the cache range we're touching upon now, provided we can and
     
    395463                {   RxReleasePagingIoResource(NULL, capFcb); /* requires {} */ }
    396464            }
     465#endif
    397466
    398467            /*
Note: See TracChangeset for help on using the changeset viewer.

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