From e50a99629e089bbe71a8d5f2cd5277eb935dbab1 Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Mon, 23 Sep 2024 11:33:11 +0200 Subject: [PATCH 1/2] Rename devdax.yml to dax.yml Rename devdax.yml to dax.yml and add info about FSDAX. Signed-off-by: Lukasz Dorau --- .github/workflows/{devdax.yml => dax.yml} | 40 +++++++++++++++-------- .github/workflows/pr_push.yml | 2 +- 2 files changed, 27 insertions(+), 15 deletions(-) rename .github/workflows/{devdax.yml => dax.yml} (62%) diff --git a/.github/workflows/devdax.yml b/.github/workflows/dax.yml similarity index 62% rename from .github/workflows/devdax.yml rename to .github/workflows/dax.yml index e8a4dc3bd..db4e5768e 100644 --- a/.github/workflows/devdax.yml +++ b/.github/workflows/dax.yml @@ -1,9 +1,20 @@ -# This workflow builds and tests the devdax memory provider. -# It requires a DAX device (e.g. /dev/dax0.0) configured in the OS. -# This DAX device should be specified using the +# +# This workflow builds and tests the DEVDAX memory provider +# and the file memory provider with FSDAX. +# It requires: +# - a DAX device (e.g. /dev/dax0.0) and +# - a FSDAX device (e.g. /dev/pmem1) +# configured and mounted in the OS. +# +# The DAX device should be specified using the # UMF_TESTS_DEVDAX_PATH and UMF_TESTS_DEVDAX_SIZE environment variables. +# +# The FSDAX device should be mounted in the OS (e.g. /mnt/pmem1) +# and the UMF_TESTS_FSDAX_PATH environment variable +# should contain a path to a file o this FSDAX device. +# -name: DevDax +name: Dax on: [workflow_call] @@ -11,12 +22,12 @@ permissions: contents: read env: - UMF_TESTS_DEVDAX_NAMESPACE : "0.0" + DEVDAX_NAMESPACE : "0.0" BUILD_DIR : "${{github.workspace}}/build" INSTL_DIR : "${{github.workspace}}/../install-dir" jobs: - devdax: + dax: name: Build # run only on upstream; forks may not have a DAX device if: github.repository == 'oneapi-src/unified-memory-framework' @@ -27,12 +38,13 @@ jobs: runs-on: ["DSS-DEVDAX", "DSS-Ubuntu"] steps: - - name: Check if the devdax exists, print out UMF_TESTS_DEVDAX_PATH and UMF_TESTS_DEVDAX_SIZE + - name: Check configuration of the DEVDAX run: | - ndctl list -N --device-dax - ls -al /dev/dax${UMF_TESTS_DEVDAX_NAMESPACE} - echo UMF_TESTS_DEVDAX_PATH="/dev/dax${UMF_TESTS_DEVDAX_NAMESPACE}" - echo UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${UMF_TESTS_DEVDAX_NAMESPACE} | grep size | cut -d':' -f2 | cut -d',' -f1)" + echo DEVDAX_NAMESPACE="${{env.DEVDAX_NAMESPACE}}" + ndctl list --namespace=namespace${{env.DEVDAX_NAMESPACE}} --device-dax + ls -al /dev/dax${{env.DEVDAX_NAMESPACE}} + echo UMF_TESTS_DEVDAX_PATH="/dev/dax${{env.DEVDAX_NAMESPACE}}" + echo UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${{env.DEVDAX_NAMESPACE}} | grep size | cut -d':' -f2 | cut -d',' -f1)" - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 @@ -62,9 +74,9 @@ jobs: - name: Build UMF run: cmake --build ${{env.BUILD_DIR}} --config ${{matrix.build_type}} -j $(nproc) - - name: Run only devdax tests + - name: Run the DEVDAX tests working-directory: ${{env.BUILD_DIR}} run: > - UMF_TESTS_DEVDAX_PATH="/dev/dax${UMF_TESTS_DEVDAX_NAMESPACE}" - UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${UMF_TESTS_DEVDAX_NAMESPACE} | grep size | cut -d':' -f2 | cut -d',' -f1)" + UMF_TESTS_DEVDAX_PATH="/dev/dax${{env.DEVDAX_NAMESPACE}}" + UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${{env.DEVDAX_NAMESPACE}} | grep size | cut -d':' -f2 | cut -d',' -f1)" ctest -C ${{matrix.build_type}} -R devdax -V diff --git a/.github/workflows/pr_push.yml b/.github/workflows/pr_push.yml index 02b7adf9f..c921eced6 100644 --- a/.github/workflows/pr_push.yml +++ b/.github/workflows/pr_push.yml @@ -88,7 +88,7 @@ jobs: uses: ./.github/workflows/basic.yml DevDax: needs: [FastBuild] - uses: ./.github/workflows/devdax.yml + uses: ./.github/workflows/dax.yml Sanitizers: needs: [FastBuild] uses: ./.github/workflows/sanitizers.yml From 64de5507fb1b0cf58e979d826f344251f6c4a9a5 Mon Sep 17 00:00:00 2001 From: Lukasz Dorau Date: Tue, 24 Sep 2024 10:26:38 +0200 Subject: [PATCH 2/2] Add test if FSDAX is mapped with the MAP_SYNC flag Signed-off-by: Lukasz Dorau --- .github/workflows/dax.yml | 19 +++++++++ test/common/CMakeLists.txt | 4 ++ test/common/test_helpers_linux.c | 67 ++++++++++++++++++++++++++++++++ test/common/test_helpers_linux.h | 21 ++++++++++ test/provider_devdax_memory.cpp | 50 ++---------------------- test/provider_file_memory.cpp | 38 ++++++++++++++++++ 6 files changed, 153 insertions(+), 46 deletions(-) create mode 100644 test/common/test_helpers_linux.c create mode 100644 test/common/test_helpers_linux.h diff --git a/.github/workflows/dax.yml b/.github/workflows/dax.yml index db4e5768e..889825eaa 100644 --- a/.github/workflows/dax.yml +++ b/.github/workflows/dax.yml @@ -23,6 +23,9 @@ permissions: env: DEVDAX_NAMESPACE : "0.0" + FSDAX_NAMESPACE : "1.0" + FSDAX_PMEM: "pmem1" + UMF_TESTS_FSDAX_PATH: "/mnt/pmem1/file" BUILD_DIR : "${{github.workspace}}/build" INSTL_DIR : "${{github.workspace}}/../install-dir" @@ -46,6 +49,16 @@ jobs: echo UMF_TESTS_DEVDAX_PATH="/dev/dax${{env.DEVDAX_NAMESPACE}}" echo UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${{env.DEVDAX_NAMESPACE}} | grep size | cut -d':' -f2 | cut -d',' -f1)" + - name: Check configuration of the FSDAX + run: | + echo FSDAX_NAMESPACE="${{env.FSDAX_NAMESPACE}}" + echo UMF_TESTS_FSDAX_PATH="${{env.UMF_TESTS_FSDAX_PATH}}" + ndctl list --namespace=namespace${{env.FSDAX_NAMESPACE}} + ls -al /dev/${{env.FSDAX_PMEM}} /mnt/${{env.FSDAX_PMEM}} + mount | grep -e "/dev/${{env.FSDAX_PMEM}}" + touch ${{env.UMF_TESTS_FSDAX_PATH}} + rm -f ${{env.UMF_TESTS_FSDAX_PATH}} + - name: Checkout uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 with: @@ -80,3 +93,9 @@ jobs: UMF_TESTS_DEVDAX_PATH="/dev/dax${{env.DEVDAX_NAMESPACE}}" UMF_TESTS_DEVDAX_SIZE="$(ndctl list --namespace=namespace${{env.DEVDAX_NAMESPACE}} | grep size | cut -d':' -f2 | cut -d',' -f1)" ctest -C ${{matrix.build_type}} -R devdax -V + + - name: Run the FSDAX tests + working-directory: ${{env.BUILD_DIR}} + run: > + UMF_TESTS_FSDAX_PATH=${{env.UMF_TESTS_FSDAX_PATH}} + ctest -C ${{matrix.build_type}} -R umf-provider_file_memory -V diff --git a/test/common/CMakeLists.txt b/test/common/CMakeLists.txt index 4f88fd7d8..6cffe5cfe 100644 --- a/test/common/CMakeLists.txt +++ b/test/common/CMakeLists.txt @@ -9,6 +9,10 @@ set(COMMON_SOURCES provider_null.c provider_trace.c) +if(LINUX) + set(COMMON_SOURCES ${COMMON_SOURCES} test_helpers_linux.c) +endif(LINUX) + add_umf_library( NAME umf_test_common TYPE STATIC diff --git a/test/common/test_helpers_linux.c b/test/common/test_helpers_linux.c new file mode 100644 index 000000000..9f7606b09 --- /dev/null +++ b/test/common/test_helpers_linux.c @@ -0,0 +1,67 @@ +// Copyright (C) 2024 Intel Corporation +// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// This file contains tests for UMF pool API + +#include +#include +#include +#include +#include +#include + +#include "test_helpers_linux.h" + +// Check if the file given by the 'path' argument was mapped with the MAP_SYNC flag: +// 1) Open and read the /proc/self/smaps file. +// 2) Look for the section of the 'path' file. +// 3) Check if the VmFlags of the 'path' file contains the "sf" flag +// marking that the file was mapped with the MAP_SYNC flag. +bool is_mapped_with_MAP_SYNC(char *path, char *buf, size_t size_buf) { + memset(buf, 0, size_buf); + + int fd = open("/proc/self/smaps", O_RDONLY); + if (fd == -1) { + return false; + } + + // number of bytes read from the file + ssize_t nbytes = 1; + // string starting from the path of the smaps + char *smaps = NULL; + + // Read the "/proc/self/smaps" file + // until the path of the smaps is found + // or EOF is reached. + while (nbytes > 0 && smaps == NULL) { + memset(buf, 0, nbytes); // erase previous data + nbytes = read(fd, buf, size_buf); + // look for the path of the smaps + smaps = strstr(buf, path); + } + + // String starting from the "sf" flag + // marking that memory was mapped with the MAP_SYNC flag. + char *sf_flag = NULL; + + if (smaps) { + // look for the "VmFlags:" string + char *VmFlags = strstr(smaps, "VmFlags:"); + if (VmFlags) { + // look for the EOL + char *eol = strstr(VmFlags, "\n"); + if (eol) { + // End the VmFlags string at EOL. + *eol = 0; + // Now the VmFlags string contains only one line with all VmFlags. + + // Look for the "sf" flag in VmFlags + // marking that memory was mapped + // with the MAP_SYNC flag. + sf_flag = strstr(VmFlags, "sf"); + } + } + } + + return (sf_flag != NULL); +} diff --git a/test/common/test_helpers_linux.h b/test/common/test_helpers_linux.h new file mode 100644 index 000000000..7755408b7 --- /dev/null +++ b/test/common/test_helpers_linux.h @@ -0,0 +1,21 @@ +// Copyright (C) 2024 Intel Corporation +// Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// This file contains helpers for tests for UMF pool API + +#ifndef UMF_TEST_HELPERS_LINUX_H +#define UMF_TEST_HELPERS_LINUX_H 1 + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +bool is_mapped_with_MAP_SYNC(char *path, char *buf, size_t size_buf); + +#ifdef __cplusplus +} +#endif + +#endif /* UMF_TEST_HELPERS_LINUX_H */ diff --git a/test/provider_devdax_memory.cpp b/test/provider_devdax_memory.cpp index 1fdd53b08..6ed5f241e 100644 --- a/test/provider_devdax_memory.cpp +++ b/test/provider_devdax_memory.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #ifndef _WIN32 +#include "test_helpers_linux.h" #include #include #include @@ -11,6 +12,7 @@ #include "base.hpp" #include "cpp_helpers.hpp" +#include "test_helpers.h" #include #include @@ -137,10 +139,6 @@ static void test_alloc_failure(umf_memory_provider_handle_t provider, // TESTS // Test checking if devdax was mapped with the MAP_SYNC flag: -// 1) Open and read the /proc/self/smaps file. -// 2) Look for the section of the devdax (the /dev/daxX.Y path). -// 3) Check if the VmFlags of the /dev/daxX.Y contains the "sf" flag -// marking that the devdax was mapped with the MAP_SYNC flag. TEST_F(test, test_if_mapped_with_MAP_SYNC) { umf_memory_provider_handle_t hProvider = nullptr; umf_result_t umf_result; @@ -167,48 +165,8 @@ TEST_F(test, test_if_mapped_with_MAP_SYNC) { umf_result = umfMemoryProviderAlloc(hProvider, size, 0, (void **)&buf); ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); ASSERT_NE(buf, nullptr); - memset(buf, 0, size); - - int fd = open("/proc/self/smaps", O_RDONLY); - ASSERT_NE(fd, -1); - - // number of bytes read from the file - ssize_t nbytes = 1; - // string starting from the path of the devdax - char *devdax = nullptr; - - // Read the "/proc/self/smaps" file - // until the path of the devdax is found - // or EOF is reached. - while (nbytes > 0 && devdax == nullptr) { - memset(buf, 0, nbytes); // erase previous data - nbytes = read(fd, buf, size); - // look for the path of the devdax - devdax = strstr(buf, path); - } - // String starting from the "sf" flag - // marking that memory was mapped with the MAP_SYNC flag. - char *sf_flag = nullptr; - - if (devdax) { - // look for the "VmFlags:" string - char *VmFlags = strstr(devdax, "VmFlags:"); - if (VmFlags) { - // look for the EOL - char *eol = strstr(VmFlags, "\n"); - if (eol) { - // End the VmFlags string at EOL. - *eol = 0; - // Now the VmFlags string contains only one line with all VmFlags. - - // Look for the "sf" flag in VmFlags - // marking that memory was mapped - // with the MAP_SYNC flag. - sf_flag = strstr(VmFlags, "sf"); - } - } - } + bool flag_found = is_mapped_with_MAP_SYNC(path, buf, size); umf_result = umfMemoryProviderFree(hProvider, buf, size); ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED); @@ -216,7 +174,7 @@ TEST_F(test, test_if_mapped_with_MAP_SYNC) { umfMemoryProviderDestroy(hProvider); // fail test if the "sf" flag was not found - ASSERT_NE(sf_flag, nullptr); + ASSERT_EQ(flag_found, true); } // positive tests using test_alloc_free_success diff --git a/test/provider_file_memory.cpp b/test/provider_file_memory.cpp index 3903febe7..3ec7b849e 100644 --- a/test/provider_file_memory.cpp +++ b/test/provider_file_memory.cpp @@ -6,6 +6,9 @@ #include "cpp_helpers.hpp" #include "test_helpers.h" +#ifndef _WIN32 +#include "test_helpers_linux.h" +#endif #include #include @@ -121,6 +124,41 @@ static void test_alloc_failure(umf_memory_provider_handle_t provider, // TESTS +// Test checking if FSDAX was mapped with the MAP_SYNC flag: +TEST_F(test, test_if_mapped_with_MAP_SYNC) { + umf_memory_provider_handle_t hProvider = nullptr; + umf_result_t umf_result; + + char *path = getenv("UMF_TESTS_FSDAX_PATH"); + if (path == nullptr || path[0] == 0) { + GTEST_SKIP() << "Test skipped, UMF_TESTS_FSDAX_PATH is not set"; + } + + auto params = umfFileMemoryProviderParamsDefault(path); + params.visibility = UMF_MEM_MAP_SYNC; + + umf_result = umfMemoryProviderCreate(umfFileMemoryProviderOps(), ¶ms, + &hProvider); + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); + ASSERT_NE(hProvider, nullptr); + + char *buf; + size_t size = 2 * 1024 * 1024; // 2MB + umf_result = umfMemoryProviderAlloc(hProvider, size, 0, (void **)&buf); + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); + ASSERT_NE(buf, nullptr); + + bool flag_found = is_mapped_with_MAP_SYNC(path, buf, size); + + umf_result = umfMemoryProviderFree(hProvider, buf, size); + ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED); + + umfMemoryProviderDestroy(hProvider); + + // fail test if the "sf" flag was not found + ASSERT_EQ(flag_found, true); +} + // positive tests using test_alloc_free_success umf_file_memory_provider_params_t get_file_params_shared(char *path) {