Add support for libpmem2 to librpma fio engine in the APM mode.
Signed-off-by: Kacper Stefanski <kacper.stefanski@intel.com>
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
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
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
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
/*
* 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,
* 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[] = {
{
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",
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);
}
/*
* 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,
/* 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,
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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);
+}