hugetlbfs_prefault relies on having a file descriptor associated with the huge page backed region to prefault the huge pages. This patch gives an alternative for prefaulting which will be used when the kernel supports MAP_HUGETLB.
Signed-off-by: Eric B Munson <[email protected]> --- hugeutils.c | 58 +++++++++++++++++++++++++++++++++++++--------------------- 1 files changed, 37 insertions(+), 21 deletions(-) diff --git a/hugeutils.c b/hugeutils.c index dd3a5c8..eecddf0 100644 --- a/hugeutils.c +++ b/hugeutils.c @@ -957,6 +957,15 @@ int hugetlbfs_unlinked_fd(void) #define IOV_LEN 64 int hugetlbfs_prefault(int fd, void *addr, size_t length) { + size_t offset; + struct iovec iov[IOV_LEN]; + int ret; + int i; + int arg_fd = fd; + + if (!__hugetlbfs_prefault) + return 0; + /* * The NUMA users of libhugetlbfs' malloc feature are * expected to use the numactl program to specify an @@ -973,30 +982,37 @@ int hugetlbfs_prefault(int fd, void *addr, size_t length) * -ENOMEM is returned. The caller is expected to release the entire * mapping and optionally it may recover by mapping base pages instead. */ - if (__hugetlbfs_prefault) { - int i; - size_t offset; - struct iovec iov[IOV_LEN]; - int ret; - - for (offset = 0; offset < length; ) { - for (i = 0; i < IOV_LEN && offset < length; i++) { - iov[i].iov_base = addr + offset; - iov[i].iov_len = 1; - offset += gethugepagesize(); - } - ret = readv(fd, iov, i); - if (ret != i) { - DEBUG("Got %d of %d requested; err=%d\n", ret, - i, ret < 0 ? errno : 0); - WARNING("Failed to reserve %ld huge pages " - "for new region\n", - length / gethugepagesize()); - return -ENOMEM; - } + + if (fd < 0 && __hugetlb_opts.map_hugetlb) { + fd = open("/dev/zero", O_RDONLY); + if (fd < 0) { + ERROR("Failed to open /dev/zero for reading\n"); + return -ENOMEM; + } + } + + for (offset = 0; offset < length; ) { + for (i = 0; i < IOV_LEN && offset < length; i++) { + iov[i].iov_base = addr + offset; + iov[i].iov_len = 1; + offset += gethugepagesize(); + } + ret = readv(fd, iov, i); + if (ret != i) { + DEBUG("Got %d of %d requested; err=%d\n", ret, + i, ret < 0 ? errno : 0); + WARNING("Failed to reserve %ld huge pages " + "for new region\n", + length / gethugepagesize()); + if (arg_fd < 0 && __hugetlb_opts.map_hugetlb) + close(fd); + return -ENOMEM; } } + if (arg_fd < 0 && __hugetlb_opts.map_hugetlb) + close(fd); + return 0; } -- 1.7.1 ------------------------------------------------------------------------------ Centralized Desktop Delivery: Dell and VMware Reference Architecture Simplifying enterprise desktop deployment and management using Dell EqualLogic storage and VMware View: A highly scalable, end-to-end client virtualization framework. Read more! http://p.sf.net/sfu/dell-eql-dev2dev _______________________________________________ Libhugetlbfs-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/libhugetlbfs-devel
