fileobj: use read/write MCS locks in page hash

This commit is contained in:
Balazs Gerofi
2016-12-18 13:45:10 +09:00
parent 6a5fe90f98
commit 5b7bcb7170

View File

@ -29,7 +29,8 @@
#define dkprintf(...) do { if (0) kprintf(__VA_ARGS__); } while (0)
#define ekprintf(...) kprintf(__VA_ARGS__)
mcs_lock_node_t fileobj_list_lock = {0, NULL};
mcs_rwlock_lock_t fileobj_list_lock =
{{{0}, MCS_RWLOCK_TYPE_COMMON_READER, 0, 0, 0, NULL}, NULL};
static LIST_HEAD(fileobj_list);
#define FILEOBJ_PAGE_HASH_SHIFT 9
@ -43,7 +44,7 @@ struct fileobj {
uintptr_t handle;
struct list_head list;
struct list_head page_hash[FILEOBJ_PAGE_HASH_SIZE];
mcs_lock_node_t page_hash_locks[FILEOBJ_PAGE_HASH_SIZE];
mcs_rwlock_lock_t page_hash_locks[FILEOBJ_PAGE_HASH_SIZE];
};
static memobj_release_func_t fileobj_release;
@ -80,7 +81,7 @@ static void fileobj_page_hash_init(struct fileobj *obj)
{
int i;
for (i = 0; i < FILEOBJ_PAGE_HASH_SIZE; ++i) {
mcs_lock_init(&obj->page_hash_locks[i]);
mcs_rwlock_init(&obj->page_hash_locks[i]);
INIT_LIST_HEAD(&obj->page_hash[i]);
}
return;
@ -189,7 +190,7 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
int error;
struct fileobj *newobj = NULL;
struct fileobj *obj;
mcs_lock_node_t node;
struct mcs_rwlock_node node;
dkprintf("fileobj_create(%d)\n", fd);
newobj = kmalloc(sizeof(*newobj), IHK_MC_AP_NOWAIT);
@ -219,7 +220,7 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
fileobj_page_hash_init(newobj);
ihk_mc_spinlock_init(&newobj->memobj.lock);
mcs_lock_lock_noirq(&fileobj_list_lock, &node);
mcs_rwlock_writer_lock_noirq(&fileobj_list_lock, &node);
obj = obj_list_lookup(result.handle);
if (!obj) {
obj_list_insert(newobj);
@ -233,7 +234,7 @@ int fileobj_create(int fd, struct memobj **objp, int *maxprotp)
memobj_unlock(&obj->memobj); /* locked by obj_list_lookup() */
}
mcs_lock_unlock_noirq(&fileobj_list_lock, &node);
mcs_rwlock_writer_unlock_noirq(&fileobj_list_lock, &node);
error = 0;
*objp = to_memobj(obj);
@ -264,7 +265,7 @@ static void fileobj_release(struct memobj *memobj)
long free_sref = 0;
uintptr_t free_handle;
struct fileobj *free_obj = NULL;
mcs_lock_node_t node;
struct mcs_rwlock_node node;
dkprintf("fileobj_release(%p %lx)\n", obj, obj->handle);
@ -321,7 +322,7 @@ static void fileobj_release(struct memobj *memobj)
#endif
}
obj_list_remove(free_obj);
mcs_lock_unlock_noirq(&fileobj_list_lock, &node);
mcs_rwlock_writer_unlock_noirq(&fileobj_list_lock, &node);
kfree(free_obj);
}
@ -367,10 +368,10 @@ static void fileobj_do_pageio(void *args0)
struct page *page;
ihk_mc_user_context_t ctx;
ssize_t ss;
mcs_lock_node_t mcs_node;
struct mcs_rwlock_node mcs_node;
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
page = __fileobj_page_hash_lookup(obj, hash, off);
if (!page) {
@ -378,10 +379,10 @@ static void fileobj_do_pageio(void *args0)
}
while (page->mode == PM_PAGEIO) {
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
cpu_pause();
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
}
@ -392,7 +393,7 @@ static void fileobj_do_pageio(void *args0)
}
else {
page->mode = PM_PAGEIO;
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
ihk_mc_syscall_arg0(&ctx) = PAGER_REQ_READ;
@ -405,7 +406,7 @@ static void fileobj_do_pageio(void *args0)
__FUNCTION__, obj->handle);
ss = syscall_generic_forwarding(__NR_mmap, &ctx);
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
if (page->mode != PM_PAGEIO) {
kprintf("fileobj_do_pageio(%p,%lx,%lx):"
@ -432,7 +433,7 @@ static void fileobj_do_pageio(void *args0)
page->mode = PM_DONE_PAGEIO;
}
out:
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
fileobj_release(&obj->memobj); /* got fileobj_get_page() */
kfree(args0);
@ -451,7 +452,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
uintptr_t phys = -1;
struct page *page;
struct pageio_args *args = NULL;
mcs_lock_node_t mcs_node;
struct mcs_rwlock_node mcs_node;
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
dkprintf("fileobj_get_page(%p,%lx,%x,%p)\n", obj, off, p2align, physp);
@ -459,7 +460,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
return -ENOMEM;
}
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_lock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
page = __fileobj_page_hash_lookup(obj, hash, off);
if (!page || (page->mode == PM_WILL_PAGEIO)
@ -529,7 +530,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off,
*physp = page_to_phys(page);
virt = NULL;
out:
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_writer_unlock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
if (virt) {
ihk_mc_free_pages(virt, npages);
@ -598,7 +599,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
struct fileobj *obj = to_fileobj(memobj);
int error = -1;
struct page *page;
mcs_lock_node_t mcs_node;
struct mcs_rwlock_node mcs_node;
int hash = (off >> PAGE_SHIFT) & FILEOBJ_PAGE_HASH_MASK;
dkprintf("fileobj_lookup_page(%p,%lx,%x,%p)\n", obj, off, p2align, physp);
@ -607,7 +608,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
return -ENOMEM;
}
mcs_lock_lock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_reader_lock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
page = __fileobj_page_hash_lookup(obj, hash, off);
@ -619,7 +620,7 @@ static int fileobj_lookup_page(struct memobj *memobj, off_t off,
error = 0;
out:
mcs_lock_unlock_noirq(&obj->page_hash_locks[hash],
mcs_rwlock_reader_unlock_noirq(&obj->page_hash_locks[hash],
&mcs_node);
dkprintf("fileobj_lookup_page(%p,%lx,%x,%p): %d \n",