From: Heesub Shin <heesub.shin@samsung.com>
To: Andrew Morton <akpm@linux-foundation.org>,
Seth Jennings <sjennings@variantweb.net>
Cc: Nitin Gupta <ngupta@vflare.org>,
Dan Streetman <ddstreet@ieee.org>,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Sunae Seo <sunae.seo@samsung.com>,
Heesub Shin <heesub.shin@samsung.com>
Subject: [RFC PATCH 4/9] mm/zbud: remove first|last_chunks from zbud_header
Date: Tue, 14 Oct 2014 20:59:23 +0900 [thread overview]
Message-ID: <1413287968-13940-5-git-send-email-heesub.shin@samsung.com> (raw)
In-Reply-To: <1413287968-13940-1-git-send-email-heesub.shin@samsung.com>
The size information of each first and last buddy are stored into
first|last_chunks in struct zbud_header respectively. Put them into
page->private instead of zbud_header.
Signed-off-by: Heesub Shin <heesub.shin@samsung.com>
---
mm/zbud.c | 62 ++++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 36 insertions(+), 26 deletions(-)
diff --git a/mm/zbud.c b/mm/zbud.c
index a2390f6..193ea4f 100644
--- a/mm/zbud.c
+++ b/mm/zbud.c
@@ -100,13 +100,9 @@ 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
- * @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;
- unsigned int first_chunks;
- unsigned int last_chunks;
bool under_reclaim;
};
@@ -212,6 +208,17 @@ static int size_to_chunks(size_t size)
return (size + CHUNK_SIZE - 1) >> CHUNK_SHIFT;
}
+static void set_num_chunks(struct page *page, enum buddy bud, size_t chunks)
+{
+ page->private = (page->private & (0xffff << (16 * !bud))) |
+ ((chunks & 0xffff) << (16 * bud));
+}
+
+static size_t get_num_chunks(struct page *page, enum buddy bud)
+{
+ return (page->private >> (16 * bud)) & 0xffff;
+}
+
#define for_each_unbuddied_list(_iter, _begin) \
for ((_iter) = (_begin); (_iter) < NCHUNKS; (_iter)++)
@@ -219,8 +226,8 @@ static int size_to_chunks(size_t size)
static struct zbud_header *init_zbud_page(struct page *page)
{
struct zbud_header *zhdr = page_address(page);
- zhdr->first_chunks = 0;
- zhdr->last_chunks = 0;
+ set_num_chunks(page, FIRST, 0);
+ set_num_chunks(page, LAST, 0);
INIT_LIST_HEAD(&zhdr->buddy);
INIT_LIST_HEAD(&page->lru);
zhdr->under_reclaim = 0;
@@ -240,6 +247,7 @@ static void free_zbud_page(struct zbud_header *zhdr)
static unsigned long encode_handle(struct zbud_header *zhdr, enum buddy bud)
{
unsigned long handle;
+ struct page *page = virt_to_page(zhdr);
/*
* For now, the encoded handle is actually just the pointer to the data
@@ -252,7 +260,8 @@ static unsigned long encode_handle(struct zbud_header *zhdr, enum buddy bud)
/* skip over zbud header */
handle += ZHDR_SIZE_ALIGNED;
else /* bud == LAST */
- handle += PAGE_SIZE - (zhdr->last_chunks << CHUNK_SHIFT);
+ handle += PAGE_SIZE -
+ (get_num_chunks(page, LAST) << CHUNK_SHIFT);
return handle;
}
@@ -263,13 +272,14 @@ static struct zbud_header *handle_to_zbud_header(unsigned long handle)
}
/* Returns the number of free chunks in a zbud page */
-static int num_free_chunks(struct zbud_header *zhdr)
+static int num_free_chunks(struct page *page)
{
/*
* Rather than branch for different situations, just use the fact that
* free buddies have a length of zero to simplify everything.
*/
- return NCHUNKS - zhdr->first_chunks - zhdr->last_chunks;
+ return NCHUNKS - get_num_chunks(page, FIRST)
+ - get_num_chunks(page, LAST);
}
/*****************
@@ -366,17 +376,17 @@ int zbud_alloc(struct zbud_pool *pool, size_t size, gfp_t gfp,
zhdr = init_zbud_page(page);
found:
- if (zhdr->first_chunks == 0) {
- zhdr->first_chunks = chunks;
+ if (get_num_chunks(page, FIRST) == 0)
bud = FIRST;
- } else {
- zhdr->last_chunks = chunks;
+ else
bud = LAST;
- }
- if (zhdr->first_chunks == 0 || zhdr->last_chunks == 0) {
+ set_num_chunks(page, bud, chunks);
+
+ if (get_num_chunks(page, FIRST) == 0 ||
+ get_num_chunks(page, LAST) == 0) {
/* Add to unbuddied list */
- freechunks = num_free_chunks(zhdr);
+ freechunks = num_free_chunks(page);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
@@ -413,9 +423,9 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
/* If first buddy, handle will be page aligned */
if ((handle - ZHDR_SIZE_ALIGNED) & ~PAGE_MASK)
- zhdr->last_chunks = 0;
+ set_num_chunks(page, LAST, 0);
else
- zhdr->first_chunks = 0;
+ set_num_chunks(page, FIRST, 0);
if (zhdr->under_reclaim) {
/* zbud page is under reclaim, reclaim will free */
@@ -423,7 +433,8 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
return;
}
- if (num_free_chunks(zhdr) == NCHUNKS) {
+ freechunks = num_free_chunks(page);
+ if (freechunks == NCHUNKS) {
/* Remove from existing unbuddied list */
list_del(&zhdr->buddy);
/* zbud page is empty, free */
@@ -432,7 +443,6 @@ void zbud_free(struct zbud_pool *pool, unsigned long handle)
pool->pages_nr--;
} else {
/* Add to unbuddied list */
- freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
@@ -503,9 +513,9 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
*/
first_handle = 0;
last_handle = 0;
- if (zhdr->first_chunks)
+ if (get_num_chunks(page, FIRST))
first_handle = encode_handle(zhdr, FIRST);
- if (zhdr->last_chunks)
+ if (get_num_chunks(page, LAST))
last_handle = encode_handle(zhdr, LAST);
spin_unlock(&pool->lock);
@@ -523,7 +533,8 @@ int zbud_reclaim_page(struct zbud_pool *pool, unsigned int retries)
next:
spin_lock(&pool->lock);
zhdr->under_reclaim = false;
- if (num_free_chunks(zhdr) == NCHUNKS) {
+ freechunks = num_free_chunks(page);
+ if (freechunks == NCHUNKS) {
/*
* Both buddies are now free, free the zbud page and
* return success.
@@ -532,10 +543,9 @@ next:
pool->pages_nr--;
spin_unlock(&pool->lock);
return 0;
- } else if (zhdr->first_chunks == 0 ||
- zhdr->last_chunks == 0) {
+ } else if (get_num_chunks(page, FIRST) == 0 ||
+ get_num_chunks(page, LAST) == 0) {
/* add to unbuddied list */
- freechunks = num_free_chunks(zhdr);
list_add(&zhdr->buddy, &pool->unbuddied[freechunks]);
}
--
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>
next prev parent reply other threads:[~2014-10-14 11:59 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-10-14 11:59 [RFC PATCH 0/9] mm/zbud: support highmem pages Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 1/9] mm/zbud: tidy up a bit Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 2/9] mm/zbud: remove buddied list from zbud_pool Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 3/9] mm/zbud: remove lru from zbud_header Heesub Shin
2014-10-14 11:59 ` Heesub Shin [this message]
2014-10-14 11:59 ` [RFC PATCH 5/9] mm/zbud: encode zbud handle using struct page Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 6/9] mm/zbud: remove list_head for buddied list from zbud_header Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 7/9] mm/zbud: drop zbud_header Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 8/9] mm/zbud: allow clients to use highmem pages Heesub Shin
2014-10-14 11:59 ` [RFC PATCH 9/9] mm/zswap: use highmem pages for compressed pool Heesub Shin
2014-10-23 23:14 ` [RFC PATCH 0/9] mm/zbud: support highmem pages Dan Streetman
2014-10-24 15:27 ` Seth Jennings
2014-11-04 16:33 ` Seth Jennings
2015-01-27 20:24 ` Seth Jennings
2015-01-28 7:14 ` Heesub Shin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1413287968-13940-5-git-send-email-heesub.shin@samsung.com \
--to=heesub.shin@samsung.com \
--cc=akpm@linux-foundation.org \
--cc=ddstreet@ieee.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ngupta@vflare.org \
--cc=sjennings@variantweb.net \
--cc=sunae.seo@samsung.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox