Linux カーネル モジュールとして独自のメモリ プールを構築しています。ユーザー レベルのプロセスがメモリ プールからページ フレームを取得するように、ページ フレーム割り当て関数を変更しました。これはうまくいきます。次に、プロセスによってページ フレームが解放されたときにページ フレームを再利用するために、ページ解放関数を変更しようとしました。しかし、ページの再利用を有効にすると、コンソールに「セグメンテーション違反」メッセージが表示されて、プログラムを起動できませんでした。
alloc_page(__GFP_HIGHMEM | __GFP_MOVABLE | __GFP_ZERO)
CPU ごとのページ フレーム キャッシュに入るメモリ プールを作成するために使用しているため、取得するすべてのページの使用カウンター (page->_count) が 1 に設定されます。
ページを解放するために、いくつかの行を に挿入しましたfree_pcppages_bulk()
。これは、CPU ごとのページ フレーム キャッシュがいくつかの空きページを Buddy システムにフラッシュするときに呼び出されます。
static void free_pcppages_bulk(struct zone *zone, int count,
struct per_cpu_pages *pcp)
{
int migratetype = 0;
int batch_free = 0;
int to_free = count;
spin_lock(&zone->lock);
zone_clear_flag(zone, ZONE_ALL_UNRECLAIMABLE);
zone->pages_scanned = 0;
while (to_free) {
struct page *page;
struct list_head *list;
/*
* Remove pages from lists in a round-robin fashion. A
* batch_free count is maintained that is incremented when an
* empty list is encountered. This is so more pages are freed
* off fuller lists instead of spinning excessively around empty
* lists
*/
do {
batch_free++;
if (++migratetype == MIGRATE_PCPTYPES)
migratetype = 0;
list = &pcp->lists[migratetype];
} while (list_empty(list));
do {
page = list_entry(list->prev, struct page, lru);
/* must delete as __free_one_page list manipulates */
list_del(&page->lru);
/* MIGRATE_MOVABLE list may include MIGRATE_RESERVEs */
/* --ADDED BY ME-- */
if(colored_free != NULL) { /* if my memory pool is created */
if(!colored_free(page, zone)) { /* if it fails, free page to Buddy system */
__free_one_page(page, zone, 0, page_private(page));
}
}
else {
__free_one_page(page, zone, 0, page_private(page));
}
trace_mm_page_pcpu_drain(page, 0, page_private(page));
} while (--to_free && --batch_free && !list_empty(list));
}
__mod_zone_page_state(zone, NR_FREE_PAGES, count);
spin_unlock(&zone->lock);
}
ではcolored_free()
、ページの空きリストにページ記述子を挿入するだけです。ページ使用カウンターは、バディ システムに解放されるときに 0 に設定されるため、メモリ プールが作成されたときに最初のページ状態を復元するために 1 にリセットします。
これに関する提案はありますか?または、バディ システムの代わりにメモリ プールにページ フレームを解放するより良い方法はありますか?