Generic multi-page exclusion
Subsystems (2)
cover Generic multi-page exclusion
Kumagai-san,
this patch was inspired by this post of yours:
http://lists.infradead.org/pipermail/kexec/2013-November/010445.html
Unfortunately, this rewrite never happened, so I took the liberty of overtaking the job. I hope you don't mind.
This is in fact a preparatory series to add hugepage support without having to care about the appropriate size of the cyclic buffer.
Petr Tesarik (2):
Generic handling of multi-page exclusions
Git rid of overrun adjustments
makedumpfile.c | 92 +++++++++++----------------------------------------------- makedumpfile.h | 7 +++++ 2 files changed, 24 insertions(+), 75 deletions(-)
Signature · 7 lines
1.8.4.5 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH 1/2 Generic handling of multi-page exclusions
When multiple pages are excluded from the dump, store the extents in the DumpInfo structure and filter them in the normal loop. By doing it this way, there is no need to process the whole region in the same cycle.
I chose to store the start and end PFN, rather than just the number of pages, because this algorithm is more robust in case the memory map does not cover the full range.
--- makedumpfile.c | 33 +++++++++++++++++---------------- makedumpfile.h | 7 +++++++ 2 files changed, 24 insertions(+), 16 deletions(-)
makedumpfile.c +17 -16
@@ -4683,6 +4683,16 @@ __exclude_unnecessary_pages(unsigned long mem_map,continue ;/* +* If this is part of a multi-page exclusion, exclude this pfn. +*/ +if (info->exclude_pfn_start <= pfn && pfn < info->exclude_pfn_end) { +if (clear_bit_on_2nd_bitmap_for_kernel (pfn, cycle)) + (*info->exclude_pfn_counter)++; + info->exclude_pfn_start = pfn +1 ; +continue ; + } + +/* * Exclude the memory hole. */ if (is_xen_memory ()) {
@@ -4732,23 +4742,14 @@ __exclude_unnecessary_pages(unsigned long mem_map,if ((info->dump_level &DL_EXCLUDE_FREE ) && info->page_is_buddy && info->page_is_buddy (flags, _mapcount, private, _count)) { -int i, nr_pages =1 << private; +int nr_pages =1 << private; -for (i =0 ; i < nr_pages; ++i) { -/* -* According to combination of -* MAX_ORDER and size of cyclic -* buffer, this clearing bit operation -* can overrun the cyclic buffer. -* -* See check_cyclic_buffer_overrun() -* for the detail. -*/ -if (clear_bit_on_2nd_bitmap_for_kernel ((pfn + i), cycle)) - pfn_free++; - } - pfn += nr_pages -1 ; - mem_map += (nr_pages -1 ) *SIZE (page); +if (clear_bit_on_2nd_bitmap_for_kernel (pfn, cycle)) + pfn_free++; + + info->exclude_pfn_start = pfn +1 ; + info->exclude_pfn_end = pfn + nr_pages; + info->exclude_pfn_counter = &pfn_free; }/* * Exclude the cache page without the private page.
makedumpfile.h +7 -0
@@ -1078,6 +1078,13 @@ struct DumpInfo {*/ int (*page_is_buddy)(unsigned long flags,unsigned int _mapcount,unsigned long private,unsigned int _count); + +/* +* for excluding multi-page regions +*/ +unsigned long exclude_pfn_start; +unsigned long exclude_pfn_end; +unsigned long long *exclude_pfn_counter; };extern struct DumpInfo *info;
Signature · 7 lines
1.8.4.5 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
PATCH 2/2 Git rid of overrun adjustments
In reply to Petr TesarikThanks to the previous commit, __exclude_unnecessary_pages does not require any specific size of the cycle.
--- makedumpfile.c | 59 ---------------------------------------------------------- 1 file changed, 59 deletions(-)
makedumpfile.c +0 -59
@@ -88,7 +88,6 @@ do { \ *ptr_long_table = value; \ }while (0 ) -static void check_cyclic_buffer_overrun(void); static void setup_page_is_buddy(void);void
@@ -3251,9 +3250,6 @@ out: !sadump_generate_elf_note_from_dumpfile())return FALSE; -if (info->flag_cyclic && info->dump_level &DL_EXCLUDE_FREE ) -check_cyclic_buffer_overrun (); - }else {if (!get_mem_map_without_mm ())return FALSE;
@@ -4271,61 +4267,6 @@ exclude_free_page(struct cycle *cycle) }/* -* Let C be a cyclic buffer size and B a bitmap size used for -* representing maximum block size managed by buddy allocator. -* -* For some combinations of C and B, clearing operation can overrun -* the cyclic buffer. Let's consider three cases. -* -* - If C == B, this is trivially safe. -* -* - If B > C, overrun can easily happen. -* -* - In case of C > B, if C mod B != 0, then there exist n > m > 0, -* B > b > 0 such that n x C = m x B + b. This means that clearing -* operation overruns cyclic buffer (B - b)-bytes in the -* combination of n-th cycle and m-th block. -* -* Note that C mod B != 0 iff (m x C) mod B != 0 for some m. -* -* If C == B, C mod B == 0 always holds. Again, if B > C, C mod B != 0 -* always holds. Hence, it's always sufficient to check the condition -* C mod B != 0 in order to determine whether overrun can happen or -* not. -* -* The bitmap size used for maximum block size B is calculated from -* MAX_ORDER as: -* -* B := DIVIDE_UP((1 << (MAX_ORDER - 1)), BITS_PER_BYTE) -* -* Normally, MAX_ORDER is 11 at default. This is configurable through -* CONFIG_FORCE_MAX_ZONEORDER. -*/ -static void -check_cyclic_buffer_overrun (void ) -{ -int max_order =ARRAY_LENGTH (zone.free_area); -int max_order_nr_pages =1 << (max_order -1 ); -unsigned long max_block_size =divideup (max_order_nr_pages,BITPERBYTE ); - -if (info->bufsize_cyclic % max_block_size) { -unsigned long bufsize; - -if (max_block_size > info->bufsize_cyclic) { -MSG ("WARNING: some free pages are not filtered.\n" ); -return ; - } - - bufsize = info->bufsize_cyclic; - info->bufsize_cyclic =round (bufsize, max_block_size); - info->pfn_cyclic = info->bufsize_cyclic *BITPERBYTE ; - -MSG ("cyclic buffer size has been changed: %lu => %lu\n" , - bufsize, info->bufsize_cyclic); - } -} - -/* * For the kernel versions from v2.6.17 to v2.6.37. */ static int
Signature · 7 lines
1.8.4.5 _______________________________________________ kexec mailing list [email protected] http://lists.infradead.org/mailman/listinfo/kexec
Quoted 11 lines · On Fri, 4 Apr 2014 11:56:07 +0200 Petr Tesarik <[email protected]> wrote:
Kumagai-san,
this patch was inspired by this post of yours:
http://lists.infradead.org/pipermail/kexec/2013-November/010445.html
Unfortunately, this rewrite never happened, so I took the liberty of overtaking the job. I hope you don't mind.
This is in fact a preparatory series to add hugepage support without having to care about the appropriate size of the cyclic buffer.
Scratch it. The algorithm assumes that work resumes exactly where it left in a previous run of __exclude_unnecessary_pages. While this is true for all dumps I have, the function is in fact invoked per-mm, so if there are two nodes in the cyclic buffer and they are not in ascending order by physical address, the algorithm may fail. That's simply not robust enough by my standards, so I'm going to respin this patch set.
Sorry if I've already wasted some of your time.
Petr Tesarik
_______________________________________________
kexec mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/kexec