Windows: non-persistent cache from pagefile->heap
authorJeffrey Altman <jaltman@your-file-system.com>
Sat, 3 Sep 2011 22:41:43 +0000 (18:41 -0400)
committerJeffrey Altman <jaltman@openafs.org>
Mon, 5 Sep 2011 04:35:00 +0000 (21:35 -0700)
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 <jaltman@openafs.org>
Tested-by: Jeffrey Altman <jaltman@openafs.org>

src/WINNT/afsd/afsd.h
src/WINNT/afsd/afsd_init.c
src/WINNT/afsd/cm_memmap.c
src/WINNT/afsd/cm_memmap.h

index 47bfa9e..00ffa12 100644 (file)
@@ -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
index 26f6142..3db3f32 100644 (file)
@@ -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";
index b9c59ea..b7bc9ca 100644 (file)
@@ -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;
 }
index a4b57b2..cd5ff21 100644 (file)
@@ -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