From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: linux-mm@kvack.org
Cc: linux-kernel@vger.kernel.org, tglx@linuxtronix.de, mingo@elte.hu,
davem@davemloft.net, lethal@linux-sh.org,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [PATCH 18/25] lmb: Move functions around into a more sensible order
Date: Mon, 10 May 2010 19:38:52 +1000 [thread overview]
Message-ID: <1273484339-28911-19-git-send-email-benh@kernel.crashing.org> (raw)
In-Reply-To: <1273484339-28911-18-git-send-email-benh@kernel.crashing.org>
Some shuffling is needed for doing array resize so we may as well
put some sense into the ordering of the functions in the whole lmb.c
file. No code change. Added some comments.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
lib/lmb.c | 295 ++++++++++++++++++++++++++++++++----------------------------
1 files changed, 157 insertions(+), 138 deletions(-)
diff --git a/lib/lmb.c b/lib/lmb.c
index 95ef5b6..4977888 100644
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -24,40 +24,18 @@ static struct lmb_region lmb_reserved_init_regions[INIT_LMB_REGIONS + 1];
#define LMB_ERROR (~(phys_addr_t)0)
-static int __init early_lmb(char *p)
-{
- if (p && strstr(p, "debug"))
- lmb_debug = 1;
- return 0;
-}
-early_param("lmb", early_lmb);
+/*
+ * Address comparison utilities
+ */
-static void lmb_dump(struct lmb_type *region, char *name)
+static phys_addr_t lmb_align_down(phys_addr_t addr, phys_addr_t size)
{
- unsigned long long base, size;
- int i;
-
- pr_info(" %s.cnt = 0x%lx\n", name, region->cnt);
-
- for (i = 0; i < region->cnt; i++) {
- base = region->regions[i].base;
- size = region->regions[i].size;
-
- pr_info(" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n",
- name, i, base, base + size - 1, size);
- }
+ return addr & ~(size - 1);
}
-void lmb_dump_all(void)
+static phys_addr_t lmb_align_up(phys_addr_t addr, phys_addr_t size)
{
- if (!lmb_debug)
- return;
-
- pr_info("LMB configuration:\n");
- pr_info(" memory size = 0x%llx\n", (unsigned long long)lmb.memory_size);
-
- lmb_dump(&lmb.memory, "memory");
- lmb_dump(&lmb.reserved, "reserved");
+ return (addr + (size - 1)) & ~(size - 1);
}
static unsigned long lmb_addrs_overlap(phys_addr_t base1, phys_addr_t size1,
@@ -88,6 +66,77 @@ static long lmb_regions_adjacent(struct lmb_type *type,
return lmb_addrs_adjacent(base1, size1, base2, size2);
}
+long lmb_overlaps_region(struct lmb_type *type, phys_addr_t base, phys_addr_t size)
+{
+ unsigned long i;
+
+ for (i = 0; i < type->cnt; i++) {
+ phys_addr_t rgnbase = type->regions[i].base;
+ phys_addr_t rgnsize = type->regions[i].size;
+ if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
+ break;
+ }
+
+ return (i < type->cnt) ? i : -1;
+}
+
+/*
+ * Find, allocate, deallocate or reserve unreserved regions. All allocations
+ * are top-down.
+ */
+
+static phys_addr_t __init lmb_find_region(phys_addr_t start, phys_addr_t end,
+ phys_addr_t size, phys_addr_t align)
+{
+ phys_addr_t base, res_base;
+ long j;
+
+ base = lmb_align_down((end - size), align);
+ while (start <= base) {
+ j = lmb_overlaps_region(&lmb.reserved, base, size);
+ if (j < 0)
+ return base;
+ res_base = lmb.reserved.regions[j].base;
+ if (res_base < size)
+ break;
+ base = lmb_align_down(res_base - size, align);
+ }
+
+ return LMB_ERROR;
+}
+
+static phys_addr_t __init lmb_find_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
+{
+ long i;
+ phys_addr_t base = 0;
+ phys_addr_t res_base;
+
+ BUG_ON(0 == size);
+
+ size = lmb_align_up(size, align);
+
+ /* Pump up max_addr */
+ if (max_addr == LMB_ALLOC_ACCESSIBLE)
+ max_addr = lmb.current_limit;
+
+ /* We do a top-down search, this tends to limit memory
+ * fragmentation by keeping early boot allocs near the
+ * top of memory
+ */
+ for (i = lmb.memory.cnt - 1; i >= 0; i--) {
+ phys_addr_t lmbbase = lmb.memory.regions[i].base;
+ phys_addr_t lmbsize = lmb.memory.regions[i].size;
+
+ if (lmbsize < size)
+ continue;
+ base = min(lmbbase + lmbsize, max_addr);
+ res_base = lmb_find_region(lmbbase, base, size, align);
+ if (res_base != LMB_ERROR)
+ return res_base;
+ }
+ return 0;
+}
+
static void lmb_remove_region(struct lmb_type *type, unsigned long r)
{
unsigned long i;
@@ -107,22 +156,6 @@ static void lmb_coalesce_regions(struct lmb_type *type,
lmb_remove_region(type, r2);
}
-void __init lmb_analyze(void)
-{
- int i;
-
- /* Check marker in the unused last array entry */
- WARN_ON(lmb_memory_init_regions[INIT_LMB_REGIONS].base
- != (phys_addr_t)RED_INACTIVE);
- WARN_ON(lmb_reserved_init_regions[INIT_LMB_REGIONS].base
- != (phys_addr_t)RED_INACTIVE);
-
- lmb.memory_size = 0;
-
- for (i = 0; i < lmb.memory.cnt; i++)
- lmb.memory_size += lmb.memory.regions[i].size;
-}
-
static long lmb_add_region(struct lmb_type *type, phys_addr_t base, phys_addr_t size)
{
unsigned long coalesced = 0;
@@ -260,50 +293,42 @@ long __init lmb_reserve(phys_addr_t base, phys_addr_t size)
return lmb_add_region(_rgn, base, size);
}
-long lmb_overlaps_region(struct lmb_type *type, phys_addr_t base, phys_addr_t size)
+phys_addr_t __init __lmb_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
{
- unsigned long i;
+ phys_addr_t found = lmb_find_base(size, align, max_addr);
- for (i = 0; i < type->cnt; i++) {
- phys_addr_t rgnbase = type->regions[i].base;
- phys_addr_t rgnsize = type->regions[i].size;
- if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
- break;
- }
+ if (found != LMB_ERROR &&
+ lmb_add_region(&lmb.reserved, found, size) >= 0)
+ return found;
- return (i < type->cnt) ? i : -1;
+ return 0;
}
-static phys_addr_t lmb_align_down(phys_addr_t addr, phys_addr_t size)
+phys_addr_t __init lmb_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
{
- return addr & ~(size - 1);
-}
+ phys_addr_t alloc;
-static phys_addr_t lmb_align_up(phys_addr_t addr, phys_addr_t size)
-{
- return (addr + (size - 1)) & ~(size - 1);
-}
+ alloc = __lmb_alloc_base(size, align, max_addr);
-static phys_addr_t __init lmb_find_region(phys_addr_t start, phys_addr_t end,
- phys_addr_t size, phys_addr_t align)
-{
- phys_addr_t base, res_base;
- long j;
+ if (alloc == 0)
+ panic("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n",
+ (unsigned long long) size, (unsigned long long) max_addr);
- base = lmb_align_down((end - size), align);
- while (start <= base) {
- j = lmb_overlaps_region(&lmb.reserved, base, size);
- if (j < 0)
- return base;
- res_base = lmb.reserved.regions[j].base;
- if (res_base < size)
- break;
- base = lmb_align_down(res_base - size, align);
- }
+ return alloc;
+}
- return LMB_ERROR;
+phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align)
+{
+ return lmb_alloc_base(size, align, LMB_ALLOC_ACCESSIBLE);
}
+
+/*
+ * Additional node-local allocators. Search for node memory is bottom up
+ * and walks lmb regions within that node bottom-up as well, but allocation
+ * within an lmb region is top-down.
+ */
+
phys_addr_t __weak __init lmb_nid_range(phys_addr_t start, phys_addr_t end, int *nid)
{
*nid = 0;
@@ -361,67 +386,9 @@ phys_addr_t __init lmb_alloc_nid(phys_addr_t size, phys_addr_t align, int nid)
return lmb_alloc(size, align);
}
-phys_addr_t __init lmb_alloc(phys_addr_t size, phys_addr_t align)
-{
- return lmb_alloc_base(size, align, LMB_ALLOC_ACCESSIBLE);
-}
-
-static phys_addr_t __init lmb_find_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
-{
- long i;
- phys_addr_t base = 0;
- phys_addr_t res_base;
-
- BUG_ON(0 == size);
-
- size = lmb_align_up(size, align);
-
- /* Pump up max_addr */
- if (max_addr == LMB_ALLOC_ACCESSIBLE)
- max_addr = lmb.current_limit;
-
- /* We do a top-down search, this tends to limit memory
- * fragmentation by keeping early boot allocs near the
- * top of memory
- */
- for (i = lmb.memory.cnt - 1; i >= 0; i--) {
- phys_addr_t lmbbase = lmb.memory.regions[i].base;
- phys_addr_t lmbsize = lmb.memory.regions[i].size;
-
- if (lmbsize < size)
- continue;
- base = min(lmbbase + lmbsize, max_addr);
- res_base = lmb_find_region(lmbbase, base, size, align);
- if (res_base != LMB_ERROR)
- return res_base;
- }
- return 0;
-}
-
-phys_addr_t __init __lmb_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
-{
- phys_addr_t found = lmb_find_base(size, align, max_addr);
-
- if (found != LMB_ERROR &&
- lmb_add_region(&lmb.reserved, found, size) >= 0)
- return found;
-
- return 0;
-}
-
-phys_addr_t __init lmb_alloc_base(phys_addr_t size, phys_addr_t align, phys_addr_t max_addr)
-{
- phys_addr_t alloc;
-
- alloc = __lmb_alloc_base(size, align, max_addr);
-
- if (alloc == 0)
- panic("ERROR: Failed to allocate 0x%llx bytes below 0x%llx.\n",
- (unsigned long long) size, (unsigned long long) max_addr);
-
- return alloc;
-}
-
+/*
+ * Remaining API functions
+ */
/* You must call lmb_analyze() before this. */
phys_addr_t __init lmb_phys_mem_size(void)
@@ -501,6 +468,50 @@ void __init lmb_set_current_limit(phys_addr_t limit)
lmb.current_limit = limit;
}
+static void lmb_dump(struct lmb_type *region, char *name)
+{
+ unsigned long long base, size;
+ int i;
+
+ pr_info(" %s.cnt = 0x%lx\n", name, region->cnt);
+
+ for (i = 0; i < region->cnt; i++) {
+ base = region->regions[i].base;
+ size = region->regions[i].size;
+
+ pr_info(" %s[0x%x]\t0x%016llx - 0x%016llx, 0x%llx bytes\n",
+ name, i, base, base + size - 1, size);
+ }
+}
+
+void lmb_dump_all(void)
+{
+ if (!lmb_debug)
+ return;
+
+ pr_info("LMB configuration:\n");
+ pr_info(" memory size = 0x%llx\n", (unsigned long long)lmb.memory_size);
+
+ lmb_dump(&lmb.memory, "memory");
+ lmb_dump(&lmb.reserved, "reserved");
+}
+
+void __init lmb_analyze(void)
+{
+ int i;
+
+ /* Check marker in the unused last array entry */
+ WARN_ON(lmb_memory_init_regions[INIT_LMB_REGIONS].base
+ != (phys_addr_t)RED_INACTIVE);
+ WARN_ON(lmb_reserved_init_regions[INIT_LMB_REGIONS].base
+ != (phys_addr_t)RED_INACTIVE);
+
+ lmb.memory_size = 0;
+
+ for (i = 0; i < lmb.memory.cnt; i++)
+ lmb.memory_size += lmb.memory.regions[i].size;
+}
+
void __init lmb_init(void)
{
/* Hookup the initial arrays */
@@ -528,3 +539,11 @@ void __init lmb_init(void)
lmb.current_limit = LMB_ALLOC_ANYWHERE;
}
+static int __init early_lmb(char *p)
+{
+ if (p && strstr(p, "debug"))
+ lmb_debug = 1;
+ return 0;
+}
+early_param("lmb", early_lmb);
+
--
1.6.3.3
--
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:[~2010-05-10 9:45 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-05-10 9:38 [PATCH/WIP] lmb cleanups and additions Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 01/25] lmb: Rename lmb_region to lmb_type and lmb_property to lmb_region Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 02/25] lmb: No reason to include asm/lmb.h late Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 03/25] lmb: Introduce for_each_lmb() and new accessors, and use it Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 04/25] lmb: Remove nid_range argument, arch provides lmb_nid_range() instead Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 05/25] lmb: Factor the lowest level alloc function Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 06/25] lmb: Expose LMB_ALLOC_ANYWHERE Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 07/25] lmb: Introduce default allocation limit and use it to replace explicit ones Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 08/25] lmb: Remove rmo_size, burry it in arch/powerpc where it belongs Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 09/25] lmb: Change u64 to phys_addr_t Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 10/25] lmb: Remove unused lmb.debug struct member Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 11/25] lmb: Remove lmb_type.size and add lmb.memory_size instead Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 12/25] lmb: Move lmb arrays to static storage in lmb.c and make their size a variable Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 13/25] lmb: Add debug markers at the end of the array Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 14/25] lmb: Make lmb_find_region() out of lmb_alloc_region() Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 15/25] lmb: Define LMB_ERROR internally instead of using ~(phys_addr_t)0 Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 16/25] lmb: Move lmb_init() to the bottom of the file Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 17/25] lmb: split lmb_find_base() out of __lmb_alloc_base() Benjamin Herrenschmidt
2010-05-10 9:38 ` Benjamin Herrenschmidt [this message]
2010-05-10 9:38 ` [PATCH 19/25] lmb: Add array resizing support Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 20/25] lmb: Add arch function to control coalescing of lmb memory regions Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 21/25] lmb: Add "start" argument to lmb_find_base() Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 22/25] lmb: NUMA allocate can now use early_pfn_map Benjamin Herrenschmidt
2010-05-10 9:38 ` [PATCH 23/25] lmb: Separate lmb_alloc_nid() and lmb_alloc_try_nid() Benjamin Herrenschmidt
2010-05-10 23:37 ` [PATCH 21/25] lmb: Add "start" argument to lmb_find_base() Yinghai Lu
2010-05-11 4:56 ` Benjamin Herrenschmidt
2010-05-10 23:59 ` [PATCH 19/25] lmb: Add array resizing support Yinghai Lu
2010-05-11 4:56 ` Benjamin Herrenschmidt
2010-05-11 17:54 ` Yinghai Lu
2010-05-10 10:44 ` [PATCH 12/25] lmb: Move lmb arrays to static storage in lmb.c and make their size a variable Paul Mundt
2010-05-10 11:46 ` Benjamin Herrenschmidt
2010-05-11 12:30 ` [PATCH 05/25] lmb: Factor the lowest level alloc function Thomas Gleixner
2010-05-11 22:24 ` Benjamin Herrenschmidt
2010-05-12 5:24 ` Benjamin Herrenschmidt
2010-05-10 15:39 ` [PATCH 03/25] lmb: Introduce for_each_lmb() and new accessors, and use it Thomas Gleixner
2010-05-10 21:52 ` Benjamin Herrenschmidt
2010-05-12 5:20 ` Benjamin Herrenschmidt
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=1273484339-28911-19-git-send-email-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=davem@davemloft.net \
--cc=lethal@linux-sh.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mingo@elte.hu \
--cc=tglx@linuxtronix.de \
/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;
as well as URLs for NNTP newsgroup(s).