Ensō 0.4.6
Software API reference
Loading...
Searching...
No Matches
ixy_helpers.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2017, Paul Emmerich
3 * Copyright (c) 2023, Hugo Sadok
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
38#include <enso/consts.h>
39#include <enso/ixy_helpers.h>
40#include <fcntl.h>
41#include <sys/mman.h>
42#include <unistd.h>
43
44#include <cstdint>
45#include <cstdio>
46#include <iostream>
47#include <string>
48
49namespace enso {
50
51uint64_t virt_to_phys(void* virt) {
52 long page_size = sysconf(_SC_PAGESIZE);
53 int fd = open("/proc/self/pagemap", O_RDONLY);
54
55 if (fd < 0) {
56 return 0;
57 }
58
59 // Pagemap is an array of pointers for each normal-sized page.
60 off_t offset = (uintptr_t)virt / page_size * sizeof(uintptr_t);
61 if (lseek(fd, offset, SEEK_SET) < 0) {
62 close(fd);
63 return 0;
64 }
65
66 uintptr_t phy = 0;
67 if (read(fd, &phy, sizeof(phy)) < 0) {
68 close(fd);
69 return 0;
70 }
71 close(fd);
72
73 if (!phy) {
74 return 0;
75 }
76
77 // Bits 0-54 are the page number.
78 return (uint64_t)((phy & 0x7fffffffffffffULL) * page_size +
79 ((uintptr_t)virt) % page_size);
80}
81
82void* get_huge_page(const std::string& path, size_t size, bool mirror) {
83 int fd;
84 if (size == 0) {
85 size = kBufPageSize;
86 }
87
88 if (mirror && size % kBufPageSize) {
89 std::cerr << "Mirror huge pages must be a multiple of huge page size"
90 << std::endl;
91 return nullptr;
92 }
93
94 fd = open(path.c_str(), O_CREAT | O_RDWR, S_IRWXU);
95 if (fd == -1) {
96 std::cerr << "(" << errno << ") Problem opening huge page file descriptor"
97 << std::endl;
98 return nullptr;
99 }
100
101 if (ftruncate(fd, (off_t)size)) {
102 std::cerr << "(" << errno
103 << ") Could not truncate huge page to size: " << size
104 << std::endl;
105 close(fd);
106 unlink(path.c_str());
107 return nullptr;
108 }
109
110 void* virt_addr = (void*)mmap(nullptr, size * 2, PROT_READ | PROT_WRITE,
111 MAP_SHARED | MAP_HUGETLB, fd, 0);
112
113 if (virt_addr == (void*)-1) {
114 std::cerr << "(" << errno << ") Could not mmap huge page" << std::endl;
115 close(fd);
116 unlink(path.c_str());
117 return nullptr;
118 }
119
120 if (mirror) {
121 // Allocate same huge page at the end of the last one.
122 void* ret =
123 (void*)mmap((uint8_t*)virt_addr + size, size, PROT_READ | PROT_WRITE,
124 MAP_FIXED | MAP_SHARED | MAP_HUGETLB, fd, 0);
125
126 if (ret == (void*)-1) {
127 std::cerr << "(" << errno << ") Could not mmap second huge page"
128 << std::endl;
129 close(fd);
130 unlink(path.c_str());
131 free(virt_addr);
132 return nullptr;
133 }
134 }
135
136 if (mlock(virt_addr, size)) {
137 std::cerr << "(" << errno << ") Could not lock huge page" << std::endl;
138 munmap(virt_addr, size);
139 close(fd);
140 unlink(path.c_str());
141 return nullptr;
142 }
143
144 close(fd);
145
146 return virt_addr;
147}
148
149} // namespace enso
Constants used throughout the codebase. Some of these constants need to be kept in sync with the hard...
Helper functions adapted from the ixy driver
void * get_huge_page(const std::string &path, size_t size=0, bool mirror=false)
Definition: ixy_helpers.cpp:82
uint64_t virt_to_phys(void *virt)
Definition: ixy_helpers.cpp:51