Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add test if FSDAX is mapped with the MAP_SYNC flag #748

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions .github/workflows/dax.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#
# 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: Dax

on: [workflow_call]

permissions:
contents: read

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"

jobs:
dax:
name: Build
# run only on upstream; forks may not have a DAX device
if: github.repository == 'oneapi-src/unified-memory-framework'
strategy:
matrix:
build_type: [Debug, Release]
shared_library: ['ON', 'OFF']

runs-on: ["DSS-DEVDAX", "DSS-Ubuntu"]
steps:
- name: Check configuration of the DEVDAX
run: |
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: 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:
fetch-depth: 0

- name: Configure build
run: >
cmake
-B ${{env.BUILD_DIR}}
-DCMAKE_INSTALL_PREFIX="${{env.INSTL_DIR}}"
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
-DCMAKE_C_COMPILER=gcc
-DCMAKE_CXX_COMPILER=g++
-DUMF_BUILD_SHARED_LIBRARY=${{matrix.shared_library}}
-DUMF_BUILD_BENCHMARKS=OFF
-DUMF_BUILD_TESTS=ON
-DUMF_BUILD_GPU_TESTS=OFF
-DUMF_BUILD_GPU_EXAMPLES=OFF
-DUMF_FORMAT_CODE_STYLE=OFF
-DUMF_DEVELOPER_MODE=ON
-DUMF_BUILD_LIBUMF_POOL_DISJOINT=ON
-DUMF_BUILD_LIBUMF_POOL_JEMALLOC=ON
-DUMF_BUILD_LEVEL_ZERO_PROVIDER=OFF
-DUMF_TESTS_FAIL_ON_SKIP=ON

- name: Build UMF
run: cmake --build ${{env.BUILD_DIR}} --config ${{matrix.build_type}} -j $(nproc)

- name: Run the DEVDAX tests
working-directory: ${{env.BUILD_DIR}}
run: >
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
70 changes: 0 additions & 70 deletions .github/workflows/devdax.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/pr_push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions test/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
67 changes: 67 additions & 0 deletions test/common/test_helpers_linux.c
Original file line number Diff line number Diff line change
@@ -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 <fcntl.h>
#include <stdbool.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#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);
}
21 changes: 21 additions & 0 deletions test/common/test_helpers_linux.h
Original file line number Diff line number Diff line change
@@ -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 <stddef.h>

#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 */
50 changes: 4 additions & 46 deletions test/provider_devdax_memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

#ifndef _WIN32
#include "test_helpers_linux.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
Expand All @@ -11,6 +12,7 @@
#include "base.hpp"

#include "cpp_helpers.hpp"
#include "test_helpers.h"

#include <umf/memory_provider.h>
#include <umf/providers/provider_devdax_memory.h>
Expand Down Expand Up @@ -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;
Expand All @@ -167,56 +165,16 @@ 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);

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
Expand Down
Loading
Loading