aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric B Munson <emunson@mgebm.net>2010-12-15 10:55:24 -0700
committerEric B Munson <emunson@mgebm.net>2010-12-16 10:20:19 -0700
commitb0d496fc01ad37a53b47fa6fd45ca446621513fd (patch)
tree17c274dcffd0b4c9221d244029cf8cdbbe2d08ff
parentee093392b99a62f8b243390d4d131c1b55b884c0 (diff)
downloadlibhugetlbfs-b0d496fc01ad37a53b47fa6fd45ca446621513fd.tar.gz
Make hugetlbfs_prefault always use /dev/zero as a readv source
On some implementations of readv passing in the fd used to map a region as a source fd causes readv to fail with the error Invalid Argument. Instead of having hugetlbfs_prefault take an fd argument it now opens /dev/zero as the source. Signed-off-by: Eric B Munson <emunson@mgebm.net>
-rw-r--r--alloc.c8
-rw-r--r--hugeutils.c22
-rw-r--r--libhugetlbfs_internal.h2
-rw-r--r--morecore.c2
4 files changed, 12 insertions, 22 deletions
diff --git a/alloc.c b/alloc.c
index 675cfda..f5815a8 100644
--- a/alloc.c
+++ b/alloc.c
@@ -119,12 +119,8 @@ void *get_huge_pages(size_t len, ghp_t flags)
return NULL;
}
- /*
- * Fault the region to ensure accesses succeed, buf_fd is passed
- * regarless of how we mmap'd because if MAP_HUGETLB was used the value
- * in buf_fd is ignored
- */
- if (hugetlbfs_prefault(buf_fd, buf, len) != 0) {
+ /* Fault the region to ensure accesses succeed */
+ if (hugetlbfs_prefault(buf, len) != 0) {
saved_error = errno;
munmap(buf, len);
if (buf_fd >= 0)
diff --git a/hugeutils.c b/hugeutils.c
index 26a0471..c56447e 100644
--- a/hugeutils.c
+++ b/hugeutils.c
@@ -954,13 +954,13 @@ int hugetlbfs_unlinked_fd(void)
}
#define IOV_LEN 64
-int hugetlbfs_prefault(int fd, void *addr, size_t length)
+int hugetlbfs_prefault(void *addr, size_t length)
{
size_t offset;
struct iovec iov[IOV_LEN];
int ret;
int i;
- int close_fd = -1;
+ int fd;
if (!__hugetlbfs_prefault)
return 0;
@@ -982,13 +982,10 @@ int hugetlbfs_prefault(int fd, void *addr, size_t length)
* mapping and optionally it may recover by mapping base pages instead.
*/
- 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;
- }
- close_fd = fd;
+ 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; ) {
@@ -1004,15 +1001,12 @@ int hugetlbfs_prefault(int fd, void *addr, size_t length)
WARNING("Failed to reserve %ld huge pages "
"for new region\n",
length / gethugepagesize());
- if (close_fd >= 0)
- close(close_fd);
+ close(fd);
return -ENOMEM;
}
}
- if (close_fd >= 0)
- close(close_fd);
-
+ close(fd);
return 0;
}
diff --git a/libhugetlbfs_internal.h b/libhugetlbfs_internal.h
index 068bbff..97b19fa 100644
--- a/libhugetlbfs_internal.h
+++ b/libhugetlbfs_internal.h
@@ -110,7 +110,7 @@ extern void hugetlbfs_check_map_hugetlb();
#define __hugetlbfs_hostname __lh___hugetlbfs_hostname
extern char __hugetlbfs_hostname[];
#define hugetlbfs_prefault __lh_hugetlbfs_prefault
-extern int hugetlbfs_prefault(int fd, void *addr, size_t length);
+extern int hugetlbfs_prefault(void *addr, size_t length);
#define parse_page_size __lh_parse_page_size
extern long parse_page_size(const char *str);
#define probe_default_hpage_size __lh__probe_default_hpage_size
diff --git a/morecore.c b/morecore.c
index 20c4860..99fbaee 100644
--- a/morecore.c
+++ b/morecore.c
@@ -136,7 +136,7 @@ static void *hugetlbfs_morecore(ptrdiff_t increment)
}
/* Fault the region to ensure accesses succeed */
- if (hugetlbfs_prefault(zero_fd, p, delta) != 0) {
+ if (hugetlbfs_prefault(p, delta) != 0) {
munmap(p, delta);
return NULL;
}