boot memory allocator――ブートメモリ分配器(四:メモリリリース)
bootmemの段階で,カーネルはfree_を提供した.ブックマーク関数はメモリを解放します.二つのパラメータが必要です.メモリ領域の開始アドレスと長さが必要です.予期せぬことで、NUMAシステム上の等価関数の名称はfree_である.bootmem_node、結点を指定するために追加のパラメータが必要です.
void __init free_bootmem(unsigned long addr, unsigned long size)
{
free_bootmem_core(NODE_DATA(0)->bdata, addr, size);
}
void __init free_bootmem_node(pg_data_t *pgdat, unsigned long physaddr,
unsigned long size)
{
free_bootmem_core(pgdat->bdata, physaddr, size);
}
二つのバージョンはいずれも仕事を_に任せています.free_bootmem_coreは、全体のページをリリースすることができます.bootmem分配器はページの区分に関する情報を保存していません.カーネル使用free_bootmem_coreは、まず、メモリ領域に完全に含まれる、リリースされるページを計算する.メモリ領域に一部含まれるページだけが無視されます.ビットマップの対応する項目を0に設定し、ページのリリースを完了します.対ひfree_bootmem_coreの分析は以下の通りである.static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,unsigned long size)
{
unsigned long sidx, eidx;
unsigned long i;
/*
* round down end of usable mem, partially free pages are
* considered reserved.
*/
BUG_ON(!size);// ,
BUG_ON(PFN_DOWN(addr + size) > bdata->node_low_pfn);// ,
if (addr < bdata->last_success)
bdata->last_success = addr;// addr<bdata->last_success, ,
/*
* Round up the beginning of the address.
*/
sidx = PFN_UP(addr) - PFN_DOWN(bdata->node_boot_start);// PFN_UP(addr) , addr 0~4kb , 0 , , 1 。 ? , , node , PFN_DOWN(bdata->node_boot_start) PFN_UP(bdata->node_boot_start), PFN_UP(bdata->node_boot_start) , 。 。
eidx = PFN_DOWN(addr + size - bdata->node_boot_start);//
for (i = sidx; i < eidx; i++) {//
if (unlikely(!test_and_clear_bit(i, bdata->node_bootmem_map)))// 0 ,
BUG();
}
}
このプロセスはいくつかのリスクを隠しています.もし2つの異なるメモリエリアにも含まれているなら、これらのメモリエリアを連続的にリリースしても、ページを解放できません.ページの前半と後半を含むメモリエリアは、一定時間間隔でそれぞれ解放されます.このページがもう使われていないかどうかは、分配器には分かりませんので、リリースできません.このページの状態はそのまま「使用中」です.それでも、free auでbootmemはあまり使われていません.これも大きな問題ではありません.システム初期化時に割り当てられたほとんどのメモリ領域は基本的なデータ構造に使用され、カーネルで動作するすべての時間は使用されるので、リリースする必要はない.