linux-4.4.1/alloc_contig_range()
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
*参照元 [#o2045ad6]
#backlinks
*説明 [#hb157032]
-パス: [[linux-4.4.1/mm/page_alloc.c]]
-FIXME: これは何?
--説明
**引数 [#u89957b1]
-unsigned long start
--
-unsigned long end
--
-unsigned migratetype
--
**返り値 [#hce649ef]
-int
--
**参考 [#i5d2b328]
*実装 [#c3dd730c]
/**
* alloc_contig_range() -- tries to allocate given range...
* @start: start PFN to allocate
* @end: one-past-the-last PFN to allocate
* @migratetype: migratetype of the underlaying p...
* #MIGRATE_MOVABLE or #MIGRATE_CMA...
* in range must have the same migr...
* be either of the two.
*
* The PFN range does not have to be pageblock or MAX_OR...
* aligned, however it's the caller's responsibility to ...
* we are the only thread that changes migrate type of p...
* pages fall in.
*
* The PFN range must belong to a single zone.
*
* Returns zero on success or negative error code. On s...
* pages which PFN is in [start, end) are allocated for ...
* need to be freed with free_contig_range().
*/
int alloc_contig_range(unsigned long start, unsigned lon...
unsigned migratetype)
{
unsigned long outer_start, outer_end;
unsigned int order;
int ret = 0;
struct compact_control cc = {
.nr_migratepages = 0,
.order = -1,
.zone = page_zone(pfn_to_page(start)),
.mode = MIGRATE_SYNC,
.ignore_skip_hint = true,
};
INIT_LIST_HEAD(&cc.migratepages);
-
--[[linux-4.4.1/compact_control]]
--[[linux-4.4.1/page_zone()]]
--[[linux-4.4.1/pfn_to_page()]]
--[[linux-4.4.1/INIT_LIST_HEAD()]]
/*
* What we do here is we mark all pageblocks in ...
* MIGRATE_ISOLATE. Because pageblock and max o...
* have different sizes, and due to the way page...
* work, we align the range to biggest of the tw...
* that page allocator won't try to merge buddie...
* different pageblocks and change MIGRATE_ISOLA...
* other migration type.
*
* Once the pageblocks are marked as MIGRATE_ISO...
* migrate the pages from an unaligned range (ie...
* we are interested in). This will put all the...
* range back to page allocator as MIGRATE_ISOLA...
*
* When this is done, we take the pages in range...
* allocator removing them from the buddy system...
* page allocator will never consider using them.
*
* This lets us mark the pageblocks back as
* MIGRATE_CMA/MIGRATE_MOVABLE so that free page...
* aligned range but not in the unaligned, origi...
* put back to page allocator so that buddy can ...
*/
ret = start_isolate_page_range(pfn_max_align_dow...
pfn_max_align_up(...
false);
if (ret)
return ret;
-
--[[linux-4.4.1/start_isolate_page_range()]]
--[[linux-4.4.1/pfn_max_align_down()]]
--[[linux-4.4.1/pfn_max_align_up()]]
ret = __alloc_contig_migrate_range(&cc, start, e...
if (ret)
goto done;
-
--[[linux-4.4.1/__alloc_contig_migrate_range()]]
/*
* Pages from [start, end) are within a MAX_ORDE...
* aligned blocks that are marked as MIGRATE_ISO...
* more, all pages in [start, end) are free in p...
* What we are going to do is to allocate all pa...
* [start, end) (that is remove them from page a...
*
* The only problem is that pages at the beginni...
* end of interesting range may be not aligned w...
* page allocator holds, ie. they can be part of...
* pages. Because of this, we reserve the bigge...
* once this is done free the pages we are not i...
*
* We don't have to hold zone->lock here because...
* isolated thus they won't get removed from bud...
*/
lru_add_drain_all();
drain_all_pages(cc.zone);
-
--[[linux-4.4.1/lru_add_drain_all()]]
--[[linux-4.4.1/drain_all_pages()]]
order = 0;
outer_start = start;
while (!PageBuddy(pfn_to_page(outer_start))) {
if (++order >= MAX_ORDER) {
ret = -EBUSY;
goto done;
}
outer_start &= ~0UL << order;
}
-
--[[linux-4.4.1/PageBuddy()]]
/* Make sure the range is really isolated. */
if (test_pages_isolated(outer_start, end, false)...
pr_info("%s: [%lx, %lx) PFNs busy\n",
__func__, outer_start, end);
ret = -EBUSY;
goto done;
}
-
--[[linux-4.4.1/test_pages_isolated()]]
/* Grab isolated pages from freelists. */
outer_end = isolate_freepages_range(&cc, outer_s...
if (!outer_end) {
ret = -EBUSY;
goto done;
}
-
--[[linux-4.4.1/isolate_freepages_range()]]
/* Free head and tail (if any) */
if (start != outer_start)
free_contig_range(outer_start, start - o...
if (end != outer_end)
free_contig_range(end, outer_end - end);
-
--[[linux-4.4.1/free_contig_range()]]
done:
undo_isolate_page_range(pfn_max_align_down(start),
pfn_max_align_up(end), m...
-
--[[linux-4.4.1/undo_isolate_page_range()]]
return ret;
}
*コメント [#a2b5fb0a]
終了行:
*参照元 [#o2045ad6]
#backlinks
*説明 [#hb157032]
-パス: [[linux-4.4.1/mm/page_alloc.c]]
-FIXME: これは何?
--説明
**引数 [#u89957b1]
-unsigned long start
--
-unsigned long end
--
-unsigned migratetype
--
**返り値 [#hce649ef]
-int
--
**参考 [#i5d2b328]
*実装 [#c3dd730c]
/**
* alloc_contig_range() -- tries to allocate given range...
* @start: start PFN to allocate
* @end: one-past-the-last PFN to allocate
* @migratetype: migratetype of the underlaying p...
* #MIGRATE_MOVABLE or #MIGRATE_CMA...
* in range must have the same migr...
* be either of the two.
*
* The PFN range does not have to be pageblock or MAX_OR...
* aligned, however it's the caller's responsibility to ...
* we are the only thread that changes migrate type of p...
* pages fall in.
*
* The PFN range must belong to a single zone.
*
* Returns zero on success or negative error code. On s...
* pages which PFN is in [start, end) are allocated for ...
* need to be freed with free_contig_range().
*/
int alloc_contig_range(unsigned long start, unsigned lon...
unsigned migratetype)
{
unsigned long outer_start, outer_end;
unsigned int order;
int ret = 0;
struct compact_control cc = {
.nr_migratepages = 0,
.order = -1,
.zone = page_zone(pfn_to_page(start)),
.mode = MIGRATE_SYNC,
.ignore_skip_hint = true,
};
INIT_LIST_HEAD(&cc.migratepages);
-
--[[linux-4.4.1/compact_control]]
--[[linux-4.4.1/page_zone()]]
--[[linux-4.4.1/pfn_to_page()]]
--[[linux-4.4.1/INIT_LIST_HEAD()]]
/*
* What we do here is we mark all pageblocks in ...
* MIGRATE_ISOLATE. Because pageblock and max o...
* have different sizes, and due to the way page...
* work, we align the range to biggest of the tw...
* that page allocator won't try to merge buddie...
* different pageblocks and change MIGRATE_ISOLA...
* other migration type.
*
* Once the pageblocks are marked as MIGRATE_ISO...
* migrate the pages from an unaligned range (ie...
* we are interested in). This will put all the...
* range back to page allocator as MIGRATE_ISOLA...
*
* When this is done, we take the pages in range...
* allocator removing them from the buddy system...
* page allocator will never consider using them.
*
* This lets us mark the pageblocks back as
* MIGRATE_CMA/MIGRATE_MOVABLE so that free page...
* aligned range but not in the unaligned, origi...
* put back to page allocator so that buddy can ...
*/
ret = start_isolate_page_range(pfn_max_align_dow...
pfn_max_align_up(...
false);
if (ret)
return ret;
-
--[[linux-4.4.1/start_isolate_page_range()]]
--[[linux-4.4.1/pfn_max_align_down()]]
--[[linux-4.4.1/pfn_max_align_up()]]
ret = __alloc_contig_migrate_range(&cc, start, e...
if (ret)
goto done;
-
--[[linux-4.4.1/__alloc_contig_migrate_range()]]
/*
* Pages from [start, end) are within a MAX_ORDE...
* aligned blocks that are marked as MIGRATE_ISO...
* more, all pages in [start, end) are free in p...
* What we are going to do is to allocate all pa...
* [start, end) (that is remove them from page a...
*
* The only problem is that pages at the beginni...
* end of interesting range may be not aligned w...
* page allocator holds, ie. they can be part of...
* pages. Because of this, we reserve the bigge...
* once this is done free the pages we are not i...
*
* We don't have to hold zone->lock here because...
* isolated thus they won't get removed from bud...
*/
lru_add_drain_all();
drain_all_pages(cc.zone);
-
--[[linux-4.4.1/lru_add_drain_all()]]
--[[linux-4.4.1/drain_all_pages()]]
order = 0;
outer_start = start;
while (!PageBuddy(pfn_to_page(outer_start))) {
if (++order >= MAX_ORDER) {
ret = -EBUSY;
goto done;
}
outer_start &= ~0UL << order;
}
-
--[[linux-4.4.1/PageBuddy()]]
/* Make sure the range is really isolated. */
if (test_pages_isolated(outer_start, end, false)...
pr_info("%s: [%lx, %lx) PFNs busy\n",
__func__, outer_start, end);
ret = -EBUSY;
goto done;
}
-
--[[linux-4.4.1/test_pages_isolated()]]
/* Grab isolated pages from freelists. */
outer_end = isolate_freepages_range(&cc, outer_s...
if (!outer_end) {
ret = -EBUSY;
goto done;
}
-
--[[linux-4.4.1/isolate_freepages_range()]]
/* Free head and tail (if any) */
if (start != outer_start)
free_contig_range(outer_start, start - o...
if (end != outer_end)
free_contig_range(end, outer_end - end);
-
--[[linux-4.4.1/free_contig_range()]]
done:
undo_isolate_page_range(pfn_max_align_down(start),
pfn_max_align_up(end), m...
-
--[[linux-4.4.1/undo_isolate_page_range()]]
return ret;
}
*コメント [#a2b5fb0a]
ページ名: