List:Commits« Previous MessageNext Message »
From:Kelly Long Date:July 29 2009 4:35pm
Subject:bzr commit into mysql-5.4 branch (k.long:2873)
View as plain text  
#At file:///FC/MYSQL/wa-2008-BZR/lcl/mysql-summit-0.3-innodb_plugin/ based on revid:k.long@stripped

 2873 Kelly Long	2009-07-29
      Large page size for innodb_plugin
      Large page size fixes for Solaris

    modified:
      configure.in
      include/my_sys.h
      mysys/my_largepage.c
      mysys/my_static.c
      sql/mysqld.cc
      storage/innobase/os/os0proc.c
      storage/innodb_plugin/handler/ha_innodb.cc
      storage/innodb_plugin/include/os0proc.h
      storage/innodb_plugin/os/os0proc.c
=== modified file 'configure.in'
--- a/configure.in	2009-07-28 22:09:19 +0000
+++ b/configure.in	2009-07-29 16:34:17 +0000
@@ -862,8 +862,6 @@ then
   AC_CHECK_DECLS(SHM_HUGETLB, 
       AC_DEFINE([HAVE_LARGE_PAGES], [1], 
                 [Define if you have large pages support])
-      AC_DEFINE([HAVE_LARGE_PAGE_OPTION], [1], 
-                [Define if you have large page option])
       AC_DEFINE([HUGETLB_USE_PROC_MEMINFO], [1],
                 [Define if /proc/meminfo shows the huge page size (Linux only)])
       , ,
@@ -872,19 +870,15 @@ then
       ]
   )
 else
-# For large pages support on Solaris
-AC_CHECK_DECLS(MHA_MAPSIZE_VA,
-      AC_DEFINE([HAVE_SOLARIS_LARGE_PAGES], [1],
-                [Define to 1 if you have large pages support])
-      AC_DEFINE([HAVE_LARGE_PAGE_OPTION], [1], 
-                [Define if you have large page option])
+  # Solaris supports LARGE_PAGES.  Use SHM_SHARE_MMU to determine Solaris.
+  AC_CHECK_DECLS(SHM_SHARE_MMU, 
+      AC_DEFINE([HAVE_LARGE_PAGES], [1], 
+                [Define if you have large pages support])
       , ,
       [
-#include <sys/mman.h>
+#include <sys/shm.h>
       ]
-)
-
-
+  )
 fi
 
 #--------------------------------------------------------------------

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2009-03-24 13:58:52 +0000
+++ b/include/my_sys.h	2009-07-29 16:34:17 +0000
@@ -171,12 +171,14 @@ extern char *my_strndup(const char *from
 #define TRASH(A,B) /* nothing */
 #endif
 
-#ifdef HAVE_LARGE_PAGES
+#ifdef HUGETLB_USE_PROC_MEMINFO
 extern uint my_get_large_page_size(void);
+#endif /* HUGETLB_USE_PROC_MEMINFO */
+
+#ifdef HAVE_LARGE_PAGES
 extern uchar * my_large_malloc(size_t size, myf my_flags);
 extern void my_large_free(uchar * ptr, myf my_flags);
-#else
-#define my_get_large_page_size() (0)
+#else /* HAVE_LARGE_PAGES */
 #define my_large_malloc(A,B) my_malloc_lock((A),(B))
 #define my_large_free(A,B) my_free_lock((A),(B))
 #endif /* HAVE_LARGE_PAGES */
@@ -218,7 +220,7 @@ extern ulong my_thread_stack_size;
 #ifdef HAVE_LARGE_PAGES
 extern my_bool my_use_large_pages;
 extern uint    my_large_page_size;
-#endif
+#endif /* HAVE_LARGE_PAGES */
 
 /* charsets */
 extern CHARSET_INFO *default_charset_info;

=== modified file 'mysys/my_largepage.c'
--- a/mysys/my_largepage.c	2007-10-02 07:32:33 +0000
+++ b/mysys/my_largepage.c	2009-07-29 16:34:17 +0000
@@ -25,12 +25,15 @@
 #include <sys/shm.h>
 #endif
 
+#ifdef HUGETLB_USE_PROC_MEMINFO
 static uint my_get_large_page_size_int(void);
+#endif /* HUGETLB_USE_PROC_MEMINFO */
 static uchar* my_large_malloc_int(size_t size, myf my_flags);
 static my_bool my_large_free_int(uchar* ptr, myf my_flags);
 
 /* Gets the size of large pages from the OS */
 
+#ifdef HUGETLB_USE_PROC_MEMINFO
 uint my_get_large_page_size(void)
 {
   uint size;
@@ -41,6 +44,7 @@ uint my_get_large_page_size(void)
 
   DBUG_RETURN(size);
 }
+#endif /* HUGETLB_USE_PROC_MEMINFO */
 
 /*
   General large pages allocator.
@@ -89,7 +93,7 @@ void my_large_free(uchar* ptr, myf my_fl
 #ifdef HUGETLB_USE_PROC_MEMINFO
 /* Linux-specific function to determine the size of large pages */
 
-uint my_get_large_page_size_int(void)
+static uint my_get_large_page_size_int(void)
 {
   FILE *f;
   uint size = 0;
@@ -111,9 +115,18 @@ finish:
 #endif /* HUGETLB_USE_PROC_MEMINFO */
 
 #if HAVE_DECL_SHM_HUGETLB
-/* Linux-specific large pages allocator  */
+ #define SHMGET_FLAG SHM_HUGETLB  /* Linux way of getting large pages */
+#else
+ #define SHMGET_FLAG 0
+#endif
+
+#ifdef SHM_SHARE_MMU
+ #define SHMMAT_FLAG SHM_SHARE_MMU /* Solaris ISM */
+#else
+ #define SHMMAT_FLAG 0
+#endif
     
-uchar* my_large_malloc_int(size_t size, myf my_flags)
+static uchar* my_large_malloc_int(size_t size, myf my_flags)
 {
   int shmid;
   uchar* ptr;
@@ -123,7 +136,7 @@ uchar* my_large_malloc_int(size_t size, 
   /* Align block size to my_large_page_size */
   size = ((size - 1) & ~(my_large_page_size - 1)) + my_large_page_size;
   
-  shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W);
+  shmid = shmget(IPC_PRIVATE, size, SHMGET_FLAG | SHM_R | SHM_W);
   if (shmid < 0)
   {
     if (my_flags & MY_WME)
@@ -134,7 +147,8 @@ uchar* my_large_malloc_int(size_t size, 
     DBUG_RETURN(NULL);
   }
 
-  ptr = (uchar*) shmat(shmid, NULL, 0);
+  ptr = (uchar*) shmat(shmid, NULL, SHMMAT_FLAG);
+
   if (ptr == (uchar *) -1)
   {
     if (my_flags& MY_WME)
@@ -161,6 +175,4 @@ my_bool my_large_free_int(uchar *ptr, my
   DBUG_ENTER("my_large_free_int");
   DBUG_RETURN(shmdt(ptr) == 0);
 }
-#endif /* HAVE_DECL_SHM_HUGETLB */
-
 #endif /* HAVE_LARGE_PAGES */

=== modified file 'mysys/my_static.c'
--- a/mysys/my_static.c	2009-02-13 16:41:47 +0000
+++ b/mysys/my_static.c	2009-07-29 16:34:17 +0000
@@ -63,7 +63,7 @@ uint	  my_once_extra=ONCE_ALLOC_INIT;	/*
 #ifdef HAVE_LARGE_PAGES
 my_bool my_use_large_pages= 0;
 uint    my_large_page_size= 0;
-#endif
+#endif /* HAVE_LARGE_PAGES */
 
 	/* from safe_malloc */
 uint sf_malloc_prehunc=0,		/* If you have problem with core- */

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-07-01 12:36:40 +0000
+++ b/sql/mysqld.cc	2009-07-29 16:34:17 +0000
@@ -130,15 +130,22 @@ extern "C" {					// Because of SCO 3.2V4
 #define SIGNAL_FMT "signal %d"
 #endif
 
-#ifdef HAVE_SOLARIS_LARGE_PAGES
-#include <sys/mman.h>
-#if defined(__sun__) && defined(__GNUC__) && defined(__cplusplus) \
-    && defined(_XOPEN_SOURCE)
+#ifdef HAVE_LARGE_PAGES
+#  define LARGE_PAGESIZE (4*(1024*1024))
+#  if defined(__sun__)
+#    define SUPER_LARGE_PAGESIZE (256*(1024*1024))
+/*
+SunOS Nehalem-Sol 5.10 Generic_137138-09 i86pc i386 i86pc
+System Configuration:  Sun Microsystems  i86pc
+Memory size: 12277 Megabytes
+---> 2MB
+*/
+#    include <sys/mman.h>
+/* WHY DO WE HAVE TO DECLARE THESE TWO?  They ARE in sys/mman.h -- KEL */
 extern int getpagesizes(size_t *, int);
-extern int getpagesizes2(size_t *, int);
 extern int memcntl(caddr_t, size_t, int, caddr_t, int, int);
-#endif /* __sun__ ... */
-#endif /* HAVE_SOLARIS_LARGE_PAGES */
+#  endif /* __sun__ */
+#endif /* HAVE_LARGE_PAGES */
 
 #ifdef __NETWARE__
 #define zVOLSTATE_ACTIVE 6
@@ -3274,75 +3281,96 @@ static int init_common_variables(const c
   DBUG_PRINT("info",("%s  Ver %s for %s on %s\n",my_progname,
 		     server_version, SYSTEM_TYPE,MACHINE_TYPE));
 
+  /* assume NOT using large pages.... prove we can use them */
+  my_use_large_pages = 0;
+  my_large_page_size = 0;
+  opt_large_page_size = 0;
+
 #ifdef HAVE_LARGE_PAGES
-  /* Initialize large page size */
-  if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
-  {
-      DBUG_PRINT("info", ("Large page set, large_page_size = %d",
-                 opt_large_page_size));
-      my_use_large_pages= 1;
-      my_large_page_size= opt_large_page_size;
+#  ifdef HUGETLB_USE_PROC_MEMINFO
+  /* NOTE: If this is more than 4M we'll use it. This is NOT what is documented. */
+  if (opt_large_pages && (opt_large_page_size = my_get_large_page_size()) )
+  {
+    /* Initialize large page size */
+    my_large_page_size = opt_large_page_size;
+    my_use_large_pages = 1;
   }
   else
   {
-    opt_large_pages= 0;
     /* 
-       Either not configured to use large pages or Linux haven't
-       been compiled with large page support
+      Either not configured to use large pages or the current Linux kernel
+      was NOT compiled with large page support
     */
+    my_large_page_size = 0;
   }
-#endif /* HAVE_LARGE_PAGES */
-#ifdef HAVE_SOLARIS_LARGE_PAGES
-#define LARGE_PAGESIZE (4*1024*1024)  /* 4MB */
-#define SUPER_LARGE_PAGESIZE (256*1024*1024)  /* 256MB */
-  if (opt_large_pages)
+#  endif /* HUGETLB_USE_PROC_MEMINFO */
+
+#  ifdef __sun__
+  if (opt_large_pages || opt_super_large_pages)
   {
   /*
-    tell the kernel that we want to use 4/256MB page for heap storage
-    and also for the stack. We use 4 MByte as default and if the
-    super-large-page is set we increase it to 256 MByte. 256 MByte
-    is for server installations with GBytes of RAM memory where
+    tell the kernel that we want to use large pages for heap storage
+    and also for the stack. We start at 256 MByte and step down until we
+    find a value that succeeds.
+
+    256 MByte is for server installations with GBytes of RAM memory where
     the MySQL Server will have page caches and other memory regions
     measured in a number of GBytes.
-    We use as big pages as possible which isn't bigger than the above
-    desired page sizes.
+
+    We use as big pages as possible.
   */
-   int nelem;
-   int max_desired_page_size;
-   int max_page_size;
-   if (opt_super_large_pages)
-     max_page_size= SUPER_LARGE_PAGESIZE;
-   else
-     max_page_size= LARGE_PAGESIZE;
-   nelem = getpagesizes(NULL, 0);
-   if (nelem > 0)
-   {
-     size_t *pagesize = (size_t *) malloc(sizeof(size_t) * nelem);
-     if (pagesize != NULL && getpagesizes(pagesize, nelem) > 0)
-     {
-       size_t i, max_page_size= 0;
-       for (i= 0; i < nelem; i++)
-       {
-         if (pagesize[i] > max_page_size &&
-             pagesize[i] <= max_desired_page_size)
-            max_page_size= pagesize[i];
-       }
-       free(pagesize);
-       if (max_page_size > 0)
-       {
-         struct memcntl_mha mpss;
+  int num_elem;
 
-         mpss.mha_cmd= MHA_MAPSIZE_BSSBRK;
-         mpss.mha_pagesize= max_page_size;
-         mpss.mha_flags= 0;
-         memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
-         mpss.mha_cmd= MHA_MAPSIZE_STACK;
-         memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
-       }
-     }
-   }
+  num_elem = getpagesizes(NULL, 0);
+  if (num_elem > 0)
+  {
+    int i;
+    size_t *pagesize = (size_t *) malloc(sizeof(size_t) * num_elem);
+
+    if ((pagesize != NULL) && (getpagesizes(pagesize, num_elem) > 0))
+    {
+      size_t max_desired_page_size, max_page_size = 0;
+
+      if (!opt_super_large_pages)
+        max_desired_page_size = LARGE_PAGESIZE;
+      else
+        max_desired_page_size = SUPER_LARGE_PAGESIZE;
+
+    for (i = 0; i < num_elem; i++)
+    {
+      if (pagesize[i] > max_page_size &&
+          pagesize[i] <= max_desired_page_size)
+            max_page_size = pagesize[i];
+    }
+    free(pagesize);
+
+    if (max_page_size > 0)
+    {
+      struct memcntl_mha mpss;
+
+      my_use_large_pages = 1;
+      my_large_page_size = opt_large_page_size = max_page_size;
+
+      mpss.mha_cmd= MHA_MAPSIZE_BSSBRK;
+      mpss.mha_pagesize= my_large_page_size;
+      mpss.mha_flags= 0;
+      memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
+
+      mpss.mha_cmd= MHA_MAPSIZE_STACK;
+      memcntl(NULL, 0, MC_HAT_ADVISE, (caddr_t)&mpss, 0, 0);
+    }
+    }
   }
-#endif /* HAVE_SOLARIS_LARGE_PAGES */
+  }
+#endif /* __sun__ */
+  if (my_use_large_pages == 1)
+    DBUG_PRINT("info", ("Large page set, large_page_size = %d",
+        my_large_page_size));
+  else
+    DBUG_PRINT("info", ("Large page NOT set"));
+#else /* HAVE_LARGE_PAGES */
+    DBUG_PRINT("info", ("Not Large page compatible"));
+#endif /* HAVE_LARGE_PAGES */
 
   /* connections and databases needs lots of files */
   {
@@ -5919,17 +5947,17 @@ struct my_option my_long_options[] =
   {"general_log", OPT_GENERAL_LOG,
    "Enable|disable general log", (uchar**) &opt_log,
    (uchar**) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-#ifdef HAVE_LARGE_PAGE_OPTION
+#ifdef HAVE_LARGE_PAGES
   {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
 Disable with --skip-large-pages.",
    (uchar**) &opt_large_pages, (uchar**) &opt_large_pages, 0, GET_BOOL,
-   NO_ARG, 0, 0, 1, 0, 1, 0},
+   NO_ARG, 0, 0, 0, 0, 0, 0},
   {"super-large-pages", OPT_ENABLE_SUPER_LARGE_PAGES,
    "Enable support for super large pages. \
 Disable with --skip-super-large-pages.",
    (uchar**) &opt_super_large_pages, (uchar**) &opt_super_large_pages, 0,
    GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-#endif
+#endif /* HAVE_LARGE_PAGES */
   {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
    "Disable initialization of builtin InnoDB plugin",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},

=== modified file 'storage/innobase/os/os0proc.c'
--- a/storage/innobase/os/os0proc.c	2006-09-05 01:52:15 +0000
+++ b/storage/innobase/os/os0proc.c	2009-07-29 16:34:17 +0000
@@ -15,6 +15,9 @@ Created 9/30/1995 Heikki Tuuri
 #include "ut0mem.h"
 #include "ut0byte.h"
 
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif /* HAVE_SYS_SHM_H */
 
 /*
 How to get AWE to compile on Windows?

=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc	2009-07-28 22:26:01 +0000
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	2009-07-29 16:34:17 +0000
@@ -2162,9 +2162,9 @@ innobase_change_buffering_inited_ok:
 	srv_use_checksums = (ibool) innobase_use_checksums;
 
 #ifdef HAVE_LARGE_PAGES
-        if ((os_use_large_pages = (ibool) my_use_large_pages))
+	if ((os_use_large_pages = (ibool) my_use_large_pages))
 		os_large_page_size = (ulint) opt_large_page_size;
-#endif
+#endif /* HAVE_LARGE_PAGES */
 
 	row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
 

=== modified file 'storage/innodb_plugin/include/os0proc.h'
--- a/storage/innodb_plugin/include/os0proc.h	2009-07-28 21:03:58 +0000
+++ b/storage/innodb_plugin/include/os0proc.h	2009-07-29 16:34:17 +0000
@@ -29,11 +29,6 @@ Created 9/30/1995 Heikki Tuuri
 
 #include "univ.i"
 
-#ifdef UNIV_LINUX
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif
-
 typedef void*			os_process_t;
 typedef unsigned long int	os_process_id_t;
 

=== modified file 'storage/innodb_plugin/os/os0proc.c'
--- a/storage/innodb_plugin/os/os0proc.c	2009-07-28 21:03:58 +0000
+++ b/storage/innodb_plugin/os/os0proc.c	2009-07-29 16:34:17 +0000
@@ -40,6 +40,28 @@ MAP_ANON but MAP_ANON is marked as depre
 #define OS_MAP_ANON	MAP_ANON
 #endif
 
+#ifdef HAVE_SYS_SHM_H
+#include <sys/shm.h>
+#endif /* HAVE_SYS_SHM_H */
+
+#if defined(SHM_HUGETLB) && defined(UNIV_LINUX)
+#  define SHMGET_FLAG SHM_HUGETLB  /* Linux way of getting large pages */
+#else /* SHM_HUGETLB  && UNIV_LINUX*/
+#  if defined(UNIV_SOLARIS)
+#    define SHMGET_FLAG IPC_CREAT
+#    if defined(SHM_SHARE_MMU)
+#      define SHMAT_FLAG SHM_SHARE_MMU /* Solaris Intimate shared memory */
+#    endif /* SHM_SHARE_MMU */
+#  endif /* UNIV_SOLARIS */
+#endif /* SHMGET_FLAG  && UNIV_LINUX*/
+
+#ifndef SHMGET_FLAG
+#  define SHMGET_FLAG 0
+#endif /* SHMGET_FLAG */
+#ifndef SHMAT_FLAG
+#  define SHMAT_FLAG 0
+#endif /* SHMAT_FLAG */
+
 UNIV_INTERN ibool os_use_large_pages;
 /* Large page size. This may be a boot-time option on some platforms */
 UNIV_INTERN ulint os_large_page_size;
@@ -73,7 +95,7 @@ os_mem_alloc_large(
 {
 	void*	ptr;
 	ulint	size;
-#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
+#if (defined(HAVE_LARGE_PAGES) && defined(UNIV_LINUX)) || defined(UNIV_SOLARIS)
 	int shmid;
 	struct shmid_ds buf;
 
@@ -84,15 +106,17 @@ os_mem_alloc_large(
 	/* Align block size to os_large_page_size */
 	ut_ad(ut_is_2pow(os_large_page_size));
 	size = ut_2pow_round(*n + (os_large_page_size - 1),
-			     os_large_page_size);
+				os_large_page_size);
 
-	shmid = shmget(IPC_PRIVATE, (size_t)size, SHM_HUGETLB | SHM_R | SHM_W);
+	shmid = shmget(IPC_PRIVATE, (size_t)size, SHMGET_FLAG | SHM_R | SHM_W);
 	if (shmid < 0) {
-		fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to allocate"
-			" %lu bytes. errno %d\n", size, errno);
+		fprintf(stderr, "InnoDBKEL: HugeTLB: Warning: Failed to allocate"
+			" %lu bytes, size=%lu, os_large_page_size=%lu. errno %d\n", *n, size, os_large_page_size, errno);
 		ptr = NULL;
 	} else {
-		ptr = shmat(shmid, NULL, 0);
+		fprintf(stderr, "InnoDBKEL: HugeTLB: allocated"
+			" %lu bytes, size=%lu, os_large_page_size=%lu. errno %d\n", *n, size, os_large_page_size, errno);
+		ptr = shmat(shmid, NULL, SHMAT_FLAG);
 		if (ptr == (void *)-1) {
 			fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to"
 				" attach shared memory segment, errno %d\n",
@@ -120,7 +144,7 @@ os_mem_alloc_large(
 	fprintf(stderr, "InnoDB HugeTLB: Warning: Using conventional"
 		" memory pool\n");
 skip:
-#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
+#endif /* (defined(HAVE_LARGE_PAGES) && defined(UNIV_LINUX)) || defined(UNIV_SOLARIS) */
 
 #ifdef __WIN__
 	SYSTEM_INFO	system_info;
@@ -188,7 +212,7 @@ os_mem_free_large(
 	ut_a(ut_total_allocated_memory >= size);
 	os_fast_mutex_unlock(&ut_list_mutex);
 
-#if defined HAVE_LARGE_PAGES && defined UNIV_LINUX
+#if (defined(HAVE_LARGE_PAGES) && defined(UNIV_LINUX)) || defined(UNIV_SOLARIS)
 	if (os_use_large_pages && os_large_page_size && !shmdt(ptr)) {
 		os_fast_mutex_lock(&ut_list_mutex);
 		ut_a(ut_total_allocated_memory >= size);
@@ -197,7 +221,7 @@ os_mem_free_large(
 		UNIV_MEM_FREE(ptr, size);
 		return;
 	}
-#endif /* HAVE_LARGE_PAGES && UNIV_LINUX */
+#endif /* (defined(HAVE_LARGE_PAGES) && defined(UNIV_LINUX)) || defined(UNIV_SOLARIS) */
 #ifdef __WIN__
 	/* When RELEASE memory, the size parameter must be 0.
 	Do not use MEM_RELEASE with MEM_DECOMMIT. */


Attachment: [text/bzr-bundle] bzr/k.long@sun.com-20090729163417-kwjmo9r7h6cm3ojr.bundle
Thread
bzr commit into mysql-5.4 branch (k.long:2873) Kelly Long29 Jul