[prev in list] [next in list] [prev in thread] [next in thread] 

List:       helix-server-cvs
Subject:    [Server-cvs]
From:       dcollins () helixcommunity ! org
Date:       2010-11-19 23:51:06
Message-ID: 201011192351.oAJNp6uM018057 () mailer ! progressive-comp ! com
[Download RAW message or body]

Update of /cvsroot/server/engine/core
In directory cvs01.internal.helixcommunity.org:/tmp/cvs-serv22391/server/engine/core

Modified Files:
	_main.cpp shregion.cpp 
Log Message:
Synopsis
========
Adds a --fhm flag to force the shared memory segment to be above 4GB on Linux

Branches: HEAD
Reviewer: Chytanya


Description
===========

This adds an undocumented command-line flag, --fhm, which is intended
for dev/QA testing.  This flag tells the server to attempt to force the
shared memory segment to have an address above 4GB by first allocating
a 4GB segment and reserving it.  Later, when create_mmap() is called
to create the real segment for the server's heap, this initial 4GB will
be unavailable.  Additionally, this reserved segment is mprotected, so
that pointers which are truncated to 32-bits might possibly reference
into this "DMZ" and cause a CA.

This is currently only useful on Linux.  On Solaris it seems unnecessary
since the mmap segment is created in high memory by default, and pointer
dereferences into lower unallocated memory will CA.  On Windows,
the OS seems extremely slow at allocating the 4GB of RAM to the
point of being unusable.

Without this, pointers could potentially be cast to 32-bits and back,
and they'd still work, since the pointer referenced a memory address
that was below 4GB.  So this command-line flag will help us detect
and eliminate certain types of bad pointer usage.

Also removed the obsolete and unused g_bUnsupportedOSFlag.


Files Affected
==============

server/engine/core/_main.cpp
server/engine/core/shregion.cpp
server/engine/core/pub/shregion.h


Testing Performed
=================

Unit Tests:
- N/A

Integration Tests:
- Ran server on 64-bit Linux with and without the --fhm flag.
- Ran with instrumentation verifying the shared memory segment was being
  allocated below 4GB without the flag and above with the flag.
- Ran with instrumentation on Solaris to obverve the shared memory
  segment was already being allocated in a high address.
- Ran with instrumentation on Win2k8/x86_64 to show it too could use
  this, but the OS was very slow at allocating 4GB so I removed this
  for now.

Leak Tests:
- N/A

Performance Tests:
- N/A

Platforms Tested: linux-rhel5-x86_64, win-x86_64-vc10, sunos-5.10-sparc64
Builds Verified: linux-rhel5-x86_64, win-x86_64-vc10, sunos-5.10-sparc64


QA Hints
========
- N/A


Index: shregion.cpp
===================================================================
RCS file: /cvsroot/server/engine/core/shregion.cpp,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- shregion.cpp	3 Nov 2010 17:56:15 -0000	1.12
+++ shregion.cpp	19 Nov 2010 23:51:03 -0000	1.13
@@ -59,6 +59,8 @@
 
 extern UINT32 g_ulBackOffPercentage;
 extern UINT64 g_ullSizemmap;
+extern HXBOOL g_bForceHighMemory;
+
 
 extern void* g_pSecondHeapBottom;
 #ifdef _LINUX
@@ -84,6 +86,8 @@
     , m_size(0)
     , m_second_heap_size(0)
 {
+    if (g_bForceHighMemory) { ForceHighMemory(); }
+
     size_t ullStartSize = PickStartSize();
     size_t ulSize = ullStartSize;
     double lfBackOffFraction = (double)g_ulBackOffPercentage / 100.0;
@@ -423,3 +427,58 @@
 
     return ullStartSize;
 }
+
+// ForceHighMemory
+//
+// This routine, intended for dev/QA testing, attempts to force the shared
+// memory segment to have an address above 4GB by first allocating a 4GB
+// segment and reserving it.  Later, when create_mmap() is called to create
+// the real segment for server usage, this initial 4GB will be unavailable.
+// Additionally, this reserved segment is mprotected, so that pointers
+// which are truncated to 32-bits might possibly reference into this "DMZ"
+// and cause a CA.
+//
+// This is currently only useful on Linux.  On Solaris it seems unnecessary
+// since the mmap segment is created in high memory by default, and pointer
+// dereferences into lower unallocated memory will CA.  On Windows,
+// allocating the 4GB of RAM is extremely slow and CPU intensive to the
+// point of being unusable.
+// 
+HXBOOL
+SharedRegion::ForceHighMemory(void)
+{
+    HXBOOL bResult = FALSE;
+
+#if defined(_LONG_IS_64) && defined(_LINUX)
+
+    UINT64 ullSizeMB = 4096; //4GB
+    UINT64 ullSize = 0; //in bytes
+    BYTE* pMem = NULL;
+
+    create_mmap(ullSizeMB);
+    pMem = m_region;
+    ullSize = m_size;
+    m_region = NULL;
+    m_size = 0;
+
+    if (pMem > (void*)(1LL << 32))
+    {
+        printf("Initial segment above 4GB, ignoring --fhm\n");
+        munmap((char*)pMem, ullSize);
+    }
+    else if (pMem)
+    {
+        printf("Forced memory segment to be in high memory (>4GB)\n");
+        if (mprotect((char*)pMem, ullSize, PROT_NONE) == 0)
+        {
+            bResult = TRUE;
+        }
+    }
+    else
+    {
+        printf("Failed to force memory segment into high memory!\n");
+    }
+#endif
+
+    return bResult;
+}

Index: _main.cpp
===================================================================
RCS file: /cvsroot/server/engine/core/_main.cpp,v
retrieving revision 1.190
retrieving revision 1.191
diff -u -d -r1.190 -r1.191
--- _main.cpp	15 Nov 2010 16:45:33 -0000	1.190
+++ _main.cpp	19 Nov 2010 23:51:03 -0000	1.191
@@ -346,9 +346,9 @@
 Engine** volatile g_ppLastEngine;
 UINT32* volatile g_pDescriptorCapacityValue = 0;
 UINT32* volatile g_pSockCapacityValue = 0;
-BOOL             g_bNoAutoRestart        = FALSE;
-BOOL             g_bForceRestart         = FALSE;
-BOOL g_bUnsupportedOSFlag = FALSE;
+BOOL g_bNoAutoRestart = FALSE;
+BOOL g_bForceRestart = FALSE;
+HXBOOL g_bForceHighMemory = FALSE;
 
 HX_MUTEX g_pServerMainLock;
 
@@ -4710,7 +4710,9 @@
 "--nss       --no-segv-syscall\n"
 "--gdb                                   Work properly with gdb\n"
 "--sdt       --shared-descriptor-tables  Share Descriptor Tables among threads\n"
-"--unsupported-os                        Attempt to run even if unsupported/incompatable OS\n"
+#if defined(_LONG_IS_64) && defined(_LINUX)
+"--fhm       --force-high-memory         Force memory segment above 4GB\n"
+#endif
 #endif //XXX_INTERNAL_FLAGS
 #endif
 
@@ -5505,10 +5507,15 @@
                 g_ullSizemmap = MIN_SHMEM_SIZE;
             }
         }
-        else if (!strcmp(*arg, "--unsupported-os"))
+        else if (!strcmp(*arg, "--force-high-memory") ||
+                 !strcmp(*arg, "--fhm"))
         {
-            suprintf("Option: Unsupported OS\n");
-            g_bUnsupportedOSFlag = TRUE;
+            suprintf("Option: Force High Memory\n");
+#if defined(_LONG_IS_64) && defined(_LINUX)
+            g_bForceHighMemory = TRUE;
+#else
+            suprintf("%s is not available on this platform (ignoring)\n", *arg);
+#endif
         }
 
 


_______________________________________________
Server-cvs mailing list
Server-cvs@helixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/server-cvs
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic