2

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 にリセットします。

これに関する提案はありますか?または、バディ システムの代わりにメモリ プールにページ フレームを解放するより良い方法はありますか?

4

0 に答える 0