The Linux specific transparent hugepage memory advisory has potentially
significant implications for how the memory management behaves. If the
platform supports it, add a new mmap ioengine specific option that advises
HUGEPAGE on an mmap'ed range. The option availability is detected during
configure. If the option is set, fio can test THP when used with private
anonymous memory (i.e. mmap /dev/zero).
Signed-off-by: Keith Busch <keith.busch@intel.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fi
print_config "-Wimplicit-fallthrough" "$fallthrough"
fi
print_config "-Wimplicit-fallthrough" "$fallthrough"
+##########################################
+# check for MADV_HUGEPAGE support
+if test "$thp" != "yes" ; then
+ thp="no"
+fi
+if test "$esx" != "yes" ; then
+ cat > $TMPC <<EOF
+#include <sys/mman.h>
+int main(void)
+{
+ return madvise(0, 0x1000, MADV_HUGEPAGE);
+}
+EOF
+ if compile_prog "" "" "thp" ; then
+ thp=yes
+ else
+ if test "$thp" = "yes" ; then
+ feature_not_found "Transparent Huge Page" ""
+ fi
+ thp=no
+ fi
+fi
+print_config "MADV_HUGEPAGE" "$thp"
+
#############################################################################
if test "$wordsize" = "64" ; then
#############################################################################
if test "$wordsize" = "64" ; then
if test "$fallthrough" = "yes"; then
CFLAGS="$CFLAGS -Wimplicit-fallthrough"
fi
if test "$fallthrough" = "yes"; then
CFLAGS="$CFLAGS -Wimplicit-fallthrough"
fi
+if test "$thp" = "yes" ; then
+ output_sym "CONFIG_HAVE_THP"
+fi
echo "LIBS+=$LIBS" >> $config_host_mak
echo "GFIO_LIBS+=$GFIO_LIBS" >> $config_host_mak
echo "LIBS+=$LIBS" >> $config_host_mak
echo "GFIO_LIBS+=$GFIO_LIBS" >> $config_host_mak
#include <sys/mman.h>
#include "../fio.h"
#include <sys/mman.h>
#include "../fio.h"
+#include "../optgroup.h"
#include "../verify.h"
/*
#include "../verify.h"
/*
+#ifdef CONFIG_HAVE_THP
+struct mmap_options {
+ void *pad;
+ unsigned int thp;
+};
+
+static struct fio_option options[] = {
+ {
+ .name = "thp",
+ .lname = "Transparent Huge Pages",
+ .type = FIO_OPT_INT,
+ .off1 = offsetof(struct mmap_options, thp),
+ .help = "Memory Advise Huge Page",
+ .category = FIO_OPT_C_ENGINE,
+ .group = FIO_OPT_G_MMAP,
+ },
+ {
+ .name = NULL,
+ },
+};
+#endif
+
static bool fio_madvise_file(struct thread_data *td, struct fio_file *f,
size_t length)
{
struct fio_mmap_data *fmd = FILE_ENG_DATA(f);
static bool fio_madvise_file(struct thread_data *td, struct fio_file *f,
size_t length)
{
struct fio_mmap_data *fmd = FILE_ENG_DATA(f);
+#ifdef CONFIG_HAVE_THP
+ struct mmap_options *o = td->eo;
+
+ /* Ignore errors on this optional advisory */
+ if (o->thp)
+ madvise(fmd->mmap_ptr, length, MADV_HUGEPAGE);
+#endif
if (!td->o.fadvise_hint)
return true;
if (!td->o.fadvise_hint)
return true;
+#ifdef CONFIG_HAVE_THP
+static int fio_mmap_get_shared(struct thread_data *td)
+{
+ struct mmap_options *o = td->eo;
+
+ if (o->thp)
+ return MAP_PRIVATE;
+ return MAP_SHARED;
+}
+#else
+static int fio_mmap_get_shared(struct thread_data *td)
+{
+ return MAP_SHARED;
+}
+#endif
+
static int fio_mmap_file(struct thread_data *td, struct fio_file *f,
size_t length, off_t off)
{
struct fio_mmap_data *fmd = FILE_ENG_DATA(f);
static int fio_mmap_file(struct thread_data *td, struct fio_file *f,
size_t length, off_t off)
{
struct fio_mmap_data *fmd = FILE_ENG_DATA(f);
+ int flags = 0, shared = fio_mmap_get_shared(td);
if (td_rw(td) && !td->o.verify_only)
flags = PROT_READ | PROT_WRITE;
if (td_rw(td) && !td->o.verify_only)
flags = PROT_READ | PROT_WRITE;
} else
flags = PROT_READ;
} else
flags = PROT_READ;
- fmd->mmap_ptr = mmap(NULL, length, flags, MAP_SHARED, f->fd, off);
+ fmd->mmap_ptr = mmap(NULL, length, flags, shared, f->fd, off);
if (fmd->mmap_ptr == MAP_FAILED) {
fmd->mmap_ptr = NULL;
td_verror(td, errno, "mmap");
if (fmd->mmap_ptr == MAP_FAILED) {
fmd->mmap_ptr = NULL;
td_verror(td, errno, "mmap");
.close_file = fio_mmapio_close_file,
.get_file_size = generic_get_file_size,
.flags = FIO_SYNCIO | FIO_NOEXTEND,
.close_file = fio_mmapio_close_file,
.get_file_size = generic_get_file_size,
.flags = FIO_SYNCIO | FIO_NOEXTEND,
+#ifdef CONFIG_HAVE_THP
+ .options = options,
+ .option_struct_size = sizeof(struct mmap_options),
+#endif
};
static void fio_init fio_mmapio_register(void)
};
static void fio_init fio_mmapio_register(void)
__FIO_OPT_G_MTD,
__FIO_OPT_G_HDFS,
__FIO_OPT_G_SG,
__FIO_OPT_G_MTD,
__FIO_OPT_G_HDFS,
__FIO_OPT_G_SG,
__FIO_OPT_G_NR,
FIO_OPT_G_RATE = (1ULL << __FIO_OPT_G_RATE),
__FIO_OPT_G_NR,
FIO_OPT_G_RATE = (1ULL << __FIO_OPT_G_RATE),
FIO_OPT_G_MTD = (1ULL << __FIO_OPT_G_MTD),
FIO_OPT_G_HDFS = (1ULL << __FIO_OPT_G_HDFS),
FIO_OPT_G_SG = (1ULL << __FIO_OPT_G_SG),
FIO_OPT_G_MTD = (1ULL << __FIO_OPT_G_MTD),
FIO_OPT_G_HDFS = (1ULL << __FIO_OPT_G_HDFS),
FIO_OPT_G_SG = (1ULL << __FIO_OPT_G_SG),
+ FIO_OPT_G_MMAP = (1ULL << __FIO_OPT_G_MMAP),
FIO_OPT_G_INVALID = (1ULL << __FIO_OPT_G_NR),
};
FIO_OPT_G_INVALID = (1ULL << __FIO_OPT_G_NR),
};