From 79e3af59f1737e46a5bbc58fc8d73f5e38ed8c30 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Sat, 3 Sep 2011 18:41:43 -0400 Subject: [PATCH] Windows: non-persistent cache from pagefile->heap Change the non-persistent cache mode to use a heap allocated cache in place of a paging file allocated cache. With a heap cache the memory for the cache can be locked into physical memory so it won't be swapped out when running in virtual machines. This patch does not apply such memory locking. Change-Id: I85e6da1bba481d3d9bca84673b918b1d7cde71f9 Reviewed-on: http://gerrit.openafs.org/5343 Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- src/WINNT/afsd/afsd.h | 2 + src/WINNT/afsd/afsd_init.c | 78 +++++++++++++++++++++++--------------- src/WINNT/afsd/cm_memmap.c | 56 +++++++++++++++++---------- src/WINNT/afsd/cm_memmap.h | 2 +- 4 files changed, 88 insertions(+), 50 deletions(-) diff --git a/src/WINNT/afsd/afsd.h b/src/WINNT/afsd/afsd.h index 47bfa9ead..00ffa12dd 100644 --- a/src/WINNT/afsd/afsd.h +++ b/src/WINNT/afsd/afsd.h @@ -121,6 +121,8 @@ extern int RDR_Initialized; extern afs_uint32 smb_Enabled; +extern int cm_virtualCache; + #define DFS_SUPPORT 1 #define LOG_PACKET 1 #undef NOTSERVICE diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index 26f614224..3db3f32e8 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -75,6 +75,7 @@ DWORD cm_mountRootCLen; int cm_readonlyVolumeVersioning = 0; int cm_logChunkSize; int cm_chunkSize; +int cm_virtualCache = 0; int smb_UseV3 = 1; afs_uint32 smb_Enabled = 1; @@ -511,7 +512,7 @@ afsd_InitCM(char **reasonP) int rx_max_rwin_size; int rx_max_swin_size; int rx_min_peer_timeout; - long virtualCache = 0; + DWORD virtualCache = 0; fschar_t rootCellName[256]; struct rx_service *serverp; static struct rx_securityClass *nullServerSecurityClassp; @@ -675,15 +676,56 @@ afsd_InitCM(char **reasonP) (BYTE *) &smb_monitorReqs, &dummyLen); afsi_log("SMB request monitoring is %s", (smb_monitorReqs != 0)? "enabled": "disabled"); + dummyLen = sizeof(virtualCache); + code = RegQueryValueEx(parmKey, "NonPersistentCaching", NULL, NULL, + (LPBYTE)&virtualCache, &dummyLen); + if (!code) + cm_virtualCache = virtualCache ? 1 : 0; + afsi_log("Cache type is %s", (cm_virtualCache?"VIRTUAL":"FILE")); + + if (!cm_virtualCache) { + dummyLen = sizeof(cm_ValidateCache); + code = RegQueryValueEx(parmKey, "ValidateCache", NULL, NULL, + (LPBYTE)&cm_ValidateCache, &dummyLen); + if ( cm_ValidateCache < 0 || cm_ValidateCache > 2 ) + cm_ValidateCache = 1; + switch (cm_ValidateCache) { + case 0: + afsi_log("Cache Validation disabled"); + break; + case 1: + afsi_log("Cache Validation on Startup"); + break; + case 2: + afsi_log("Cache Validation on Startup and Shutdown"); + break; + } + } + dummyLen = sizeof(cacheSize); code = RegQueryValueEx(parmKey, "CacheSize", NULL, NULL, (BYTE *) &cacheSize, &dummyLen); - if (code == ERROR_SUCCESS) - afsi_log("Cache size %d", cacheSize); - else { + if (code != ERROR_SUCCESS) cacheSize = CM_CONFIGDEFAULT_CACHESIZE; - afsi_log("Default cache size %d", cacheSize); + + if (cm_virtualCache) { + MEMORYSTATUSEX memStatus; + DWORD maxCacheSize; + + memStatus.dwLength = sizeof(memStatus); + if (GlobalMemoryStatusEx(&memStatus)) { + /* Set maxCacheSize to 10% of physical memory */ + maxCacheSize = (DWORD)(memStatus.ullTotalPhys / 1024 / 10); + } else { + /* Cannot determine physical memory, set limit to 64MB */ + maxCacheSize = 65536; + } + if (cacheSize > maxCacheSize) { + afsi_log("Requested Cache size %u", cacheSize); + cacheSize = maxCacheSize; + } } + afsi_log("Allocated Cache size %u", cacheSize); dummyLen = sizeof(logChunkSize); code = RegQueryValueEx(parmKey, "ChunkSize", NULL, NULL, @@ -854,30 +896,6 @@ afsd_InitCM(char **reasonP) afsi_log("Default cache path %s", cm_CachePath); } - dummyLen = sizeof(virtualCache); - code = RegQueryValueEx(parmKey, "NonPersistentCaching", NULL, NULL, - (LPBYTE)&virtualCache, &dummyLen); - afsi_log("Cache type is %s", (virtualCache?"VIRTUAL":"FILE")); - - if (!virtualCache) { - dummyLen = sizeof(cm_ValidateCache); - code = RegQueryValueEx(parmKey, "ValidateCache", NULL, NULL, - (LPBYTE)&cm_ValidateCache, &dummyLen); - if ( cm_ValidateCache < 0 || cm_ValidateCache > 2 ) - cm_ValidateCache = 1; - switch (cm_ValidateCache) { - case 0: - afsi_log("Cache Validation disabled"); - break; - case 1: - afsi_log("Cache Validation on Startup"); - break; - case 2: - afsi_log("Cache Validation on Startup and Shutdown"); - break; - } - } - dummyLen = sizeof(traceOnPanic); code = RegQueryValueEx(parmKey, "TrapOnPanic", NULL, NULL, (BYTE *) &traceOnPanic, &dummyLen); @@ -1317,7 +1335,7 @@ afsd_InitCM(char **reasonP) cm_InitNormalization(); - code = cm_InitMappedMemory(virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize); + code = cm_InitMappedMemory(cm_virtualCache, cm_CachePath, stats, volumes, cells, cm_chunkSize, cacheBlocks, blockSize); afsi_log("cm_InitMappedMemory code %x", code); if (code != 0) { *reasonP = "error initializing cache file"; diff --git a/src/WINNT/afsd/cm_memmap.c b/src/WINNT/afsd/cm_memmap.c index b9c59ea1d..b7bc9ca9c 100644 --- a/src/WINNT/afsd/cm_memmap.c +++ b/src/WINNT/afsd/cm_memmap.c @@ -11,6 +11,9 @@ extern void afsi_log(char *pattern, ...); extern DWORD cm_ValidateCache; +static HANDLE hMemoryMappedFile = NULL; +static HANDLE hCacheHeap = NULL; + afs_uint64 GranularityAdjustment(afs_uint64 size) { @@ -202,8 +205,6 @@ VOID FreeCacheFileSA(PSECURITY_ATTRIBUTES psa) GlobalFree(psa); } -static HANDLE hMemoryMappedFile = NULL; - int cm_IsCacheValid(void) { @@ -260,6 +261,11 @@ cm_ShutdownMappedMemory(void) cm_ShutdownCell(); cm_ShutdownVolume(); + if (hCacheHeap) { + HeapFree(hCacheHeap, 0, cm_data.baseAddress); + HeapDestroy(hCacheHeap); + afsi_log("Memory Heap has been destroyed"); + } else { if (cm_ValidateCache == 2) dirty = !cm_IsCacheValid(); @@ -268,8 +274,8 @@ cm_ShutdownMappedMemory(void) UnmapViewOfFile(config_data_p); CloseHandle(hMemoryMappedFile); hMemoryMappedFile = NULL; - afsi_log("Memory Mapped File has been closed"); + } return 0; } @@ -630,10 +636,8 @@ int cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD maxVols, DWORD maxCells, DWORD chunkSize, afs_uint64 cacheBlocks, afs_uint32 blockSize) { - HANDLE hf = INVALID_HANDLE_VALUE, hm; - PSECURITY_ATTRIBUTES psa; - int newFile = 1; afs_uint64 mappingSize; + int newCache = 1; DWORD volumeSerialNumber = 0; DWORD sidStringSize = 0; DWORD rc; @@ -647,7 +651,21 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max mappingSize = ComputeSizeOfMappingFile(stats, maxVols, maxCells, chunkSize, cacheBlocks, blockSize); - if ( !virtualCache ) { + if ( virtualCache ) { + hCacheHeap = HeapCreate( HEAP_GENERATE_EXCEPTIONS, 0, 0); + + baseAddress = HeapAlloc(hCacheHeap, 0, mappingSize); + + if (baseAddress == NULL) { + afsi_log("Error allocating Virtual Memory gle=%d", + GetLastError()); + return CM_ERROR_INVAL; + } + newCache = 1; + } else { + HANDLE hf = INVALID_HANDLE_VALUE, hm; + PSECURITY_ATTRIBUTES psa; + psa = CreateCacheFileSA(); hf = CreateFile( cachePath, GENERIC_READ | GENERIC_WRITE, @@ -767,7 +785,7 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max afsi_log("Previous session terminated prematurely"); } else { baseAddress = config_data_p->baseAddress; - newFile = 0; + newCache = 0; } } else { afsi_log("Configuration changed or Not a persistent cache file"); @@ -775,7 +793,6 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max UnmapViewOfFile(config_data_p); CloseHandle(hm); } - } hm = CreateFileMapping( hf, NULL, @@ -812,13 +829,15 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max CloseHandle(hm); return CM_ERROR_INVAL; } - newFile = 1; + newCache = 1; } CloseHandle(hm); + hMemoryMappedFile = hf; + } config_data_p = (cm_config_data_t *) baseAddress; - if (!newFile) { + if (!newCache) { afsi_log("Reusing existing AFS Cache data:"); cm_data = *config_data_p; @@ -851,11 +870,11 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max */ if (baseAddress != cm_data.baseAddress || cm_ValidateCache && !cm_IsCacheValid()) { - newFile = 1; + newCache = 1; } } - if ( newFile ) { + if ( newCache ) { afsi_log("Building AFS Cache from scratch"); memset(&cm_data, 0, sizeof(cm_config_data_t)); cm_data.size = sizeof(cm_config_data_t); @@ -970,24 +989,23 @@ cm_InitMappedMemory(DWORD virtualCache, char * cachePath, DWORD stats, DWORD max RpcStringFree(&p); afsi_log("Initializing Volume Data"); - cm_InitVolume(newFile, maxVols); + cm_InitVolume(newCache, maxVols); afsi_log("Initializing Cell Data"); - cm_InitCell(newFile, maxCells); + cm_InitCell(newCache, maxCells); afsi_log("Initializing ACL Data"); - cm_InitACLCache(newFile, 2*stats); + cm_InitACLCache(newCache, 2*stats); afsi_log("Initializing Stat Data"); - cm_InitSCache(newFile, stats); + cm_InitSCache(newCache, stats); afsi_log("Initializing Data Buffers"); - cm_InitDCache(newFile, 0, cacheBlocks); + cm_InitDCache(newCache, 0, cacheBlocks); *config_data_p = cm_data; config_data_p->dirty = 1; - hMemoryMappedFile = hf; afsi_log("Cache Initialization Complete"); return 0; } diff --git a/src/WINNT/afsd/cm_memmap.h b/src/WINNT/afsd/cm_memmap.h index a4b57b2d2..cd5ff2189 100644 --- a/src/WINNT/afsd/cm_memmap.h +++ b/src/WINNT/afsd/cm_memmap.h @@ -1,5 +1,5 @@ /* - * Copyright 2004, Secure Endpoints Inc. + * Copyright 2004-2011, Secure Endpoints Inc. * All Rights Reserved. * * This software has been released under the terms of the IBM Public -- 2.39.5