use atomic operations for manipulating page.count

This commit is contained in:
NAKAMURA Gou
2014-05-07 18:16:13 +09:00
parent 604d1da50f
commit 29c7d40005
3 changed files with 20 additions and 10 deletions

View File

@@ -253,23 +253,25 @@ static void fileobj_release(struct memobj *memobj)
/* zap page_list */
for (;;) {
struct page *page;
int count;
page = page_list_first(obj);
if (!page) {
break;
}
page_list_remove(obj, page);
count = ihk_atomic_sub_return(1, &page->count);
if (!((page->mode == PM_WILL_PAGEIO)
|| (page->mode == PM_DONE_PAGEIO)
|| (page->mode == PM_PAGEIO_EOF)
|| (page->mode == PM_PAGEIO_ERROR)
|| ((page->mode == PM_MAPPED)
&& (page->count <= 0)))) {
&& (count <= 0)))) {
kprintf("fileobj_release(%p %lx): "
"mode %x, count %d, off %lx\n",
obj, obj->handle, page->mode,
page->count, page->offset);
count, page->offset);
panic("fileobj_release");
}
@@ -429,6 +431,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintp
}
page->mode = PM_WILL_PAGEIO;
page->offset = off;
ihk_atomic_set(&page->count, 1);
page_list_insert(obj, page);
}
@@ -448,7 +451,6 @@ static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintp
}
else if (page->mode == PM_DONE_PAGEIO) {
page->mode = PM_MAPPED;
page->count = 0;
}
else if (page->mode == PM_PAGEIO_EOF) {
error = -ERANGE;
@@ -459,7 +461,7 @@ static int fileobj_get_page(struct memobj *memobj, off_t off, int p2align, uintp
goto out;
}
++page->count;
ihk_atomic_inc(&page->count);
error = 0;
*physp = page_to_phys(page);
@@ -486,6 +488,7 @@ static uintptr_t fileobj_copy_page(
void *newkva = NULL;
uintptr_t newpa = -1;
void *orgkva;
int count;
dkprintf("fileobj_copy_page(%p,%lx,%d)\n", memobj, orgpa, p2align);
if (p2align != PAGE_P2ALIGN) {
@@ -500,22 +503,24 @@ static uintptr_t fileobj_copy_page(
memobj, orgpa, p2align, orgpage->mode);
panic("fileobj_copy_page:invalid cow page");
}
if (orgpage->count == 1) { // XXX: private only
count = ihk_atomic_read(&orgpage->count);
if (count == 2) { // XXX: private only
list_del(&orgpage->list);
ihk_atomic_dec(&orgpage->count);
orgpage->mode = PM_NONE;
newpa = orgpa;
break;
}
if (orgpage->count <= 0) {
if (count <= 0) {
kprintf("fileobj_copy_page(%p,%lx,%d):"
"orgpage count corrupted. %x\n",
memobj, orgpa, p2align, orgpage->count);
memobj, orgpa, p2align, count);
panic("fileobj_copy_page:orgpage count corrupted");
}
if (newkva) {
orgkva = phys_to_virt(orgpa);
memcpy(newkva, orgkva, pgsize);
--orgpage->count;
ihk_atomic_dec(&orgpage->count);
newpa = virt_to_phys(newkva);
newkva = NULL; /* avoid ihk_mc_free_pages() */
break;

View File

@@ -13,11 +13,13 @@
#ifndef __HEADER_PAGE_H
#define __HEADER_PAGE_H
#include <ihk/atomic.h>
struct page {
struct list_head list;
uint8_t mode;
uint8_t padding[3];
int32_t count;
ihk_atomic_t count;
off_t offset;
};

View File

@@ -343,7 +343,7 @@ int page_unmap(struct page *page)
return 1;
}
if (--page->count > 0) {
if (ihk_atomic_sub_return(1, &page->count) > 0) {
/* other mapping exist */
dkprintf("page_unmap(%p %x %d): 0\n",
page, page->mode, page->count);
@@ -363,6 +363,9 @@ static void page_init(void)
size_t allocsize;
size_t allocpages;
if (sizeof(ihk_atomic_t) != sizeof(uint32_t)) {
panic("sizeof(ihk_atomic_t) is not 32 bit");
}
npages = (pa_end - pa_start) >> PAGE_SHIFT;
allocsize = sizeof(struct page) * npages;
allocpages = (allocsize + PAGE_SIZE - 1) >> PAGE_SHIFT;