Release 4.11 mm/bootmem.c
/*
* bootmem - A boot-time physical memory allocator and configurator
*
* Copyright (C) 1999 Ingo Molnar
* 1999 Kanoj Sarcar, SGI
* 2008 Johannes Weiner
*
* Access to this subsystem has to be serialized externally (which is true
* for the boot process anyway).
*/
#include <linux/init.h>
#include <linux/pfn.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/kmemleak.h>
#include <linux/range.h>
#include <linux/bug.h>
#include <linux/io.h>
#include <linux/bootmem.h>
#include "internal.h"
#ifndef CONFIG_NEED_MULTIPLE_NODES
struct pglist_data __refdata contig_page_data = {
.bdata = &bootmem_node_data[0]
};
EXPORT_SYMBOL(contig_page_data);
#endif
unsigned long max_low_pfn;
unsigned long min_low_pfn;
unsigned long max_pfn;
unsigned long long max_possible_pfn;
bootmem_data_t bootmem_node_data[MAX_NUMNODES] __initdata;
static struct list_head bdata_list __initdata = LIST_HEAD_INIT(bdata_list);
static int bootmem_debug;
static int __init bootmem_debug_setup(char *buf)
{
bootmem_debug = 1;
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 18 | 100.00% | 1 | 100.00% |
Total | 18 | 100.00% | 1 | 100.00% |
early_param("bootmem_debug", bootmem_debug_setup);
#define bdebug(fmt, args...) ({ \
if (unlikely(bootmem_debug)) \
pr_info("bootmem::%s " fmt, \
__func__, ## args); \
})
static unsigned long __init bootmap_bytes(unsigned long pages)
{
unsigned long bytes = DIV_ROUND_UP(pages, BITS_PER_BYTE);
return ALIGN(bytes, sizeof(long));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 29 | 85.29% | 2 | 50.00% |
Uwe Kleine-König | 4 | 11.76% | 1 | 25.00% |
Adygzhy Ondar | 1 | 2.94% | 1 | 25.00% |
Total | 34 | 100.00% | 4 | 100.00% |
/**
* bootmem_bootmap_pages - calculate bitmap size in pages
* @pages: number of pages the bitmap has to represent
*/
unsigned long __init bootmem_bootmap_pages(unsigned long pages)
{
unsigned long bytes = bootmap_bytes(pages);
return PAGE_ALIGN(bytes) >> PAGE_SHIFT;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 16 | 57.14% | 1 | 50.00% |
Johannes Weiner | 12 | 42.86% | 1 | 50.00% |
Total | 28 | 100.00% | 2 | 100.00% |
/*
* link bdata in order
*/
static void __init link_bootmem(bootmem_data_t *bdata)
{
bootmem_data_t *ent;
list_for_each_entry(ent, &bdata_list, list) {
if (bdata->node_min_pfn < ent->node_min_pfn) {
list_add_tail(&bdata->list, &ent->list);
return;
}
}
list_add_tail(&bdata->list, &bdata_list);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Kamezawa Hiroyuki | 32 | 51.61% | 1 | 20.00% |
Gavin Shan | 23 | 37.10% | 1 | 20.00% |
Johannes Weiner | 6 | 9.68% | 2 | 40.00% |
Franck Bui-Huu | 1 | 1.61% | 1 | 20.00% |
Total | 62 | 100.00% | 5 | 100.00% |
/*
* Called once to set up the allocator itself.
*/
static unsigned long __init init_bootmem_core(bootmem_data_t *bdata,
unsigned long mapstart, unsigned long start, unsigned long end)
{
unsigned long mapsize;
mminit_validate_memmodel_limits(&start, &end);
bdata->node_bootmem_map = phys_to_virt(PFN_PHYS(mapstart));
bdata->node_min_pfn = start;
bdata->node_low_pfn = end;
link_bootmem(bdata);
/*
* Initially all pages are reserved - setup_arch() has to
* register free RAM areas explicitly.
*/
mapsize = bootmap_bytes(end - start);
memset(bdata->node_bootmem_map, 0xff, mapsize);
bdebug("nid=%td start=%lx map=%lx end=%lx mapsize=%lx\n",
bdata - bootmem_node_data, start, mapstart, end, mapsize);
return mapsize;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Linus Torvalds (pre-git) | 36 | 33.64% | 3 | 30.00% |
Franck Bui-Huu | 33 | 30.84% | 1 | 10.00% |
Johannes Weiner | 24 | 22.43% | 4 | 40.00% |
Mel Gorman | 9 | 8.41% | 1 | 10.00% |
Kamezawa Hiroyuki | 5 | 4.67% | 1 | 10.00% |
Total | 107 | 100.00% | 10 | 100.00% |
/**
* init_bootmem_node - register a node as boot memory
* @pgdat: node to register
* @freepfn: pfn where the bitmap for this node is to be placed
* @startpfn: first pfn on the node
* @endpfn: first pfn after the node
*
* Returns the number of bytes needed to hold the bitmap for this node.
*/
unsigned long __init init_bootmem_node(pg_data_t *pgdat, unsigned long freepfn,
unsigned long startpfn, unsigned long endpfn)
{
return init_bootmem_core(pgdat->bdata, freepfn, startpfn, endpfn);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 25 | 67.57% | 1 | 25.00% |
Linus Torvalds (pre-git) | 11 | 29.73% | 2 | 50.00% |
Bernhard Walle | 1 | 2.70% | 1 | 25.00% |
Total | 37 | 100.00% | 4 | 100.00% |
/**
* init_bootmem - register boot memory
* @start: pfn where the bitmap is to be placed
* @pages: number of available physical pages
*
* Returns the number of bytes needed to hold the bitmap.
*/
unsigned long __init init_bootmem(unsigned long start, unsigned long pages)
{
max_low_pfn = pages;
min_low_pfn = start;
return init_bootmem_core(NODE_DATA(0)->bdata, start, 0, pages);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 30 | 75.00% | 1 | 14.29% |
Linus Torvalds (pre-git) | 5 | 12.50% | 2 | 28.57% |
Yinghai Lu | 2 | 5.00% | 1 | 14.29% |
Franck Bui-Huu | 1 | 2.50% | 1 | 14.29% |
Linus Torvalds | 1 | 2.50% | 1 | 14.29% |
Andrew Morton | 1 | 2.50% | 1 | 14.29% |
Total | 40 | 100.00% | 7 | 100.00% |
/*
* free_bootmem_late - free bootmem pages directly to page allocator
* @addr: starting physical address of the range
* @size: size of the range in bytes
*
* This is only useful when the bootmem allocator has already been torn
* down, but we are still initializing the system. Pages are given directly
* to the page allocator, no bootmem metadata is updated because it is gone.
*/
void __init free_bootmem_late(unsigned long physaddr, unsigned long size)
{
unsigned long cursor, end;
kmemleak_free_part_phys(physaddr, size);
cursor = PFN_UP(physaddr);
end = PFN_DOWN(physaddr + size);
for (; cursor < end; cursor++) {
__free_pages_bootmem(pfn_to_page(cursor), cursor, 0);
totalram_pages++;
}
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
FUJITA Tomonori | 63 | 90.00% | 1 | 25.00% |
JoonSoo Kim | 4 | 5.71% | 1 | 25.00% |
Mel Gorman | 2 | 2.86% | 1 | 25.00% |
Catalin Marinas | 1 | 1.43% | 1 | 25.00% |
Total | 70 | 100.00% | 4 | 100.00% |
static unsigned long __init free_all_bootmem_core(bootmem_data_t *bdata)
{
struct page *page;
unsigned long *map, start, end, pages, cur, count = 0;
if (!bdata->node_bootmem_map)
return 0;
map = bdata->node_bootmem_map;
start = bdata->node_min_pfn;
end = bdata->node_low_pfn;
bdebug("nid=%td start=%lx end=%lx\n",
bdata - bootmem_node_data, start, end);
while (start < end) {
unsigned long idx, vec;
unsigned shift;
idx = start - bdata->node_min_pfn;
shift = idx & (BITS_PER_LONG - 1);
/*
* vec holds at most BITS_PER_LONG map bits,
* bit 0 corresponds to start.
*/
vec = ~map[idx / BITS_PER_LONG];
if (shift) {
vec >>= shift;
if (end - start >= BITS_PER_LONG)
vec |= ~map[idx / BITS_PER_LONG + 1] <<
(BITS_PER_LONG - shift);
}
/*
* If we have a properly aligned and fully unreserved
* BITS_PER_LONG block of pages in front of us, free
* it in one go.
*/
if (IS_ALIGNED(start, BITS_PER_LONG) && vec == ~0UL) {
int order = ilog2(BITS_PER_LONG);
__free_pages_bootmem(pfn_to_page(start), start, order);
count += BITS_PER_LONG;
start += BITS_PER_LONG;
} else {
cur = start;
start = ALIGN(start + 1, BITS_PER_LONG);
while (vec && cur != start) {
if (vec & 1) {
page = pfn_to_page(cur);
__free_pages_bootmem(page, cur, 0);
count++;
}
vec >>= 1;
++cur;
}
}
}
cur = bdata->node_min_pfn;
page = virt_to_page(bdata->node_bootmem_map);
pages = bdata->node_low_pfn - bdata->node_min_pfn;
pages = bootmem_bootmap_pages(pages);
count += pages;
while (pages--)
__free_pages_bootmem(page++, cur++, 0);
bdata->node_bootmem_map = NULL;
bdebug("nid=%td released=%lx\n", bdata - bootmem_node_data, count);
return count;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 169 | 50.30% | 2 | 14.29% |
Max Filippov | 66 | 19.64% | 1 | 7.14% |
Johannes Weiner | 64 | 19.05% | 6 | 42.86% |
Mel Gorman | 17 | 5.06% | 1 | 7.14% |
DaeSeok Youn | 9 | 2.68% | 1 | 7.14% |
Chris Metcalf | 6 | 1.79% | 1 | 7.14% |
Gavin Shan | 3 | 0.89% | 1 | 7.14% |
Linus Torvalds (pre-git) | 2 | 0.60% | 1 | 7.14% |
Total | 336 | 100.00% | 14 | 100.00% |
static int reset_managed_pages_done __initdata;
void reset_node_managed_pages(pg_data_t *pgdat)
{
struct zone *z;
for (z = pgdat->node_zones; z < pgdat->node_zones + MAX_NR_ZONES; z++)
z->managed_pages = 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiang Liu | 39 | 100.00% | 2 | 100.00% |
Total | 39 | 100.00% | 2 | 100.00% |
void __init reset_all_zones_managed_pages(void)
{
struct pglist_data *pgdat;
if (reset_managed_pages_done)
return;
for_each_online_pgdat(pgdat)
reset_node_managed_pages(pgdat);
reset_managed_pages_done = 1;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Jiang Liu | 26 | 83.87% | 1 | 50.00% |
Tang Chen | 5 | 16.13% | 1 | 50.00% |
Total | 31 | 100.00% | 2 | 100.00% |
/**
* free_all_bootmem - release free pages to the buddy allocator
*
* Returns the number of pages actually released.
*/
unsigned long __init free_all_bootmem(void)
{
unsigned long total_pages = 0;
bootmem_data_t *bdata;
reset_all_zones_managed_pages();
list_for_each_entry(bdata, &bdata_list, list)
total_pages += free_all_bootmem_core(bdata);
totalram_pages += total_pages;
return total_pages;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 23 | 52.27% | 1 | 16.67% |
Johannes Weiner | 13 | 29.55% | 1 | 16.67% |
Jiang Liu | 7 | 15.91% | 3 | 50.00% |
Bernhard Walle | 1 | 2.27% | 1 | 16.67% |
Total | 44 | 100.00% | 6 | 100.00% |
static void __init __free(bootmem_data_t *bdata,
unsigned long sidx, unsigned long eidx)
{
unsigned long idx;
bdebug("nid=%td start=%lx end=%lx\n", bdata - bootmem_node_data,
sidx + bdata->node_min_pfn,
eidx + bdata->node_min_pfn);
if (WARN_ON(bdata->node_bootmem_map == NULL))
return;
if (bdata->hint_idx > sidx)
bdata->hint_idx = sidx;
for (idx = sidx; idx < eidx; idx++)
if (!test_and_clear_bit(idx, bdata->node_bootmem_map))
BUG();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 86 | 87.76% | 3 | 75.00% |
Chris Metcalf | 12 | 12.24% | 1 | 25.00% |
Total | 98 | 100.00% | 4 | 100.00% |
static int __init __reserve(bootmem_data_t *bdata, unsigned long sidx,
unsigned long eidx, int flags)
{
unsigned long idx;
int exclusive = flags & BOOTMEM_EXCLUSIVE;
bdebug("nid=%td start=%lx end=%lx flags=%x\n",
bdata - bootmem_node_data,
sidx + bdata->node_min_pfn,
eidx + bdata->node_min_pfn,
flags);
if (WARN_ON(bdata->node_bootmem_map == NULL))
return 0;
for (idx = sidx; idx < eidx; idx++)
if (test_and_set_bit(idx, bdata->node_bootmem_map)) {
if (exclusive) {
__free(bdata, sidx, idx);
return -EBUSY;
}
bdebug("silent double reserve of PFN %lx\n",
idx + bdata->node_min_pfn);
}
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 115 | 89.15% | 2 | 66.67% |
Chris Metcalf | 14 | 10.85% | 1 | 33.33% |
Total | 129 | 100.00% | 3 | 100.00% |
static int __init mark_bootmem_node(bootmem_data_t *bdata,
unsigned long start, unsigned long end,
int reserve, int flags)
{
unsigned long sidx, eidx;
bdebug("nid=%td start=%lx end=%lx reserve=%d flags=%x\n",
bdata - bootmem_node_data, start, end, reserve, flags);
BUG_ON(start < bdata->node_min_pfn);
BUG_ON(end > bdata->node_low_pfn);
sidx = start - bdata->node_min_pfn;
eidx = end - bdata->node_min_pfn;
if (reserve)
return __reserve(bdata, sidx, eidx, flags);
else
__free(bdata, sidx, eidx);
return 0;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 62 | 55.86% | 5 | 41.67% |
Linus Torvalds (pre-git) | 28 | 25.23% | 3 | 25.00% |
Yinghai Lu | 13 | 11.71% | 1 | 8.33% |
Franck Bui-Huu | 5 | 4.50% | 1 | 8.33% |
Andrew Morton | 3 | 2.70% | 2 | 16.67% |
Total | 111 | 100.00% | 12 | 100.00% |
static int __init mark_bootmem(unsigned long start, unsigned long end,
int reserve, int flags)
{
unsigned long pos;
bootmem_data_t *bdata;
pos = start;
list_for_each_entry(bdata, &bdata_list, list) {
int err;
unsigned long max;
if (pos < bdata->node_min_pfn ||
pos >= bdata->node_low_pfn) {
BUG_ON(pos != start);
continue;
}
max = min(bdata->node_low_pfn, end);
err = mark_bootmem_node(bdata, pos, max, reserve, flags);
if (reserve && err) {
mark_bootmem(start, pos, 0, 0);
return err;
}
if (max == end)
return 0;
pos = bdata->node_low_pfn;
}
BUG();
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 109 | 77.86% | 3 | 25.00% |
Yinghai Lu | 10 | 7.14% | 2 | 16.67% |
Linus Torvalds (pre-git) | 9 | 6.43% | 2 | 16.67% |
Franck Bui-Huu | 5 | 3.57% | 1 | 8.33% |
Yasunori Goto | 4 | 2.86% | 1 | 8.33% |
Andrew Morton | 2 | 1.43% | 2 | 16.67% |
Linus Torvalds | 1 | 0.71% | 1 | 8.33% |
Total | 140 | 100.00% | 12 | 100.00% |
/**
* free_bootmem_node - mark a page range as usable
* @pgdat: node the range resides on
* @physaddr: starting address of the range
* @size: size of the range in bytes
*
* Partial pages will be considered reserved and left as they are.
*
* The range must reside completely on the specified node.
*/
void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
unsigned long size)
{
unsigned long start, end;
kmemleak_free_part_phys(physaddr, size);
start = PFN_UP(physaddr);
end = PFN_DOWN(physaddr + size);
mark_bootmem_node(pgdat->bdata, start, end, 0, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 50 | 80.65% | 2 | 28.57% |
Catalin Marinas | 7 | 11.29% | 2 | 28.57% |
Andrew Morton | 2 | 3.23% | 1 | 14.29% |
Yinghai Lu | 2 | 3.23% | 1 | 14.29% |
Linus Torvalds | 1 | 1.61% | 1 | 14.29% |
Total | 62 | 100.00% | 7 | 100.00% |
/**
* free_bootmem - mark a page range as usable
* @addr: starting physical address of the range
* @size: size of the range in bytes
*
* Partial pages will be considered reserved and left as they are.
*
* The range must be contiguous but may span node boundaries.
*/
void __init free_bootmem(unsigned long physaddr, unsigned long size)
{
unsigned long start, end;
kmemleak_free_part_phys(physaddr, size);
start = PFN_UP(physaddr);
end = PFN_DOWN(physaddr + size);
mark_bootmem(start, end, 0, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 40 | 74.07% | 3 | 37.50% |
Catalin Marinas | 6 | 11.11% | 2 | 25.00% |
JoonSoo Kim | 4 | 7.41% | 1 | 12.50% |
Linus Torvalds (pre-git) | 4 | 7.41% | 2 | 25.00% |
Total | 54 | 100.00% | 8 | 100.00% |
/**
* reserve_bootmem_node - mark a page range as reserved
* @pgdat: node the range resides on
* @physaddr: starting address of the range
* @size: size of the range in bytes
* @flags: reservation flags (see linux/bootmem.h)
*
* Partial pages will be reserved.
*
* The range must reside completely on the specified node.
*/
int __init reserve_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
unsigned long size, int flags)
{
unsigned long start, end;
start = PFN_DOWN(physaddr);
end = PFN_UP(physaddr + size);
return mark_bootmem_node(pgdat->bdata, start, end, 1, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 51 | 86.44% | 2 | 33.33% |
Andrew Morton | 4 | 6.78% | 2 | 33.33% |
Linus Torvalds (pre-git) | 3 | 5.08% | 1 | 16.67% |
Yinghai Lu | 1 | 1.69% | 1 | 16.67% |
Total | 59 | 100.00% | 6 | 100.00% |
/**
* reserve_bootmem - mark a page range as reserved
* @addr: starting address of the range
* @size: size of the range in bytes
* @flags: reservation flags (see linux/bootmem.h)
*
* Partial pages will be reserved.
*
* The range must be contiguous but may span node boundaries.
*/
int __init reserve_bootmem(unsigned long addr, unsigned long size,
int flags)
{
unsigned long start, end;
start = PFN_DOWN(addr);
end = PFN_UP(addr + size);
return mark_bootmem(start, end, 1, flags);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 41 | 80.39% | 2 | 28.57% |
Andrew Morton | 6 | 11.76% | 2 | 28.57% |
Linus Torvalds (pre-git) | 3 | 5.88% | 2 | 28.57% |
Linus Torvalds | 1 | 1.96% | 1 | 14.29% |
Total | 51 | 100.00% | 7 | 100.00% |
static unsigned long __init align_idx(struct bootmem_data *bdata,
unsigned long idx, unsigned long step)
{
unsigned long base = bdata->node_min_pfn;
/*
* Align the index with respect to the node start so that the
* combination of both satisfies the requested alignment.
*/
return ALIGN(base + idx, step) - base;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 41 | 97.62% | 1 | 50.00% |
Jan Beulich | 1 | 2.38% | 1 | 50.00% |
Total | 42 | 100.00% | 2 | 100.00% |
static unsigned long __init align_off(struct bootmem_data *bdata,
unsigned long off, unsigned long align)
{
unsigned long base = PFN_PHYS(bdata->node_min_pfn);
/* Same as align_idx for byte offsets */
return ALIGN(base + off, align) - base;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 44 | 97.78% | 1 | 50.00% |
Jan Beulich | 1 | 2.22% | 1 | 50.00% |
Total | 45 | 100.00% | 2 | 100.00% |
static void * __init alloc_bootmem_bdata(struct bootmem_data *bdata,
unsigned long size, unsigned long align,
unsigned long goal, unsigned long limit)
{
unsigned long fallback = 0;
unsigned long min, max, start, sidx, midx, step;
bdebug("nid=%td size=%lx [%lu pages] align=%lx goal=%lx limit=%lx\n",
bdata - bootmem_node_data, size, PAGE_ALIGN(size) >> PAGE_SHIFT,
align, goal, limit);
BUG_ON(!size);
BUG_ON(align & (align - 1));
BUG_ON(limit && goal + size > limit);
if (!bdata->node_bootmem_map)
return NULL;
min = bdata->node_min_pfn;
max = bdata->node_low_pfn;
goal >>= PAGE_SHIFT;
limit >>= PAGE_SHIFT;
if (limit && max > limit)
max = limit;
if (max <= min)
return NULL;
step = max(align >> PAGE_SHIFT, 1UL);
if (goal && min < goal && goal < max)
start = ALIGN(goal, step);
else
start = ALIGN(min, step);
sidx = start - bdata->node_min_pfn;
midx = max - bdata->node_min_pfn;
if (bdata->hint_idx > sidx) {
/*
* Handle the valid case of sidx being zero and still
* catch the fallback below.
*/
fallback = sidx + 1;
sidx = align_idx(bdata, bdata->hint_idx, step);
}
while (1) {
int merge;
void *region;
unsigned long eidx, i, start_off, end_off;
find_block:
sidx = find_next_zero_bit(bdata->node_bootmem_map, midx, sidx);
sidx = align_idx(bdata, sidx, step);
eidx = sidx + PFN_UP(size);
if (sidx >= midx || eidx > midx)
break;
for (i = sidx; i < eidx; i++)
if (test_bit(i, bdata->node_bootmem_map)) {
sidx = align_idx(bdata, i, step);
if (sidx == i)
sidx += step;
goto find_block;
}
if (bdata->last_end_off & (PAGE_SIZE - 1) &&
PFN_DOWN(bdata->last_end_off) + 1 == sidx)
start_off = align_off(bdata, bdata->last_end_off, align);
else
start_off = PFN_PHYS(sidx);
merge = PFN_DOWN(start_off) < sidx;
end_off = start_off + size;
bdata->last_end_off = end_off;
bdata->hint_idx = PFN_UP(end_off);
/*
* Reserve the area now:
*/
if (__reserve(bdata, PFN_DOWN(start_off) + merge,
PFN_UP(end_off), BOOTMEM_EXCLUSIVE))
BUG();
region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) +
start_off);
memset(region, 0, size);
/*
* The min_count is set to 0 so that bootmem allocated blocks
* are never reported as leaks.
*/
kmemleak_alloc(region, size, 0, 0);
return region;
}
if (fallback) {
sidx = align_idx(bdata, fallback - 1, step);
fallback = 0;
goto find_block;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 419 | 79.81% | 9 | 36.00% |
Linus Torvalds (pre-git) | 52 | 9.90% | 3 | 12.00% |
Yinghai Lu | 14 | 2.67% | 3 | 12.00% |
Catalin Marinas | 12 | 2.29% | 2 | 8.00% |
Andi Kleen | 8 | 1.52% | 1 | 4.00% |
Mikulas Patocka | 6 | 1.14% | 1 | 4.00% |
Josh Aas | 5 | 0.95% | 1 | 4.00% |
Andy Whitcroft | 3 | 0.57% | 1 | 4.00% |
Linus Torvalds | 2 | 0.38% | 1 | 4.00% |
Andrew Morton | 2 | 0.38% | 1 | 4.00% |
Nick Wilson | 1 | 0.19% | 1 | 4.00% |
Franck Bui-Huu | 1 | 0.19% | 1 | 4.00% |
Total | 525 | 100.00% | 25 | 100.00% |
static void * __init alloc_bootmem_core(unsigned long size,
unsigned long align,
unsigned long goal,
unsigned long limit)
{
bootmem_data_t *bdata;
void *region;
if (WARN_ON_ONCE(slab_is_available()))
return kzalloc(size, GFP_NOWAIT);
list_for_each_entry(bdata, &bdata_list, list) {
if (goal && bdata->node_low_pfn <= PFN_DOWN(goal))
continue;
if (limit && bdata->node_min_pfn >= PFN_DOWN(limit))
break;
region = alloc_bootmem_bdata(bdata, size, align, goal, limit);
if (region)
return region;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 37 | 33.33% | 4 | 30.77% |
Tejun Heo | 22 | 19.82% | 1 | 7.69% |
Pekka J Enberg | 16 | 14.41% | 1 | 7.69% |
Linus Torvalds (pre-git) | 13 | 11.71% | 2 | 15.38% |
JoonSoo Kim | 9 | 8.11% | 1 | 7.69% |
Kamezawa Hiroyuki | 6 | 5.41% | 1 | 7.69% |
Franck Bui-Huu | 5 | 4.50% | 1 | 7.69% |
Andrew Morton | 2 | 1.80% | 1 | 7.69% |
Yasunori Goto | 1 | 0.90% | 1 | 7.69% |
Total | 111 | 100.00% | 13 | 100.00% |
static void * __init ___alloc_bootmem_nopanic(unsigned long size,
unsigned long align,
unsigned long goal,
unsigned long limit)
{
void *ptr;
restart:
ptr = alloc_bootmem_core(size, align, goal, limit);
if (ptr)
return ptr;
if (goal) {
goal = 0;
goto restart;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 62 | 93.94% | 2 | 66.67% |
Andi Kleen | 4 | 6.06% | 1 | 33.33% |
Total | 66 | 100.00% | 3 | 100.00% |
/**
* __alloc_bootmem_nopanic - allocate boot memory without panicking
* @size: size of the request in bytes
* @align: alignment of the region
* @goal: preferred starting address of the region
*
* The goal is dropped if it can not be satisfied and the allocation will
* fall back to memory below @goal.
*
* Allocation may happen on any node in the system.
*
* Returns NULL on failure.
*/
void * __init __alloc_bootmem_nopanic(unsigned long size, unsigned long align,
unsigned long goal)
{
unsigned long limit = 0;
return ___alloc_bootmem_nopanic(size, align, goal, limit);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Andi Kleen | 17 | 45.95% | 1 | 33.33% |
Johannes Weiner | 13 | 35.14% | 1 | 33.33% |
Yinghai Lu | 7 | 18.92% | 1 | 33.33% |
Total | 37 | 100.00% | 3 | 100.00% |
static void * __init ___alloc_bootmem(unsigned long size, unsigned long align,
unsigned long goal, unsigned long limit)
{
void *mem = ___alloc_bootmem_nopanic(size, align, goal, limit);
if (mem)
return mem;
/*
* Whoops, we cannot satisfy the allocation request.
*/
pr_alert("bootmem alloc of %lu bytes failed!\n", size);
panic("Out of memory");
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 26 | 41.94% | 1 | 16.67% |
Andi Kleen | 19 | 30.65% | 1 | 16.67% |
Linus Torvalds | 10 | 16.13% | 1 | 16.67% |
Linus Torvalds (pre-git) | 6 | 9.68% | 2 | 33.33% |
Joe Perches | 1 | 1.61% | 1 | 16.67% |
Total | 62 | 100.00% | 6 | 100.00% |
/**
* __alloc_bootmem - allocate boot memory
* @size: size of the request in bytes
* @align: alignment of the region
* @goal: preferred starting address of the region
*
* The goal is dropped if it can not be satisfied and the allocation will
* fall back to memory below @goal.
*
* Allocation may happen on any node in the system.
*
* The function panics if the request can not be satisfied.
*/
void * __init __alloc_bootmem(unsigned long size, unsigned long align,
unsigned long goal)
{
unsigned long limit = 0;
return ___alloc_bootmem(size, align, goal, limit);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 30 | 81.08% | 1 | 50.00% |
Yinghai Lu | 7 | 18.92% | 1 | 50.00% |
Total | 37 | 100.00% | 2 | 100.00% |
void * __init ___alloc_bootmem_node_nopanic(pg_data_t *pgdat,
unsigned long size, unsigned long align,
unsigned long goal, unsigned long limit)
{
void *ptr;
if (WARN_ON_ONCE(slab_is_available()))
return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
again:
/* do not panic in alloc_bootmem_bdata() */
if (limit && goal + size > limit)
limit = 0;
ptr = alloc_bootmem_bdata(pgdat->bdata, size, align, goal, limit);
if (ptr)
return ptr;
ptr = alloc_bootmem_core(size, align, goal, limit);
if (ptr)
return ptr;
if (goal) {
goal = 0;
goto again;
}
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 72 | 56.25% | 2 | 20.00% |
Johannes Weiner | 34 | 26.56% | 4 | 40.00% |
JoonSoo Kim | 12 | 9.38% | 1 | 10.00% |
zijun_hu | 5 | 3.91% | 1 | 10.00% |
Linus Torvalds (pre-git) | 5 | 3.91% | 2 | 20.00% |
Total | 128 | 100.00% | 10 | 100.00% |
void * __init __alloc_bootmem_node_nopanic(pg_data_t *pgdat, unsigned long size,
unsigned long align, unsigned long goal)
{
return ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 37 | 100.00% | 1 | 100.00% |
Total | 37 | 100.00% | 1 | 100.00% |
void * __init ___alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
unsigned long align, unsigned long goal,
unsigned long limit)
{
void *ptr;
ptr = ___alloc_bootmem_node_nopanic(pgdat, size, align, goal, 0);
if (ptr)
return ptr;
pr_alert("bootmem alloc of %lu bytes failed!\n", size);
panic("Out of memory");
return NULL;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 65 | 95.59% | 3 | 60.00% |
Yinghai Lu | 2 | 2.94% | 1 | 20.00% |
Joe Perches | 1 | 1.47% | 1 | 20.00% |
Total | 68 | 100.00% | 5 | 100.00% |
/**
* __alloc_bootmem_node - allocate boot memory from a specific node
* @pgdat: node to allocate from
* @size: size of the request in bytes
* @align: alignment of the region
* @goal: preferred starting address of the region
*
* The goal is dropped if it can not be satisfied and the allocation will
* fall back to memory below @goal.
*
* Allocation may fall back to any node in the system if the specified node
* can not hold the requested memory.
*
* The function panics if the request can not be satisfied.
*/
void * __init __alloc_bootmem_node(pg_data_t *pgdat, unsigned long size,
unsigned long align, unsigned long goal)
{
if (WARN_ON_ONCE(slab_is_available()))
return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
return ___alloc_bootmem_node(pgdat, size, align, goal, 0);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 28 | 49.12% | 2 | 28.57% |
Linus Torvalds (pre-git) | 14 | 24.56% | 1 | 14.29% |
Tejun Heo | 6 | 10.53% | 1 | 14.29% |
Anton Blanchard | 4 | 7.02% | 1 | 14.29% |
Johannes Weiner | 3 | 5.26% | 1 | 14.29% |
Linus Torvalds | 2 | 3.51% | 1 | 14.29% |
Total | 57 | 100.00% | 7 | 100.00% |
void * __init __alloc_bootmem_node_high(pg_data_t *pgdat, unsigned long size,
unsigned long align, unsigned long goal)
{
#ifdef MAX_DMA32_PFN
unsigned long end_pfn;
if (WARN_ON_ONCE(slab_is_available()))
return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
/* update goal according ...MAX_DMA32_PFN */
end_pfn = pgdat_end_pfn(pgdat);
if (end_pfn > MAX_DMA32_PFN + (128 >> (20 - PAGE_SHIFT)) &&
(goal >> PAGE_SHIFT) < MAX_DMA32_PFN) {
void *ptr;
unsigned long new_goal;
new_goal = MAX_DMA32_PFN << PAGE_SHIFT;
ptr = alloc_bootmem_bdata(pgdat->bdata, size, align,
new_goal, 0);
if (ptr)
return ptr;
}
#endif
return __alloc_bootmem_node(pgdat, size, align, goal);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 77 | 56.62% | 1 | 16.67% |
Johannes Weiner | 33 | 24.26% | 2 | 33.33% |
Pekka J Enberg | 20 | 14.71% | 1 | 16.67% |
Xishi Qiu | 3 | 2.21% | 1 | 16.67% |
Ravikiran G. Thirumalai | 3 | 2.21% | 1 | 16.67% |
Total | 136 | 100.00% | 6 | 100.00% |
/**
* __alloc_bootmem_low - allocate low boot memory
* @size: size of the request in bytes
* @align: alignment of the region
* @goal: preferred starting address of the region
*
* The goal is dropped if it can not be satisfied and the allocation will
* fall back to memory below @goal.
*
* Allocation may happen on any node in the system.
*
* The function panics if the request can not be satisfied.
*/
void * __init __alloc_bootmem_low(unsigned long size, unsigned long align,
unsigned long goal)
{
return ___alloc_bootmem(size, align, goal, ARCH_LOW_ADDRESS_LIMIT);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ravikiran G. Thirumalai | 28 | 90.32% | 1 | 33.33% |
Johannes Weiner | 2 | 6.45% | 1 | 33.33% |
Heiko Carstens | 1 | 3.23% | 1 | 33.33% |
Total | 31 | 100.00% | 3 | 100.00% |
void * __init __alloc_bootmem_low_nopanic(unsigned long size,
unsigned long align,
unsigned long goal)
{
return ___alloc_bootmem_nopanic(size, align, goal,
ARCH_LOW_ADDRESS_LIMIT);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Yinghai Lu | 31 | 100.00% | 1 | 100.00% |
Total | 31 | 100.00% | 1 | 100.00% |
/**
* __alloc_bootmem_low_node - allocate low boot memory from a specific node
* @pgdat: node to allocate from
* @size: size of the request in bytes
* @align: alignment of the region
* @goal: preferred starting address of the region
*
* The goal is dropped if it can not be satisfied and the allocation will
* fall back to memory below @goal.
*
* Allocation may fall back to any node in the system if the specified node
* can not hold the requested memory.
*
* The function panics if the request can not be satisfied.
*/
void * __init __alloc_bootmem_low_node(pg_data_t *pgdat, unsigned long size,
unsigned long align, unsigned long goal)
{
if (WARN_ON_ONCE(slab_is_available()))
return kzalloc_node(size, GFP_NOWAIT, pgdat->node_id);
return ___alloc_bootmem_node(pgdat, size, align,
goal, ARCH_LOW_ADDRESS_LIMIT);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ravikiran G. Thirumalai | 31 | 54.39% | 1 | 14.29% |
Pekka J Enberg | 20 | 35.09% | 1 | 14.29% |
Yinghai Lu | 2 | 3.51% | 1 | 14.29% |
Linus Torvalds (pre-git) | 1 | 1.75% | 1 | 14.29% |
Heiko Carstens | 1 | 1.75% | 1 | 14.29% |
Johannes Weiner | 1 | 1.75% | 1 | 14.29% |
Linus Torvalds | 1 | 1.75% | 1 | 14.29% |
Total | 57 | 100.00% | 7 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Johannes Weiner | 1671 | 52.98% | 23 | 22.55% |
Yinghai Lu | 490 | 15.54% | 10 | 9.80% |
Linus Torvalds (pre-git) | 221 | 7.01% | 9 | 8.82% |
Jiang Liu | 77 | 2.44% | 3 | 2.94% |
Max Filippov | 66 | 2.09% | 1 | 0.98% |
FUJITA Tomonori | 63 | 2.00% | 1 | 0.98% |
Ravikiran G. Thirumalai | 62 | 1.97% | 1 | 0.98% |
Pekka J Enberg | 56 | 1.78% | 2 | 1.96% |
Franck Bui-Huu | 55 | 1.74% | 3 | 2.94% |
Andi Kleen | 48 | 1.52% | 2 | 1.96% |
Kamezawa Hiroyuki | 44 | 1.40% | 1 | 0.98% |
Chris Metcalf | 32 | 1.01% | 1 | 0.98% |
Tejun Heo | 31 | 0.98% | 2 | 1.96% |
JoonSoo Kim | 31 | 0.98% | 2 | 1.96% |
Catalin Marinas | 29 | 0.92% | 3 | 2.94% |
Mel Gorman | 28 | 0.89% | 2 | 1.96% |
Gavin Shan | 26 | 0.82% | 2 | 1.96% |
Linus Torvalds | 23 | 0.73% | 6 | 5.88% |
Andrew Morton | 22 | 0.70% | 5 | 4.90% |
DaeSeok Youn | 9 | 0.29% | 1 | 0.98% |
zijun_hu | 6 | 0.19% | 1 | 0.98% |
Mikulas Patocka | 6 | 0.19% | 1 | 0.98% |
Igor Mammedov | 5 | 0.16% | 1 | 0.98% |
Yasunori Goto | 5 | 0.16% | 1 | 0.98% |
Josh Aas | 5 | 0.16% | 1 | 0.98% |
Tang Chen | 5 | 0.16% | 1 | 0.98% |
Anton Blanchard | 4 | 0.13% | 1 | 0.98% |
Uwe Kleine-König | 4 | 0.13% | 1 | 0.98% |
Heiko Carstens | 4 | 0.13% | 1 | 0.98% |
Andy Whitcroft | 3 | 0.10% | 1 | 0.98% |
Xishi Qiu | 3 | 0.10% | 1 | 0.98% |
David Howells | 3 | 0.10% | 1 | 0.98% |
Joe Perches | 3 | 0.10% | 1 | 0.98% |
Johan Adolfsson | 2 | 0.06% | 1 | 0.98% |
Jan Beulich | 2 | 0.06% | 1 | 0.98% |
Bernhard Walle | 2 | 0.06% | 1 | 0.98% |
Paul McQuade | 2 | 0.06% | 1 | 0.98% |
James Bottomley | 2 | 0.06% | 1 | 0.98% |
Javi Merino | 1 | 0.03% | 1 | 0.98% |
Nick Wilson | 1 | 0.03% | 1 | 0.98% |
Paul Gortmaker | 1 | 0.03% | 1 | 0.98% |
Adygzhy Ondar | 1 | 0.03% | 1 | 0.98% |
Total | 3154 | 100.00% | 102 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.