[Linux] Use memfd_create when available in SharedMemory implementation
authorcarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 14:24:09 +0000 (14:24 +0000)
committercarlosgc@webkit.org <carlosgc@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Nov 2018 14:24:09 +0000 (14:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189741

Reviewed by Michael Catanzaro.

.:

Add include check for linux/memfd.h header.

* Source/cmake/OptionsCommon.cmake:

Source/WebKit:

If memfd is available, use it instead of shm_open.

* Platform/unix/SharedMemoryUnix.cpp:
(WebKit::createSharedMemory): Helper to create the shared memory, trying first with memfd and falling back to
shm if it's not available.
(WebKit::SharedMemory::create): Use createSharedMemory() helper.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237922 268f45cc-cd09-0410-ab3c-d52691b4dbfc

ChangeLog
Source/WebKit/ChangeLog
Source/WebKit/Platform/unix/SharedMemoryUnix.cpp
Source/cmake/OptionsCommon.cmake

index cb4efb2..c2d2b07 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2018-11-07  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [Linux] Use memfd_create when available in SharedMemory implementation
+        https://bugs.webkit.org/show_bug.cgi?id=189741
+
+        Reviewed by Michael Catanzaro.
+
+        Add include check for linux/memfd.h header.
+
+        * Source/cmake/OptionsCommon.cmake:
+
 2018-11-05  Dominik Infuehr  <dinfuehr@igalia.com>
 
         Enable LLInt on ARMv7/Linux
index ac7dfe5..b18c032 100644 (file)
@@ -1,3 +1,17 @@
+2018-11-07  Carlos Garcia Campos  <cgarcia@igalia.com>
+
+        [Linux] Use memfd_create when available in SharedMemory implementation
+        https://bugs.webkit.org/show_bug.cgi?id=189741
+
+        Reviewed by Michael Catanzaro.
+
+        If memfd is available, use it instead of shm_open.
+
+        * Platform/unix/SharedMemoryUnix.cpp:
+        (WebKit::createSharedMemory): Helper to create the shared memory, trying first with memfd and falling back to
+        shm if it's not available.
+        (WebKit::SharedMemory::create): Use createSharedMemory() helper.
+
 2018-11-06  Justin Fan  <justin_fan@apple.com>
 
         [WebGPU] Experimental prototype for WebGPURenderPipeline and WebGPUSwapChain
index 713dc35..c52c9c7 100644 (file)
 #include <wtf/text/CString.h>
 #include <wtf/text/WTFString.h>
 
+#if HAVE(LINUX_MEMFD_H)
+#include <linux/memfd.h>
+#include <sys/syscall.h>
+#endif
+
 namespace WebKit {
 
 SharedMemory::Handle::Handle()
@@ -106,11 +111,27 @@ static inline int accessModeMMap(SharedMemory::Protection protection)
     return PROT_READ | PROT_WRITE;
 }
 
-RefPtr<SharedMemory> SharedMemory::create(void* address, size_t size, Protection protection)
+static int createSharedMemory()
 {
-    CString tempName;
-
+#if HAVE(LINUX_MEMFD_H)
+    static bool isMemFdAvailable = true;
     int fileDescriptor = -1;
+    if (isMemFdAvailable) {
+        do {
+            fileDescriptor = syscall(__NR_memfd_create, "WebKitSharedMemory", MFD_CLOEXEC);
+        } while (fileDescriptor == -1 && errno == EINTR);
+
+        if (fileDescriptor != -1)
+            return fileDescriptor;
+
+        if (errno != ENOSYS)
+            return fileDescriptor;
+
+        isMemFdAvailable = false;
+    }
+#endif
+
+    CString tempName;
     for (int tries = 0; fileDescriptor == -1 && tries < 10; ++tries) {
         String name = String("/WK2SharedMemory.") + String::number(static_cast<unsigned>(WTF::randomNumber() * (std::numeric_limits<unsigned>::max() + 1.0)));
         tempName = name.utf8();
@@ -119,15 +140,24 @@ RefPtr<SharedMemory> SharedMemory::create(void* address, size_t size, Protection
             fileDescriptor = shm_open(tempName.data(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
         } while (fileDescriptor == -1 && errno == EINTR);
     }
+
+    if (fileDescriptor != -1)
+        shm_unlink(tempName.data());
+
+    return fileDescriptor;
+}
+
+RefPtr<SharedMemory> SharedMemory::create(void* address, size_t size, Protection protection)
+{
+    int fileDescriptor = createSharedMemory();
     if (fileDescriptor == -1) {
-        WTFLogAlways("Failed to create shared memory file %s: %s", tempName.data(), strerror(errno));
+        WTFLogAlways("Failed to create shared memory: %s", strerror(errno));
         return nullptr;
     }
 
     while (ftruncate(fileDescriptor, size) == -1) {
         if (errno != EINTR) {
             closeWithRetry(fileDescriptor);
-            shm_unlink(tempName.data());
             return nullptr;
         }
     }
@@ -135,12 +165,9 @@ RefPtr<SharedMemory> SharedMemory::create(void* address, size_t size, Protection
     void* data = mmap(address, size, accessModeMMap(protection), MAP_SHARED, fileDescriptor, 0);
     if (data == MAP_FAILED) {
         closeWithRetry(fileDescriptor);
-        shm_unlink(tempName.data());
         return nullptr;
     }
 
-    shm_unlink(tempName.data());
-
     RefPtr<SharedMemory> instance = adoptRef(new SharedMemory());
     instance->m_data = data;
     instance->m_fileDescriptor = fileDescriptor;
index 2740daa..3a43f5a 100644 (file)
@@ -122,6 +122,7 @@ WEBKIT_CHECK_HAVE_INCLUDE(HAVE_STRINGS_H strings.h)
 WEBKIT_CHECK_HAVE_INCLUDE(HAVE_SYS_PARAM_H sys/param.h)
 WEBKIT_CHECK_HAVE_INCLUDE(HAVE_SYS_TIME_H sys/time.h)
 WEBKIT_CHECK_HAVE_INCLUDE(HAVE_SYS_TIMEB_H sys/timeb.h)
+WEBKIT_CHECK_HAVE_INCLUDE(HAVE_LINUX_MEMFD_H linux/memfd.h)
 
 # Check for functions
 WEBKIT_CHECK_HAVE_FUNCTION(HAVE_ALIGNED_MALLOC _aligned_malloc)