support madvise(MADV_REMOVE) partially
This MADV_REMOVE works with a mapping which is - created with shmat() and - not sharing memobj with other mappings.
This commit is contained in:
@@ -31,6 +31,7 @@ enum {
|
||||
/* for memobj.flags */
|
||||
MF_HAS_PAGER = 0x0001,
|
||||
MF_SHMDT_OK = 0x0002,
|
||||
MF_IS_REMOVABLE = 0x0004,
|
||||
};
|
||||
|
||||
struct memobj {
|
||||
@@ -120,6 +121,11 @@ static inline int memobj_has_pager(struct memobj *obj)
|
||||
return !!(obj->flags & MF_HAS_PAGER);
|
||||
}
|
||||
|
||||
static inline int memobj_is_removable(struct memobj *obj)
|
||||
{
|
||||
return !!(obj->flags & MF_IS_REMOVABLE);
|
||||
}
|
||||
|
||||
int fileobj_create(int fd, struct memobj **objp, int *maxprotp);
|
||||
struct shmid_ds;
|
||||
int shmobj_create(struct shmid_ds *ds, struct memobj **objp);
|
||||
|
||||
@@ -33,11 +33,13 @@ static ihk_spinlock_t shmobj_list_lock_body = SPIN_LOCK_UNLOCKED;
|
||||
static memobj_release_func_t shmobj_release;
|
||||
static memobj_ref_func_t shmobj_ref;
|
||||
static memobj_get_page_func_t shmobj_get_page;
|
||||
static memobj_invalidate_page_func_t shmobj_invalidate_page;
|
||||
|
||||
static struct memobj_ops shmobj_ops = {
|
||||
.release = &shmobj_release,
|
||||
.ref = &shmobj_ref,
|
||||
.get_page = &shmobj_get_page,
|
||||
.invalidate_page = &shmobj_invalidate_page,
|
||||
};
|
||||
|
||||
static struct shmobj *to_shmobj(struct memobj *memobj)
|
||||
@@ -158,7 +160,7 @@ int shmobj_create_indexed(struct shmid_ds *ds, struct shmobj **objp)
|
||||
|
||||
error = shmobj_create(ds, &obj);
|
||||
if (!error) {
|
||||
obj->flags |= MF_SHMDT_OK;
|
||||
obj->flags |= MF_SHMDT_OK | MF_IS_REMOVABLE;
|
||||
*objp = to_shmobj(obj);
|
||||
}
|
||||
return error;
|
||||
@@ -369,3 +371,30 @@ out:
|
||||
memobj, off, p2align, physp, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int shmobj_invalidate_page(struct memobj *memobj, uintptr_t phys,
|
||||
size_t pgsize)
|
||||
{
|
||||
struct shmobj *obj = to_shmobj(memobj);
|
||||
int error;
|
||||
struct page *page;
|
||||
|
||||
dkprintf("shmobj_invalidate_page(%p,%#lx,%#lx)\n", memobj, phys, pgsize);
|
||||
|
||||
if (!(page = phys_to_page(phys))
|
||||
|| !(page = page_list_lookup(obj, page->offset))) {
|
||||
error = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ihk_atomic_read(&page->count) == 1) {
|
||||
if (page_unmap(page)) {
|
||||
ihk_mc_free_pages(phys_to_virt(phys), pgsize/PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
error = 0;
|
||||
out:
|
||||
dkprintf("shmobj_invalidate_page(%p,%#lx,%#lx):%d\n", memobj, phys, pgsize, error);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -2691,6 +2691,8 @@ SYSCALL_DECLARE(madvise)
|
||||
uintptr_t addr;
|
||||
struct vm_range *range;
|
||||
int error;
|
||||
uintptr_t s;
|
||||
uintptr_t e;
|
||||
|
||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x)\n",
|
||||
ihk_mc_get_processor_id(), start, len0, advice);
|
||||
@@ -2732,10 +2734,7 @@ SYSCALL_DECLARE(madvise)
|
||||
case MADV_DONTNEED:
|
||||
case MADV_DONTFORK:
|
||||
case MADV_DOFORK:
|
||||
break;
|
||||
|
||||
case MADV_REMOVE:
|
||||
error = -EACCES;
|
||||
break;
|
||||
|
||||
case MADV_HWPOISON:
|
||||
@@ -2777,7 +2776,17 @@ SYSCALL_DECLARE(madvise)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!range->memobj || !memobj_has_pager(range->memobj)) {
|
||||
if (advice == MADV_REMOVE) {
|
||||
if (!range->memobj || !memobj_is_removable(range->memobj)) {
|
||||
dkprintf("sys_madvise(%lx,%lx,%x):"
|
||||
"not removable [%lx-%lx)\n",
|
||||
start, len0, advice,
|
||||
range->start, range->end);
|
||||
error = -EACCES;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (!range->memobj || !memobj_has_pager(range->memobj)) {
|
||||
dkprintf("[%d]sys_madvise(%lx,%lx,%x):has not pager"
|
||||
"[%lx-%lx) %lx\n",
|
||||
ihk_mc_get_processor_id(), start,
|
||||
@@ -2797,6 +2806,28 @@ SYSCALL_DECLARE(madvise)
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
s = start;
|
||||
if (s < range->start) {
|
||||
s = range->start;
|
||||
}
|
||||
e = end;
|
||||
if (range->end < e) {
|
||||
e = range->end;
|
||||
}
|
||||
|
||||
if (advice == MADV_REMOVE) {
|
||||
error = invalidate_process_memory_range(
|
||||
thread->vm, range, s, e);
|
||||
if (error) {
|
||||
kprintf("sys_madvise(%lx,%lx,%x):[%lx-%lx):"
|
||||
"invalidate failed. %d\n",
|
||||
start, len0, advice,
|
||||
range->start, range->end,
|
||||
error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
Reference in New Issue
Block a user