内存管理之bootmem管理之对外分配函数
2017-03-06 10:09
316 查看
alloc_bootmem_bdata和alloc_bootmem_core
基于node和不需要node两个类别的函数
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; }
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; }
相关文章推荐
- 内存管理之bootmem管理之释放所有bootmem内存
- 内存管理之bootmem管理之标记内存为reserve
- 内存管理之bootmem管理之释放内存
- 内存管理之bootmem管理之标记内存
- 内存管理之bootmem管理之__free_pages_boot_core
- 内存管理之bootmem管理之free_all_bootmem
- linux 内存管理之bootmem allocator
- linux 内存管理之bootmem allocator
- linux 内核 内存管理 bootmem alloctor 申请内存
- 启动期间的内存管理之bootmem_init初始化内存管理--Linux内存管理(十二)
- 内存管理(上):基本内存管理
- 三读bootmem
- Spring Boot Admin管理监控数据的方法
- Spring Boot shiro 权限管理 小例子
- OC加强知识点笔记-内存管理,@class,NSString 内存管理
- spring boot+mvc+mybatis(通用mapper)+druid+jsp+bootstrap实现后台权限管理系统源码
- 【SpringBoot探索四】SpringBoot项目集成Swagger2管理接口文档
- 操作系统内存管理——分区、页式、段式管理、段页式
- Spring Boot Admin 更换应用管理端口后在Environment中配置参数
- SpringBoot Beans管理和自动配置 火推 02