This is an automated email from the ASF dual-hosted git repository.

robertnishihara pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git


The following commit(s) were added to refs/heads/master by this push:
     new af2047e  ARROW-2215: [Plasma] Hugetables munmap issue
af2047e is described below

commit af2047e5e2cccd0dec6e567e387fc85e600fb284
Author: Philipp Moritz <[email protected]>
AuthorDate: Wed Feb 28 16:43:40 2018 -0800

    ARROW-2215: [Plasma] Hugetables munmap issue
    
    Author: Philipp Moritz <[email protected]>
    
    Closes #1660 from pcmoritz/fix-huge-pages and squashes the following 
commits:
    
    4e933e1 [Philipp Moritz] linting
    91900ee [Philipp Moritz] fix
    aa939bd [Philipp Moritz] fix linting
    03da6f0 [Philipp Moritz] introduce constant
    61b705d [Philipp Moritz] only try to create huge pages on linux
    2b9a294 [Philipp Moritz] fixes
    6f124ce [Philipp Moritz] fix test
    49cf78f [Philipp Moritz] fix
    59ed734 [Philipp Moritz] add tests
    4ac737b [Philipp Moritz] linting
    adee028 [Philipp Moritz] test if hugepages can be activated on travis
    ea7aa11 [Philipp Moritz] fix hugetables munmap issue
---
 ci/travis_script_python.sh          |  8 ++++++++
 cpp/src/plasma/client.cc            | 11 ++++++++---
 cpp/src/plasma/malloc.cc            | 10 +++++-----
 cpp/src/plasma/malloc.h             |  6 ++++++
 python/pyarrow/tests/test_plasma.py | 18 +++++++++++++++++-
 5 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/ci/travis_script_python.sh b/ci/travis_script_python.sh
index 9ed5825..a776c42 100755
--- a/ci/travis_script_python.sh
+++ b/ci/travis_script_python.sh
@@ -96,6 +96,14 @@ if [ $ARROW_TRAVIS_VALGRIND == "1" ]; then
   export PLASMA_VALGRIND=1
 fi
 
+# Set up huge pages for plasma test
+if [ $TRAVIS_OS_NAME == "linux" ]; then
+    sudo mkdir -p /mnt/hugepages
+    sudo mount -t hugetlbfs -o uid=`id -u` -o gid=`id -g` none /mnt/hugepages
+    sudo bash -c "echo `id -g` > /proc/sys/vm/hugetlb_shm_group"
+    sudo bash -c "echo 20000 > /proc/sys/vm/nr_hugepages"
+fi
+
 PYARROW_PATH=$CONDA_PREFIX/lib/python$PYTHON_VERSION/site-packages/pyarrow
 python -m pytest -vv -r sxX --durations=15 -s $PYARROW_PATH --parquet
 
diff --git a/cpp/src/plasma/client.cc b/cpp/src/plasma/client.cc
index 679d9ce..a9bbd8c 100644
--- a/cpp/src/plasma/client.cc
+++ b/cpp/src/plasma/client.cc
@@ -45,6 +45,7 @@
 #include "plasma/common.h"
 #include "plasma/fling.h"
 #include "plasma/io.h"
+#include "plasma/malloc.h"
 #include "plasma/plasma.h"
 #include "plasma/protocol.h"
 
@@ -117,8 +118,10 @@ uint8_t* PlasmaClient::lookup_or_mmap(int fd, int 
store_fd_val, int64_t map_size
     close(fd);
     return entry->second.pointer;
   } else {
-    uint8_t* result = reinterpret_cast<uint8_t*>(
-        mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0));
+    // We subtract kMmapRegionsGap from the length that was added
+    // in fake_mmap in malloc.h, to make map_size page-aligned again.
+    uint8_t* result = reinterpret_cast<uint8_t*>(mmap(
+        NULL, map_size - kMmapRegionsGap, PROT_READ | PROT_WRITE, MAP_SHARED, 
fd, 0));
     // TODO(pcm): Don't fail here, instead return a Status.
     if (result == MAP_FAILED) {
       ARROW_LOG(FATAL) << "mmap failed";
@@ -395,7 +398,9 @@ Status PlasmaClient::UnmapObject(const ObjectID& object_id) 
{
   ARROW_CHECK(entry->second.count >= 1);
   if (entry->second.count == 1) {
     // If no other objects are being used, then unmap the file.
-    int err = munmap(entry->second.pointer, entry->second.length);
+    // We subtract kMmapRegionsGap from the length that was added
+    // in fake_mmap in malloc.h, to make the size page-aligned again.
+    int err = munmap(entry->second.pointer, entry->second.length - 
kMmapRegionsGap);
     if (err == -1) {
       return Status::IOError("Error during munmap");
     }
diff --git a/cpp/src/plasma/malloc.cc b/cpp/src/plasma/malloc.cc
index 3c5d107..e2403fd 100644
--- a/cpp/src/plasma/malloc.cc
+++ b/cpp/src/plasma/malloc.cc
@@ -127,10 +127,10 @@ int create_buffer(int64_t size) {
 }
 
 void* fake_mmap(size_t size) {
-  // Add sizeof(size_t) so that the returned pointer is deliberately not
+  // Add kMmapRegionsGap so that the returned pointer is deliberately not
   // page-aligned. This ensures that the segments of memory returned by
   // fake_mmap are never contiguous.
-  size += sizeof(size_t);
+  size += kMmapRegionsGap;
 
   int fd = create_buffer(size);
   ARROW_CHECK(fd >= 0) << "Failed to create buffer during mmap";
@@ -155,15 +155,15 @@ void* fake_mmap(size_t size) {
   record.size = size;
 
   // We lie to dlmalloc about where mapped memory actually lives.
-  pointer = pointer_advance(pointer, sizeof(size_t));
+  pointer = pointer_advance(pointer, kMmapRegionsGap);
   ARROW_LOG(DEBUG) << pointer << " = fake_mmap(" << size << ")";
   return pointer;
 }
 
 int fake_munmap(void* addr, int64_t size) {
   ARROW_LOG(DEBUG) << "fake_munmap(" << addr << ", " << size << ")";
-  addr = pointer_retreat(addr, sizeof(size_t));
-  size += sizeof(size_t);
+  addr = pointer_retreat(addr, kMmapRegionsGap);
+  size += kMmapRegionsGap;
 
   auto entry = mmap_records.find(addr);
 
diff --git a/cpp/src/plasma/malloc.h b/cpp/src/plasma/malloc.h
index cb8c600..c24f154 100644
--- a/cpp/src/plasma/malloc.h
+++ b/cpp/src/plasma/malloc.h
@@ -21,6 +21,12 @@
 #include <inttypes.h>
 #include <stddef.h>
 
+/// Gap between two consecutive mmap regions allocated by fake_mmap.
+/// This ensures that the segments of memory returned by
+/// fake_mmap are never contiguous and dlmalloc does not coalesce it
+/// (in the client we cannot guarantee that these mmaps are contiguous).
+constexpr int64_t kMmapRegionsGap = sizeof(size_t);
+
 void get_malloc_mapinfo(void* addr, int* fd, int64_t* map_length, ptrdiff_t* 
offset);
 
 /// Get the mmap size corresponding to a specific file descriptor.
diff --git a/python/pyarrow/tests/test_plasma.py 
b/python/pyarrow/tests/test_plasma.py
index 27556e6..0df627f 100644
--- a/python/pyarrow/tests/test_plasma.py
+++ b/python/pyarrow/tests/test_plasma.py
@@ -105,7 +105,8 @@ def assert_get_object_equal(unit_test, client1, client2, 
object_id,
 def start_plasma_store(plasma_store_memory=DEFAULT_PLASMA_STORE_MEMORY,
                        use_valgrind=False, use_profiler=False,
                        stdout_file=None, stderr_file=None,
-                       use_one_memory_mapped_file=False):
+                       use_one_memory_mapped_file=False,
+                       plasma_directory=None, use_hugepages=False):
     """Start a plasma store process.
     Args:
         use_valgrind (bool): True if the plasma store should be started inside
@@ -131,6 +132,10 @@ def 
start_plasma_store(plasma_store_memory=DEFAULT_PLASMA_STORE_MEMORY,
                "-m", str(plasma_store_memory)]
     if use_one_memory_mapped_file:
         command += ["-f"]
+    if plasma_directory:
+        command += ["-d", plasma_directory]
+    if use_hugepages:
+        command += ["-h"]
     if use_valgrind:
         pid = subprocess.Popen(["valgrind",
                                 "--track-origins=yes",
@@ -762,3 +767,14 @@ def test_object_id_size():
     with pytest.raises(ValueError):
         plasma.ObjectID("hello")
     plasma.ObjectID(20 * b"0")
+
+
[email protected](not os.path.exists("/mnt/hugepages"),
+                    reason="requires hugepage support")
+def test_use_huge_pages():
+    import pyarrow.plasma as plasma
+    plasma_store_name, p = start_plasma_store(
+        plasma_directory="/mnt/hugepages", use_hugepages=True)
+    plasma_client = plasma.connect(plasma_store_name, "", 64)
+    create_object(plasma_client, 100000000)
+    p.kill()

-- 
To stop receiving notification emails like this one, please contact
[email protected].

Reply via email to