Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15
xen.8389
5b471517-page_alloc-correct-first_dirty-calc-in...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5b471517-page_alloc-correct-first_dirty-calc-in-block-merging.patch of Package xen.8389
# Commit 1e2df9608857b5355f2ec3b1a34b87a2007dcd16 # Date 2018-07-12 10:45:11 +0200 # Author Sergey Dyasli <sergey.dyasli@citrix.com> # Committer Jan Beulich <jbeulich@suse.com> mm/page_alloc: correct first_dirty calculations during block merging Currently it's possible to hit an assertion in alloc_heap_pages(): Assertion 'first_dirty != INVALID_DIRTY_IDX || !(pg[i].count_info & PGC_need_scrub)' failed at page_alloc.c:988 This can happen because a piece of logic to calculate first_dirty during block merging in free_heap_pages() is missing for the following scenario: 1. Current block's first_dirty equals to INVALID_DIRTY_IDX 2. Successor block is free but its first_dirty != INVALID_DIRTY_IDX 3. The successor is merged into current block 4. Current block's first_dirty still equals to INVALID_DIRTY_IDX This will trigger the assertion during allocation of such block in alloc_heap_pages() because there will be pages with PGC_need_scrub bit set despite the claim of first_dirty that the block is scrubbed. Add the missing piece of logic and slightly update the comment for the predecessor case to better capture the code's intent. Fixes 1a37f33ea613 ("mm: Place unscrubbed pages at the end of pagelist") Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@oracle.com> --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1424,7 +1424,7 @@ static void free_heap_pages( page_list_del(predecessor, &heap(node, zone, order)); - /* Keep predecessor's first_dirty if it is already set. */ + /* Update predecessor's first_dirty if necessary. */ if ( predecessor->u.free.first_dirty == INVALID_DIRTY_IDX && pg->u.free.first_dirty != INVALID_DIRTY_IDX ) predecessor->u.free.first_dirty = (1U << order) + @@ -1445,6 +1445,12 @@ static void free_heap_pages( check_and_stop_scrub(successor); + /* Update pg's first_dirty if necessary. */ + if ( pg->u.free.first_dirty == INVALID_DIRTY_IDX && + successor->u.free.first_dirty != INVALID_DIRTY_IDX ) + pg->u.free.first_dirty = (1U << order) + + successor->u.free.first_dirty; + page_list_del(successor, &heap(node, zone, order)); }
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor