Skip to content

Commit

Permalink
rpma: add support for libpmem2 to librpma engine in APM mode
Browse files Browse the repository at this point in the history
Add support for libpmem2 to librpma fio engine in the APM mode.

Signed-off-by: Kacper Stefanski <[email protected]>
  • Loading branch information
haichangsi authored and ldorau committed Sep 6, 2022
1 parent d3061c1 commit 8fabefc
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 43 deletions.
12 changes: 10 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,21 @@ endif
ifdef CONFIG_LIBRPMA_APM
librpma_apm_SRCS = engines/librpma_apm.c
librpma_fio_SRCS = engines/librpma_fio.c
librpma_apm_LIBS = -lrpma -lpmem
ifdef CONFIG_LIBPMEM2_INSTALLED
librpma_apm_LIBS = -lrpma -lpmem2
else
librpma_apm_LIBS = -lrpma -lpmem
endif
ENGINES += librpma_apm
endif
ifdef CONFIG_LIBRPMA_GPSPM
librpma_gpspm_SRCS = engines/librpma_gpspm.c engines/librpma_gpspm_flush.pb-c.c
librpma_fio_SRCS = engines/librpma_fio.c
librpma_gpspm_LIBS = -lrpma -lpmem -lprotobuf-c
ifdef CONFIG_LIBPMEM2_INSTALLED
librpma_gpspm_LIBS = -lrpma -lpmem2 -lprotobuf-c
else
librpma_gpspm_LIBS = -lrpma -lpmem -lprotobuf-c
endif
ENGINES += librpma_gpspm
endif
ifdef librpma_fio_SRCS
Expand Down
29 changes: 27 additions & 2 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -2201,6 +2201,26 @@ EOF
fi
print_config "libpmem1_5" "$libpmem1_5"

##########################################
# Check whether we have libpmem2
if test "$libpmem2" != "yes" ; then
libpmem2="no"
fi
cat > $TMPC << EOF
#include <libpmem2.h>
int main(int argc, char **argv)
{
struct pmem2_config *cfg;
pmem2_config_new(&cfg);
pmem2_config_delete(&cfg);
return 0;
}
EOF
if compile_prog "" "-lpmem2" "libpmem2"; then
libpmem2="yes"
fi
print_config "libpmem2" "$libpmem2"

##########################################
# Check whether we have libpmemblk
# libpmem is a prerequisite
Expand Down Expand Up @@ -2990,11 +3010,13 @@ if test "$libverbs" = "yes" -a "$rdmacm" = "yes" ; then
fi
# librpma is supported on the 'x86_64' architecture for now
if test "$cpu" = "x86_64" -a "$libverbs" = "yes" -a "$rdmacm" = "yes" \
-a "$librpma" = "yes" -a "$libpmem" = "yes" ; then
-a "$librpma" = "yes" \
&& test "$libpmem" = "yes" -o "$libpmem2" = "yes" ; then
output_sym "CONFIG_LIBRPMA_APM"
fi
if test "$cpu" = "x86_64" -a "$libverbs" = "yes" -a "$rdmacm" = "yes" \
-a "$librpma" = "yes" -a "$libpmem" = "yes" -a "$libprotobuf_c" = "yes" ; then
-a "$librpma" = "yes" -a "$libprotobuf_c" = "yes" \
&& test "$libpmem" = "yes" -o "$libpmem2" = "yes" ; then
output_sym "CONFIG_LIBRPMA_GPSPM"
fi
if test "$clock_gettime" = "yes" ; then
Expand Down Expand Up @@ -3138,6 +3160,9 @@ fi
if test "$pmem" = "yes" ; then
output_sym "CONFIG_LIBPMEM"
fi
if test "$libpmem2" = "yes" ; then
output_sym "CONFIG_LIBPMEM2_INSTALLED"
fi
if test "$libime" = "yes" ; then
output_sym "CONFIG_IME"
fi
Expand Down
52 changes: 14 additions & 38 deletions engines/librpma_fio.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* librpma_fio: librpma_apm and librpma_gpspm engines' common part.
*
* Copyright 2021, Intel Corporation
* Copyright 2021-2022, Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
Expand All @@ -13,9 +13,11 @@
* GNU General Public License for more details.
*/

#include "librpma_fio.h"

#include <libpmem.h>
#ifdef CONFIG_LIBPMEM2_INSTALLED
#include "librpma_fio_pmem2.h"
#else
#include "librpma_fio_pmem.h"
#endif /* CONFIG_LIBPMEM2_INSTALLED */

struct fio_option librpma_fio_options[] = {
{
Expand Down Expand Up @@ -111,10 +113,8 @@ char *librpma_fio_allocate_dram(struct thread_data *td, size_t size,
char *librpma_fio_allocate_pmem(struct thread_data *td, struct fio_file *f,
size_t size, struct librpma_fio_mem *mem)
{
size_t size_mmap = 0;
char *mem_ptr = NULL;
int is_pmem = 0;
size_t ws_offset;
mem->mem_ptr = NULL;

if (size % page_size) {
log_err("fio: size (%zu) is not aligned to page size (%zu)\n",
Expand All @@ -135,48 +135,24 @@ char *librpma_fio_allocate_pmem(struct thread_data *td, struct fio_file *f,
return NULL;
}

/* map the file */
mem_ptr = pmem_map_file(f->file_name, 0 /* len */, 0 /* flags */,
0 /* mode */, &size_mmap, &is_pmem);
if (mem_ptr == NULL) {
log_err("fio: pmem_map_file(%s) failed\n", f->file_name);
/* pmem_map_file() sets errno on failure */
td_verror(td, errno, "pmem_map_file");
return NULL;
}

/* pmem is expected */
if (!is_pmem) {
log_err("fio: %s is not located in persistent memory\n",
if (librpma_fio_pmem_map_file(f, size, mem, ws_offset)) {
log_err("fio: librpma_fio_pmem_map_file(%s) failed\n",
f->file_name);
goto err_unmap;
}

/* check size of allocated persistent memory */
if (size_mmap < ws_offset + size) {
log_err(
"fio: %s is too small to handle so many threads (%zu < %zu)\n",
f->file_name, size_mmap, ws_offset + size);
goto err_unmap;
return NULL;
}

log_info("fio: size of memory mapped from the file %s: %zu\n",
f->file_name, size_mmap);

mem->mem_ptr = mem_ptr;
mem->size_mmap = size_mmap;
f->file_name, mem->size_mmap);

return mem_ptr + ws_offset;
log_info("fio: library used to map PMem from file: %s\n", RPMA_PMEM_USED);

err_unmap:
(void) pmem_unmap(mem_ptr, size_mmap);
return NULL;
return mem->mem_ptr ? mem->mem_ptr + ws_offset : NULL;
}

void librpma_fio_free(struct librpma_fio_mem *mem)
{
if (mem->size_mmap)
(void) pmem_unmap(mem->mem_ptr, mem->size_mmap);
librpma_fio_unmap(mem);
else
free(mem->mem_ptr);
}
Expand Down
7 changes: 6 additions & 1 deletion engines/librpma_fio.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*
* librpma_fio: librpma_apm and librpma_gpspm engines' common header.
*
* Copyright 2021, Intel Corporation
* Copyright 2021-2022, Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
Expand Down Expand Up @@ -72,6 +72,11 @@ struct librpma_fio_mem {

/* size of the mapped persistent memory */
size_t size_mmap;

#ifdef CONFIG_LIBPMEM2_INSTALLED
/* libpmem2 structure used for mapping PMem */
struct pmem2_map *map;
#endif
};

char *librpma_fio_allocate_dram(struct thread_data *td, size_t size,
Expand Down
67 changes: 67 additions & 0 deletions engines/librpma_fio_pmem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* librpma_fio_pmem: allocates pmem using libpmem.
*
* Copyright 2022, Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* version 2 as published by the Free Software Foundation..
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <libpmem.h>
#include "librpma_fio.h"

#define RPMA_PMEM_USED "libpmem"

static int librpma_fio_pmem_map_file(struct fio_file *f, size_t size,
struct librpma_fio_mem *mem, size_t ws_offset)
{
int is_pmem = 0;
size_t size_mmap = 0;

/* map the file */
mem->mem_ptr = pmem_map_file(f->file_name, 0 /* len */, 0 /* flags */,
0 /* mode */, &size_mmap, &is_pmem);
if (mem->mem_ptr == NULL) {
/* pmem_map_file() sets errno on failure */
log_err("fio: pmem_map_file(%s) failed: %s (errno %i)\n",
f->file_name, strerror(errno), errno);
return -1;
}

/* pmem is expected */
if (!is_pmem) {
log_err("fio: %s is not located in persistent memory\n",
f->file_name);
goto err_unmap;
}

/* check size of allocated persistent memory */
if (size_mmap < ws_offset + size) {
log_err(
"fio: %s is too small to handle so many threads (%zu < %zu)\n",
f->file_name, size_mmap, ws_offset + size);
goto err_unmap;
}

log_info("fio: size of memory mapped from the file %s: %zu\n",
f->file_name, size_mmap);

mem->size_mmap = size_mmap;

return 0;

err_unmap:
(void) pmem_unmap(mem->mem_ptr, size_mmap);
return -1;
}

static inline void librpma_fio_unmap(struct librpma_fio_mem *mem)
{
(void) pmem_unmap(mem->mem_ptr, mem->size_mmap);
}
91 changes: 91 additions & 0 deletions engines/librpma_fio_pmem2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* librpma_fio_pmem2: allocates pmem using libpmem2.
*
* Copyright 2022, Intel Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License,
* version 2 as published by the Free Software Foundation..
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/

#include <libpmem2.h>
#include "librpma_fio.h"

#define RPMA_PMEM_USED "libpmem2"

static int librpma_fio_pmem_map_file(struct fio_file *f, size_t size,
struct librpma_fio_mem *mem, size_t ws_offset)
{
int fd;
struct pmem2_config *cfg = NULL;
struct pmem2_map *map = NULL;
struct pmem2_source *src = NULL;

size_t size_mmap;

if((fd = open(f->file_name, O_RDWR)) < 0) {
log_err("fio: cannot open fio file\n");
return -1;
}

if (pmem2_source_from_fd(&src, fd) != 0) {
log_err("fio: pmem2_source_from_fd() failed\n");
goto err_close;
}

if (pmem2_config_new(&cfg) != 0) {
log_err("fio: pmem2_config_new() failed\n");
goto err_source_delete;
}

if (pmem2_config_set_required_store_granularity(cfg,
PMEM2_GRANULARITY_CACHE_LINE) != 0) {
log_err("fio: pmem2_config_set_required_store_granularity() failed: %s\n", pmem2_errormsg());
goto err_config_delete;
}

if (pmem2_map_new(&map, cfg, src) != 0) {
log_err("fio: pmem2_map_new(%s) failed: %s\n", f->file_name, pmem2_errormsg());
goto err_config_delete;
}

size_mmap = pmem2_map_get_size(map);

/* check size of allocated persistent memory */
if (size_mmap < ws_offset + size) {
log_err(
"fio: %s is too small to handle so many threads (%zu < %zu)\n",
f->file_name, size_mmap, ws_offset + size);
goto err_map_delete;
}

mem->mem_ptr = pmem2_map_get_address(map);
mem->size_mmap = size_mmap;
mem->map = map;
pmem2_config_delete(&cfg);
pmem2_source_delete(&src);
close(fd);

return 0;

err_map_delete:
pmem2_map_delete(&map);
err_config_delete:
pmem2_config_delete(&cfg);
err_source_delete:
pmem2_source_delete(&src);
err_close:
close(fd);

return -1;
}

static inline void librpma_fio_unmap(struct librpma_fio_mem *mem)
{
(void) pmem2_map_delete(&mem->map);
}

0 comments on commit 8fabefc

Please sign in to comment.