From 29c7d400052b4506e64b93890372cf96d84da43b Mon Sep 17 00:00:00 2001 From: NAKAMURA Gou Date: Wed, 7 May 2014 18:16:13 +0900 Subject: [PATCH] use atomic operations for manipulating page.count --- kernel/fileobj.c | 21 +++++++++++++-------- kernel/include/page.h | 4 +++- kernel/mem.c | 5 ++++- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/kernel/fileobj.c b/kernel/fileobj.c index 4b4e734d..87578399 100644 --- a/kernel/fileobj.c +++ b/kernel/fileobj.c @@ -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; diff --git a/kernel/include/page.h b/kernel/include/page.h index b5ff5fce..5c850bf8 100644 --- a/kernel/include/page.h +++ b/kernel/include/page.h @@ -13,11 +13,13 @@ #ifndef __HEADER_PAGE_H #define __HEADER_PAGE_H +#include + struct page { struct list_head list; uint8_t mode; uint8_t padding[3]; - int32_t count; + ihk_atomic_t count; off_t offset; }; diff --git a/kernel/mem.c b/kernel/mem.c index 34ebfd77..95bbd963 100644 --- a/kernel/mem.c +++ b/kernel/mem.c @@ -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;