From: Tejun Heo <tj@kernel.org>
To: mingo@elte.hu, rusty@rustcorp.com.au, tglx@linutronix.de,
x86@kernel.org, linux-kernel@vger.kernel.org, hpa@zytor.com,
npiggin@suse.de, akpm@linux-foundation.org
Cc: Tejun Heo <tj@kernel.org>
Subject: [PATCH 1/4] percpu: replace pcpu_realloc() with pcpu_mem_alloc() and pcpu_mem_free()
Date: Sat, 7 Mar 2009 00:54:40 +0900 [thread overview]
Message-ID: <1236354883-25063-2-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1236354883-25063-1-git-send-email-tj@kernel.org>
Impact: code reorganization for later changes
With static map handling moved to pcpu_split_block(), pcpu_realloc()
only clutters the code and it's also unsuitable for scheduled locking
changes. Implement and use pcpu_mem_alloc/free() instead.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
mm/percpu.c | 85 +++++++++++++++++++++++++++++------------------------------
1 files changed, 42 insertions(+), 43 deletions(-)
diff --git a/mm/percpu.c b/mm/percpu.c
index ef8e169..f1d0e90 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -164,39 +164,41 @@ static bool pcpu_chunk_page_occupied(struct pcpu_chunk *chunk,
}
/**
- * pcpu_realloc - versatile realloc
- * @p: the current pointer (can be NULL for new allocations)
- * @size: the current size in bytes (can be 0 for new allocations)
- * @new_size: the wanted new size in bytes (can be 0 for free)
+ * pcpu_mem_alloc - allocate memory
+ * @size: bytes to allocate
*
- * More robust realloc which can be used to allocate, resize or free a
- * memory area of arbitrary size. If the needed size goes over
- * PAGE_SIZE, kernel VM is used.
+ * Allocate @size bytes. If @size is smaller than PAGE_SIZE,
+ * kzalloc() is used; otherwise, vmalloc() is used. The returned
+ * memory is always zeroed.
*
* RETURNS:
- * The new pointer on success, NULL on failure.
+ * Pointer to the allocated area on success, NULL on failure.
*/
-static void *pcpu_realloc(void *p, size_t size, size_t new_size)
+static void *pcpu_mem_alloc(size_t size)
{
- void *new;
-
- if (new_size <= PAGE_SIZE)
- new = kmalloc(new_size, GFP_KERNEL);
- else
- new = vmalloc(new_size);
- if (new_size && !new)
- return NULL;
-
- memcpy(new, p, min(size, new_size));
- if (new_size > size)
- memset(new + size, 0, new_size - size);
+ if (size <= PAGE_SIZE)
+ return kzalloc(size, GFP_KERNEL);
+ else {
+ void *ptr = vmalloc(size);
+ if (ptr)
+ memset(ptr, 0, size);
+ return ptr;
+ }
+}
+/**
+ * pcpu_mem_free - free memory
+ * @ptr: memory to free
+ * @size: size of the area
+ *
+ * Free @ptr. @ptr should have been allocated using pcpu_mem_alloc().
+ */
+static void pcpu_mem_free(void *ptr, size_t size)
+{
if (size <= PAGE_SIZE)
- kfree(p);
+ kfree(ptr);
else
- vfree(p);
-
- return new;
+ vfree(ptr);
}
/**
@@ -331,29 +333,27 @@ static int pcpu_split_block(struct pcpu_chunk *chunk, int i, int head, int tail)
if (chunk->map_alloc < target) {
int new_alloc;
int *new;
+ size_t size;
new_alloc = PCPU_DFL_MAP_ALLOC;
while (new_alloc < target)
new_alloc *= 2;
- if (chunk->map_alloc < PCPU_DFL_MAP_ALLOC) {
- /*
- * map_alloc smaller than the default size
- * indicates that the chunk is one of the
- * first chunks and still using static map.
- * Allocate a dynamic one and copy.
- */
- new = pcpu_realloc(NULL, 0, new_alloc * sizeof(new[0]));
- if (new)
- memcpy(new, chunk->map,
- chunk->map_alloc * sizeof(new[0]));
- } else
- new = pcpu_realloc(chunk->map,
- chunk->map_alloc * sizeof(new[0]),
- new_alloc * sizeof(new[0]));
+ new = pcpu_mem_alloc(new_alloc * sizeof(new[0]));
if (!new)
return -ENOMEM;
+ size = chunk->map_alloc * sizeof(chunk->map[0]);
+ memcpy(new, chunk->map, size);
+
+ /*
+ * map_alloc < PCPU_DFL_MAP_ALLOC indicates that the
+ * chunk is one of the first chunks and still using
+ * static map.
+ */
+ if (chunk->map_alloc >= PCPU_DFL_MAP_ALLOC)
+ pcpu_mem_free(chunk->map, size);
+
chunk->map_alloc = new_alloc;
chunk->map = new;
}
@@ -696,7 +696,7 @@ static void free_pcpu_chunk(struct pcpu_chunk *chunk)
return;
if (chunk->vm)
free_vm_area(chunk->vm);
- pcpu_realloc(chunk->map, chunk->map_alloc * sizeof(chunk->map[0]), 0);
+ pcpu_mem_free(chunk->map, chunk->map_alloc * sizeof(chunk->map[0]));
kfree(chunk);
}
@@ -708,8 +708,7 @@ static struct pcpu_chunk *alloc_pcpu_chunk(void)
if (!chunk)
return NULL;
- chunk->map = pcpu_realloc(NULL, 0,
- PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
+ chunk->map = pcpu_mem_alloc(PCPU_DFL_MAP_ALLOC * sizeof(chunk->map[0]));
chunk->map_alloc = PCPU_DFL_MAP_ALLOC;
chunk->map[chunk->map_used++] = pcpu_unit_size;
chunk->page = chunk->page_ar;
--
1.6.0.2
next prev parent reply other threads:[~2009-03-06 15:56 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-03-06 15:54 [GIT PULL] percpu: finer grained locking Tejun Heo
2009-03-06 15:54 ` Tejun Heo [this message]
2009-03-06 15:54 ` [PATCH 2/4] percpu: move chunk area map extension out of area allocation Tejun Heo
2009-03-06 15:54 ` [PATCH 3/4] percpu: move fully free chunk reclamation into a work Tejun Heo
2009-03-06 15:54 ` [PATCH 4/4] percpu: finer grained locking to break deadlock and allow atomic free Tejun Heo
2009-03-07 5:49 ` [PATCH UPDATED " Tejun Heo
2009-03-08 10:20 ` Ingo Molnar
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=1236354883-25063-2-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=npiggin@suse.de \
--cc=rusty@rustcorp.com.au \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/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