[RFC PATCH 3/9] mm/zbud: remove lru from zbud_header
From: Heesub Shin <hidden>
Date: 2014-10-14 12:01:18
Also in:
lkml
Subsystem:
memory management, the rest · Maintainers:
Andrew Morton, Linus Torvalds
zbud_pool has an lru list for tracking zbud pages and they are strung together via zhdr->lru. If we reuse page->lru for linking zbud pages instead of it, the lru field in zbud_header can be dropped. Signed-off-by: Heesub Shin <redacted> --- mm/zbud.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/mm/zbud.c b/mm/zbud.c
index 0f5add0..a2390f6 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c@@ -100,13 +100,11 @@ struct zbud_pool { * struct zbud_header - zbud page metadata occupying the first chunk of each * zbud page. * @buddy: links the zbud page into the unbuddied lists in the pool - * @lru: links the zbud page into the lru list in the pool * @first_chunks: the size of the first buddy in chunks, 0 if free * @last_chunks: the size of the last buddy in chunks, 0 if free */ struct zbud_header { struct list_head buddy; - struct list_head lru; unsigned int first_chunks; unsigned int last_chunks; bool under_reclaim;
@@ -224,7 +222,7 @@ static struct zbud_header *init_zbud_page(struct page *page) zhdr->first_chunks = 0; zhdr->last_chunks = 0; INIT_LIST_HEAD(&zhdr->buddy); - INIT_LIST_HEAD(&zhdr->lru); + INIT_LIST_HEAD(&page->lru); zhdr->under_reclaim = 0; return zhdr; }
@@ -352,6 +350,7 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp, if (!list_empty(&pool->unbuddied[i])) { zhdr = list_first_entry(&pool->unbuddied[i], struct zbud_header, buddy); + page = virt_to_page(zhdr); list_del(&zhdr->buddy); goto found; }
@@ -382,9 +381,9 @@ found: } /* Add/move zbud page to beginning of LRU */ - if (!list_empty(&zhdr->lru)) - list_del(&zhdr->lru); - list_add(&zhdr->lru, &pool->lru); + if (!list_empty(&page->lru)) + list_del(&page->lru); + list_add(&page->lru, &pool->lru); *handle = encode_handle(zhdr, bud); spin_unlock(&pool->lock);
@@ -405,10 +404,12 @@ found: void zbud_free(struct zbud_pool *pool, unsigned long handle) { struct zbud_header *zhdr; + struct page *page; int freechunks; spin_lock(&pool->lock); zhdr = handle_to_zbud_header(handle); + page = virt_to_page(zhdr); /* If first buddy, handle will be page aligned */ if ((handle - ZHDR_SIZE_ALIGNED) & ~PAGE_MASK)
@@ -426,7 +427,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) /* Remove from existing unbuddied list */ list_del(&zhdr->buddy); /* zbud page is empty, free */ - list_del(&zhdr->lru); + list_del(&page->lru); free_zbud_page(zhdr); pool->pages_nr--; } else {
@@ -479,6 +480,7 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle) int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) { int i, ret, freechunks; + struct page *page; struct zbud_header *zhdr; unsigned long first_handle, last_handle;
@@ -489,8 +491,9 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries) return -EINVAL; } for (i = 0; i < retries; i++) { - zhdr = list_tail_entry(&pool->lru, struct zbud_header, lru); - list_del(&zhdr->lru); + page = list_tail_entry(&pool->lru, struct page, lru); + zhdr = page_address(page); + list_del(&page->lru); list_del(&zhdr->buddy); /* Protect zbud page against free */ zhdr->under_reclaim = true;
@@ -537,7 +540,7 @@ next: } /* add to beginning of LRU */ - list_add(&zhdr->lru, &pool->lru); + list_add(&page->lru, &pool->lru); } spin_unlock(&pool->lock); return -EAGAIN;
--
1.9.1
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>