From: "Roy.Li" <rongqing.li@xxxxxxxxxxxxx> On a number of arches, any fixed and shared mmap() mapping address must be aligned to 16k, or MIPS cpu askes that the address must be aligned to not violate cache aliasing constraints. If we create a shared memory like below: addr_orig = mmap (NULL, bytes, PROT_NONE, MAP_ANONYMOUS| MAP_PRIVATE, -1, 0); addr = mmap (addr_orig, bytes, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0); If the first mmap() upper is not shared then the first mmap() will succeed because these restrictions do not apply to private mappings. The second mmap() wants a shared memory mapping but the address returned by the first one is only page-aligned and not aligned to 16k, or violate cache aliasing constraints on MIPS cpu, will lead to second mmap failure. Signed-off-by: Roy.Li <rongqing.li@xxxxxxxxxxxxx> --- configure.ac | 25 +++++++++++++++++++++++++ exec/cpg.c | 13 +++++++++---- lib/cpg.c | 10 ++++++++-- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 523d2cf..d3a9c25 100644 --- a/configure.ac +++ b/configure.ac @@ -647,6 +647,31 @@ else AC_SUBST(VERSCRIPT_LDFLAGS, [""]) fi +arch_force_shmlba=no +AC_MSG_CHECKING([for architecture in ${host_cpu}]) +case $host_cpu in + sparc*) + AC_MSG_RESULT([${host_cpu}]) + arch_force_shmlba=yes + ;; + arm*) + AC_MSG_RESULT([${host_cpu}]) + arch_force_shmlba=yes + ;; + mips*) + AC_MSG_RESULT([${host_cpu}]) + arch_force_shmlba=yes + ;; + *) + AC_MSG_RESULT([${host_cpu}]) + ;; +esac + +if test $arch_force_shmlba = yes; then + AC_DEFINE_UNQUOTED([FORCE_SHM_ALIGN], [1], + [shared and fixed mmap must align on cache alias or 16k]) +fi + # define global include dirs INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include -I\$(top_srcdir)/include" INCLUDE_DIRS="$INCLUDE_DIRS -I\$(top_builddir)/include/corosync -I\$(top_srcdir)/include/corosync" diff --git a/exec/cpg.c b/exec/cpg.c index 695f311..04260e0 100644 --- a/exec/cpg.c +++ b/exec/cpg.c @@ -1606,6 +1606,7 @@ memory_map ( void *addr_orig; void *addr; int32_t res; + int flags = MAP_ANONYMOUS; fd = open (path, O_RDWR, 0600); @@ -1620,15 +1621,19 @@ memory_map ( goto error_close_unlink; } - addr_orig = mmap (NULL, bytes, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +#ifdef FORCE_SHM_ALIGN + flags |= MAP_SHARED; +#else + flags |= MAP_PRIVATE; +#endif /* FORCE_SHM_ALIGN */ + + addr_orig = mmap (NULL, bytes, PROT_NONE, flags, -1, 0); if (addr_orig == MAP_FAILED) { goto error_close_unlink; } - addr = mmap (addr_orig, bytes, PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd, 0); + addr = mmap (addr_orig, bytes, PROT_READ | PROT_WRITE, flags, fd, 0); if (addr != addr_orig) { munmap(addr_orig, bytes); diff --git a/lib/cpg.c b/lib/cpg.c index b96df4e..7cc3ce9 100644 --- a/lib/cpg.c +++ b/lib/cpg.c @@ -737,6 +737,7 @@ memory_map (char *path, const char *file, void **buf, size_t bytes) int32_t i; size_t written; size_t page_size; + int flags = MAP_ANONYMOUS; snprintf (path, PATH_MAX, "/dev/shm/%s", file); @@ -772,8 +773,13 @@ retry_write: } free (buffer); - addr_orig = mmap (NULL, bytes, PROT_NONE, - MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +#ifdef FORCE_SHM_ALIGN + flags |= MAP_SHARED; +#else + flags |= MAP_PRIVATE; +#endif /* FORCE_SHM_ALIGN */ + + addr_orig = mmap (NULL, bytes, PROT_NONE, flags, -1, 0); if (addr_orig == MAP_FAILED) { goto error_close_unlink; -- 1.7.10.4 _______________________________________________ discuss mailing list discuss@xxxxxxxxxxxx http://lists.corosync.org/mailman/listinfo/discuss