#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 Long | 29 Jul |