Handle hugetlbfs file mapping
Hugetlbfs file mappings are handled differently than regular files: - pager_req_create will tell us the file is in a hugetlbfs - allocate memory upfront, we need to fail if not enough memory - the memory needs to be given again if another process maps the same file This implementation still has some hacks, in particular, the memory needs to be freed when all mappings are done and the file has been deleted/closed by all processes. We cannot know when the file is closed/unlinked easily, so clean up memory when all processes have exited. To test, install libhugetlbfs and link a program with the additional LDFLAGS += -B /usr/share/libhugetlbfs -Wl,--hugetlbfs-align Then run with HUGETLB_ELFMAP=RW set, you can check this works with HUGETLB_DEBUG=1 HUGETLB_VERBOSE=2 Change-Id: I327920ff06efd82e91b319b27319f41912169af1
This commit is contained in:
committed by
Masamichi Takagi
parent
3e3ccf377c
commit
39f9d7fdff
@ -229,6 +229,9 @@ void (*mcctrl_zap_page_range)(struct vm_area_struct *vma,
|
||||
unsigned long size,
|
||||
struct zap_details *details);
|
||||
|
||||
struct inode_operations *mcctrl_hugetlbfs_inode_operations;
|
||||
|
||||
|
||||
static int symbols_init(void)
|
||||
{
|
||||
mcctrl_sys_mount = (void *) kallsyms_lookup_name("sys_mount");
|
||||
@ -263,6 +266,11 @@ static int symbols_init(void)
|
||||
if (WARN_ON(!mcctrl_zap_page_range))
|
||||
return -EFAULT;
|
||||
|
||||
mcctrl_hugetlbfs_inode_operations =
|
||||
(void *) kallsyms_lookup_name("hugetlbfs_inode_operations");
|
||||
if (WARN_ON(!mcctrl_hugetlbfs_inode_operations))
|
||||
return -EFAULT;
|
||||
|
||||
return arch_symbols_init();
|
||||
}
|
||||
|
||||
|
||||
@ -428,6 +428,7 @@ extern void (*mcctrl_zap_page_range)(struct vm_area_struct *vma,
|
||||
unsigned long start,
|
||||
unsigned long size,
|
||||
struct zap_details *details);
|
||||
extern struct inode_operations *mcctrl_hugetlbfs_inode_operations;
|
||||
|
||||
/* syscall.c */
|
||||
void pager_add_process(void);
|
||||
|
||||
@ -1165,6 +1165,7 @@ enum {
|
||||
MF_XPMEM = 0x10000, /* To identify XPMEM attachment pages for rusage accounting */
|
||||
MF_ZEROOBJ = 0x20000, /* To identify pages of anonymous, on-demand paging ranges for rusage accounting */
|
||||
MF_SHM = 0x40000,
|
||||
MF_HUGETLBFS = 0x100000,
|
||||
};
|
||||
|
||||
static int pager_get_path(struct file *file, char *path) {
|
||||
@ -1254,6 +1255,17 @@ static int pager_req_create(ihk_os_t os, int fd, uintptr_t result_pa)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (inode->i_op == mcctrl_hugetlbfs_inode_operations) {
|
||||
mf_flags = MF_HUGETLBFS;
|
||||
/* pager is used as handle id on mckernel side, use inode */
|
||||
pager = (void *)st.ino;
|
||||
/* retrofit blksize in resp as well through st.size field;
|
||||
* the actual file size is not used
|
||||
*/
|
||||
st.size = st.blksize;
|
||||
goto out_reply;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
spin_lock_irqsave(&pager_lock, irqflags);
|
||||
|
||||
@ -1322,6 +1334,7 @@ found:
|
||||
}
|
||||
spin_unlock_irqrestore(&pager_lock, irqflags);
|
||||
|
||||
out_reply:
|
||||
phys = ihk_device_map_memory(dev, result_pa, sizeof(*resp));
|
||||
resp = ihk_device_map_virtual(dev, phys, sizeof(*resp), NULL, 0);
|
||||
if (!resp) {
|
||||
|
||||
Reference in New Issue
Block a user