lkml.org 
[lkml]   [2010]   [Mar]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 12/31] lmb: Add lmb_register_active_regions() and lmb_hole_size()
    Date
    lmb_register_active_regions() will be used to fill early_node_map,
    the result will be lmb.memory.region AND numa data

    lmb_hole_size will be used to find hole size on lmb.memory.region
    with specified range.

    Signed-off-by: Yinghai Lu <yinghai@kernel.org>
    ---
    include/linux/lmb.h | 4 +++
    mm/lmb.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
    2 files changed, 72 insertions(+), 0 deletions(-)

    diff --git a/include/linux/lmb.h b/include/linux/lmb.h
    index 9e2dcf5..6568e9d 100644
    --- a/include/linux/lmb.h
    +++ b/include/linux/lmb.h
    @@ -96,6 +96,10 @@ void lmb_to_bootmem(u64 start, u64 end);
    struct range;
    int get_free_all_memory_range(struct range **rangep, int nodeid);

    +void lmb_register_active_regions(int nid, unsigned long start_pfn,
    + unsigned long last_pfn);
    +u64 lmb_hole_size(u64 start, u64 end);
    +
    #include <asm/lmb.h>

    #endif /* __KERNEL__ */
    diff --git a/mm/lmb.c b/mm/lmb.c
    index abece72..7e3c2c1 100644
    --- a/mm/lmb.c
    +++ b/mm/lmb.c
    @@ -912,3 +912,71 @@ u64 __init find_lmb_area_size(u64 start, u64 *sizep, u64 align)
    return -1ULL;
    }

    +/*
    + * Finds an active region in the address range from start_pfn to last_pfn and
    + * returns its range in ei_startpfn and ei_endpfn for the lmb entry.
    + */
    +static int __init lmb_find_active_region(const struct lmb_property *ei,
    + unsigned long start_pfn,
    + unsigned long last_pfn,
    + unsigned long *ei_startpfn,
    + unsigned long *ei_endpfn)
    +{
    + u64 align = PAGE_SIZE;
    +
    + *ei_startpfn = round_up(ei->base, align) >> PAGE_SHIFT;
    + *ei_endpfn = round_down(ei->base + ei->size, align) >> PAGE_SHIFT;
    +
    + /* Skip map entries smaller than a page */
    + if (*ei_startpfn >= *ei_endpfn)
    + return 0;
    +
    + /* Skip if map is outside the node */
    + if (*ei_endpfn <= start_pfn || *ei_startpfn >= last_pfn)
    + return 0;
    +
    + /* Check for overlaps */
    + if (*ei_startpfn < start_pfn)
    + *ei_startpfn = start_pfn;
    + if (*ei_endpfn > last_pfn)
    + *ei_endpfn = last_pfn;
    +
    + return 1;
    +}
    +
    +/* Walk the lmb.memory map and register active regions within a node */
    +void __init lmb_register_active_regions(int nid, unsigned long start_pfn,
    + unsigned long last_pfn)
    +{
    + unsigned long ei_startpfn;
    + unsigned long ei_endpfn;
    + int i;
    +
    + for (i = 0; i < lmb.memory.cnt; i++)
    + if (lmb_find_active_region(&lmb.memory.region[i],
    + start_pfn, last_pfn,
    + &ei_startpfn, &ei_endpfn))
    + add_active_range(nid, ei_startpfn, ei_endpfn);
    +}
    +
    +/*
    + * Find the hole size (in bytes) in the memory range.
    + * @start: starting address of the memory range to scan
    + * @end: ending address of the memory range to scan
    + */
    +u64 __init lmb_hole_size(u64 start, u64 end)
    +{
    + unsigned long start_pfn = start >> PAGE_SHIFT;
    + unsigned long last_pfn = end >> PAGE_SHIFT;
    + unsigned long ei_startpfn, ei_endpfn, ram = 0;
    + int i;
    +
    + for (i = 0; i < lmb.memory.cnt; i++) {
    + if (lmb_find_active_region(&lmb.memory.region[i],
    + start_pfn, last_pfn,
    + &ei_startpfn, &ei_endpfn))
    + ram += ei_endpfn - ei_startpfn;
    + }
    + return end - start - ((u64)ram << PAGE_SHIFT);
    +}
    +
    --
    1.6.4.2


    \
     
     \ /
      Last update: 2010-03-29 05:07    [W:5.132 / U:0.384 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site