X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvppinfra%2Flinux%2Fmem.c;h=2d968fae0ac70070fb900cf0220f25f10851bcd6;hb=642829de7958d5cd9c1c88f9845385882a7c211d;hp=665ddf6194f1c48776d5d25a110b7be7573c58bd;hpb=01914ce45729833cec88c65689de9a0336cd40cc;p=vpp.git diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c index 665ddf6194f..2d968fae0ac 100644 --- a/src/vppinfra/linux/mem.c +++ b/src/vppinfra/linux/mem.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -45,13 +46,34 @@ #define F_SEAL_WRITE 0x0008 /* prevent writes */ #endif -int -clib_mem_vm_get_log2_page_size (int fd) +u64 +clib_mem_vm_get_page_size (int fd) { struct stat st = { 0 }; - if (fstat (fd, &st)) + if (fstat (fd, &st) == -1) return 0; - return min_log2 (st.st_blksize); + return st.st_blksize; +} + +int +clib_mem_vm_get_log2_page_size (int fd) +{ + return min_log2 (clib_mem_vm_get_page_size (fd)); +} + +void +clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size) +{ + u8 bit_mask = 15; + + if (log2_page_size <= 12) + bit_mask = 15; + else if (log2_page_size > 12 && log2_page_size <= 16) + bit_mask = 3; + else + bit_mask = 0; + + *requested_va += (clib_cpu_time_now () & bit_mask) * (1 << log2_page_size); } clib_error_t * @@ -61,22 +83,22 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) clib_error_t *err = 0; void *addr = 0; u8 *filename = 0; - int mmap_flags = MAP_SHARED; + int mmap_flags = 0; int log2_page_size; int n_pages; int old_mpol = -1; - u64 old_mask[16] = { 0 }; + long unsigned int old_mask[16] = { 0 }; /* save old numa mem policy if needed */ if (a->flags & (CLIB_MEM_VM_F_NUMA_PREFER | CLIB_MEM_VM_F_NUMA_FORCE)) { int rv; - rv = - get_mempolicy (&old_mpol, old_mask, sizeof (old_mask) * 8 + 1, 0, 0); + rv = get_mempolicy (&old_mpol, old_mask, sizeof (old_mask) * 8 + 1, + 0, 0); if (rv == -1) { - if ((a->flags & CLIB_MEM_VM_F_NUMA_FORCE) != 0) + if (a->numa_node != 0 && (a->flags & CLIB_MEM_VM_F_NUMA_FORCE) != 0) { err = clib_error_return_unix (0, "get_mempolicy"); goto error; @@ -86,9 +108,13 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) } } + if (a->flags & CLIB_MEM_VM_F_LOCKED) + mmap_flags |= MAP_LOCKED; + /* if we are creating shared segment, we need file descriptor */ if (a->flags & CLIB_MEM_VM_F_SHARED) { + mmap_flags |= MAP_SHARED; /* if hugepages are needed we need to create mount point */ if (a->flags & CLIB_MEM_VM_F_HUGETLB) { @@ -101,6 +127,7 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) if (mount ("none", (char *) mount_dir, "hugetlbfs", 0, NULL)) { + rmdir ((char *) mount_dir); err = clib_error_return_unix (0, "mount hugetlb directory '%s'", mount_dir); goto error; @@ -110,6 +137,8 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) if ((fd = open ((char *) filename, O_CREAT | O_RDWR, 0755)) == -1) { + umount2 ((char *) mount_dir, MNT_DETACH); + rmdir ((char *) mount_dir); err = clib_error_return_unix (0, "open"); goto error; } @@ -131,25 +160,36 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) goto error; } } + log2_page_size = clib_mem_vm_get_log2_page_size (fd); + if (log2_page_size == 0) + { + err = clib_error_return_unix (0, "cannot determine page size"); + goto error; + } + + if (a->requested_va) + { + clib_mem_vm_randomize_va (&a->requested_va, log2_page_size); + mmap_flags |= MAP_FIXED; + } } else /* not CLIB_MEM_VM_F_SHARED */ { + mmap_flags |= MAP_PRIVATE | MAP_ANONYMOUS; if (a->flags & CLIB_MEM_VM_F_HUGETLB) { - mmap_flags |= MAP_HUGETLB | MAP_PRIVATE | MAP_ANONYMOUS; + mmap_flags |= MAP_HUGETLB; log2_page_size = 21; } else { - mmap_flags |= MAP_PRIVATE | MAP_ANONYMOUS; log2_page_size = min_log2 (sysconf (_SC_PAGESIZE)); } } n_pages = ((a->size - 1) >> log2_page_size) + 1; - if (a->flags & CLIB_MEM_VM_F_HUGETLB_PREALLOC) { err = clib_sysfs_prealloc_hugepages (a->numa_node, @@ -161,7 +201,7 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) } if (fd != -1) - if ((ftruncate (fd, a->size)) == -1) + if ((ftruncate (fd, (u64) n_pages * (1 << log2_page_size))) == -1) { err = clib_error_return_unix (0, "ftruncate"); goto error; @@ -170,24 +210,26 @@ clib_mem_vm_ext_alloc (clib_mem_vm_alloc_t * a) if (old_mpol != -1) { int rv; - u64 mask[16] = { 0 }; + long unsigned int mask[16] = { 0 }; mask[0] = 1 << a->numa_node; rv = set_mempolicy (MPOL_BIND, mask, sizeof (mask) * 8 + 1); - if (rv) + if (rv == -1 && a->numa_node != 0 && + (a->flags & CLIB_MEM_VM_F_NUMA_FORCE) != 0) { err = clib_error_return_unix (0, "set_mempolicy"); goto error; } } - addr = mmap (0, a->size, (PROT_READ | PROT_WRITE), mmap_flags, fd, 0); + addr = mmap (uword_to_pointer (a->requested_va, void *), a->size, + (PROT_READ | PROT_WRITE), mmap_flags, fd, 0); if (addr == MAP_FAILED) { err = clib_error_return_unix (0, "mmap"); goto error; } - /* re-apply ole numa memory policy */ + /* re-apply old numa memory policy */ if (old_mpol != -1 && set_mempolicy (old_mpol, old_mask, sizeof (old_mask) * 8 + 1) == -1) { @@ -210,6 +252,17 @@ done: return err; } +void +clib_mem_vm_ext_free (clib_mem_vm_alloc_t * a) +{ + if (a != 0) + { + clib_mem_vm_free (a->addr, 1 << a->log2_page_size); + if (a->fd != -1) + close (a->fd); + } +} + u64 * clib_mem_vm_get_paddr (void *mem, int log2_page_size, int n_pages) { @@ -249,7 +302,24 @@ done: return r; } +clib_error_t * +clib_mem_vm_ext_map (clib_mem_vm_map_t * a) +{ + int mmap_flags = MAP_SHARED; + void *addr; + + if (a->requested_va) + mmap_flags |= MAP_FIXED; + + addr = (void *) mmap (uword_to_pointer (a->requested_va, void *), a->size, + PROT_READ | PROT_WRITE, mmap_flags, a->fd, 0); + if (addr == MAP_FAILED) + return clib_error_return_unix (0, "mmap"); + + a->addr = addr; + return 0; +} /* * fd.io coding-style-patch-verification: ON