mm: migrate: Fix page migration stalls for blkdev pages
Subsystems (6)
Jan Kara
reviewerHello,
this patch set deals with page migration stalls that were reported by our customer due to block device page that had buffer head that was in bh LRU cache.
The patch set modifies page migration code so that buffer heads are completely handled inside buffer_migrate_page() and then provides new migration helper for pages with buffer heads that is safe to use even for block device pages and that also deals with bh lrus.
Honza
Jan Kara
reviewerPATCH 1/6 mm: migration: Factor out code to compute expected number of page references
Factor out function to compute number of expected page references in migrate_page_move_mapping(). Note that we move hpage_nr_pages() and page_has_private() checks from under xas_lock_irq() however this is safe since we hold page lock.
--- mm/migrate.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)
mm/migrate.c +17 -10
@@ -428,6 +428,22 @@ static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, }#endif /* CONFIG_BLOCK */ +static int expected_page_refs (struct page *page) +{ +int expected_count =1 ; + +/* +* Device public or private pages have an extra refcount as they are +* ZONE_DEVICE pages. +*/ + expected_count +=is_device_private_page (page); + expected_count +=is_device_public_page (page); +if (page->mapping) + expected_count +=hpage_nr_pages (page) +page_has_private (page); + +return expected_count; +} +/* * Replace the page in the mapping. *
@@ -444,14 +460,7 @@ int migrate_page_move_mapping(struct address_space *mapping,XA_STATE (xas, &mapping->i_pages,page_index (page));struct zone *oldzone, *newzone;int dirty; -int expected_count =1 + extra_count; - -/* -* Device public or private pages have an extra refcount as they are -* ZONE_DEVICE pages. -*/ - expected_count +=is_device_private_page (page); - expected_count +=is_device_public_page (page); +int expected_count =expected_page_refs (page) + extra_count;if (!mapping) {/* Anonymous page without mapping */
@@ -471,8 +480,6 @@ int migrate_page_move_mapping(struct address_space *mapping, newzone =page_zone (newpage);xas_lock_irq (&xas); - - expected_count +=hpage_nr_pages (page) +page_has_private (page);if (page_count (page) != expected_count ||xas_load (&xas) != page) {xas_unlock_irq (&xas);return -EAGAIN ;
Signature · 1 line
2.16.4
Re: [PATCH 1/6] mm: migration: Factor out code to compute expected number of page references
Quoted 6 lines · Jan Kara
Factor out function to compute number of expected page references in
migrate_page_move_mapping(). Note that we movehpage_nr_pages()andpage_has_private()checks from underxas_lock_irq()however this is safe since we hold page lock.Signed-off-by Jan Kara <[email protected]>
Signature · 2 lines
Mel Gorman SUSE Labs
Re: [PATCH 1/6] mm: migration: Factor out code to compute expected number of page references
In reply to Jan KaraQuoted 24 lines · Jan Kara
Factor out function to compute number of expected page references in
migrate_page_move_mapping(). Note that we movehpage_nr_pages()andpage_has_private()checks from underxas_lock_irq()however this is safe since we hold page lock.Signed-off-by Jan Kara <[email protected]>--- mm/migrate.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)mm/migrate.c +6
-0@@ -428,6 +428,22 @@ static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, }#endif /* CONFIG_BLOCK */ +static int expected_page_refs (struct page *page) +{ +int expected_count =1 ; + +/* +* Device public or private pages have an extra refcount as they are
mm/migrate.c static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, · line 446
Quoted 10 lines
mm/migrate.c +10
-0+* ZONE_DEVICE pages. +*/ + expected_count +=is_device_private_page (page); + expected_count +=is_device_public_page (page); +if (page->mapping) + expected_count +=hpage_nr_pages (page) +page_has_private (page); + +return expected_count; +} +
I noticed during testing that THP allocation success rates under the mmtests configuration global-dhp__workload_thpscale-madvhugepage-xfs were terrible with massive latencies introduced somewhere in the series. I haven't tried chasing it down as it's relatively late but this block looked odd and I missed it the first time.
This page->mapping test is relevant for the "Anonymous page without mapping" check but I think it's wrong. An anonymous page without mapping doesn't have a NULL mapping, it sets PAGE_MAPPING_ANON and the field can be special in other ways. I think you meant to use page_mapping(page) here, not page->mapping?
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerRe: [PATCH 1/6] mm: migration: Factor out code to compute expected number of page references
Quoted 33 lines · Mel Gorman
Quoted 32 lines · Jan Kara
Factor out function to compute number of expected page references in
migrate_page_move_mapping(). Note that we movehpage_nr_pages()andpage_has_private()checks from underxas_lock_irq()however this is safe since we hold page lock.Signed-off-by Jan Kara <[email protected]>--- mm/migrate.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-)mm/migrate.c +14
-0@@ -428,6 +428,22 @@ static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, }#endif /* CONFIG_BLOCK */ +static int expected_page_refs (struct page *page) +{ +int expected_count =1 ; + +/* +* Device public or private pages have an extra refcount as they are +* ZONE_DEVICE pages. +*/ + expected_count +=is_device_private_page (page); + expected_count +=is_device_public_page (page); +if (page->mapping) + expected_count +=hpage_nr_pages (page) +page_has_private (page); + +return expected_count;
Quoted 8 lines
mm/migrate.c static inline bool buffer_migrate_lock_buffers(struct buffer_head *head, · line 446
Quoted 2 lines
mm/migrate.c +2
-0+} +I noticed during testing that THP allocation success rates under the mmtests configuration global-dhp__workload_thpscale-madvhugepage-xfs were terrible with massive latencies introduced somewhere in the series. I haven't tried chasing it down as it's relatively late but this block looked odd and I missed it the first time.
Interesting. I've run config-global-dhp__workload_thpscale and that didn't show anything strange. But the numbers were fluctuating a lot both with and without my patches applied. I'll have a look if I can reproduce this sometime next week and look what could be causing the delays.
Quoted 5 lines
This
page->mappingtest is relevant for the "Anonymous page without mapping" check but I think it's wrong. An anonymous page without mapping doesn't have a NULL mapping, it setsPAGE_MAPPING_ANONand the field can be special in other ways. I think you meant to usepage_mapping(page)here, notpage->mapping?
Yes, that's a bug. It should have been page_mapping(page). Thanks for catching this.
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Re: [PATCH 1/6] mm: migration: Factor out code to compute expected number of page references
Quoted 11 lines · Jan Kara
Quoted 5 lines
I noticed during testing that THP allocation success rates under the mmtests configuration global-dhp__workload_thpscale-madvhugepage-xfs were terrible with massive latencies introduced somewhere in the series. I haven't tried chasing it down as it's relatively late but this block looked odd and I missed it the first time.
Interesting. I've run config-global-dhp__workload_thpscale and that didn't show anything strange. But the numbers were fluctuating a lot both with and without my patches applied. I'll have a look if I can reproduce this sometime next week and look what could be causing the delays.
Ah, it's the difference between madvise and !madvise. The configuration you used does very little compaction as it neither wakes kswapd of kcompactd. It just falls back to base pages to limit fault latency so you wouldn't have hit the same paths of interest.
Quoted 9 lines
Quoted 5 lines
This
page->mappingtest is relevant for the "Anonymous page without mapping" check but I think it's wrong. An anonymous page without mapping doesn't have a NULL mapping, it setsPAGE_MAPPING_ANONand the field can be special in other ways. I think you meant to usepage_mapping(page)here, notpage->mapping?Yes, that's a bug. It should have been
page_mapping(page). Thanks for catching this.
My pleasure, should have spotted it the first time around :/
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerRe: [PATCH 1/6] mm: migration: Factor out code to compute expected number of page references
Quoted 7 lines · Mel Gorman
Quoted 6 lines · Jan Kara
Quoted 5 lines
This
page->mappingtest is relevant for the "Anonymous page without mapping" check but I think it's wrong. An anonymous page without mapping doesn't have a NULL mapping, it setsPAGE_MAPPING_ANONand the field can be special in other ways. I think you meant to usepage_mapping(page)here, notpage->mapping?
Quoted 5 lines
Quoted 3 lines
Yes, that's a bug. It should have been
page_mapping(page). Thanks for catching this.My pleasure, should have spotted it the first time around :/
And after fixing this, I can see the success rates for global-dhp__workload_thpscale-madvhugepage to go back to the original values. So that was indeed the problem. I'll send the fixup to Andrew.
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Jan Kara
reviewerPATCH 2/6 mm: migrate: Lock buffers before migrate_page_move_mapping()
In reply to Jan KaraLock buffers before calling into migrate_page_move_mapping() so that that function doesn't have to know about buffers (which is somewhat unexpected anyway) and all the buffer head logic is in buffer_migrate_page().
--- mm/migrate.c | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-)
mm/migrate.c +13 -26
@@ -490,20 +490,6 @@ int migrate_page_move_mapping(struct address_space *mapping,return -EAGAIN ; } -/* -* In the async migration case of moving a page with buffers, lock the -* buffers using trylock before the mapping is moved. If the mapping -* was moved, we later failed to lock the buffers and could not move -* the mapping back due to an elevated page count, we would have to -* block waiting on other references to be dropped. -*/ -if (mode ==MIGRATE_ASYNC && head && - !buffer_migrate_lock_buffers (head, mode)) { -page_ref_unfreeze (page, expected_count); -xas_unlock_irq (&xas); -return -EAGAIN ; - } -/* * Now we know that no one else is looking at the page: * no turning back from here.
@@ -779,24 +765,23 @@ int buffer_migrate_page(struct address_space *mapping, {struct buffer_head *bh, *head;int rc; +int expected_count;if (!page_has_buffers (page))return migrate_page (mapping, newpage, page, mode); - head =page_buffers (page); +/* Check whether page does not have extra refs before we do more work */ + expected_count =expected_page_refs (page); +if (page_count (page) != expected_count) +return -EAGAIN ; - rc =migrate_page_move_mapping (mapping, newpage, page, head, mode,0 ); + head =page_buffers (page); +if (!buffer_migrate_lock_buffers (head, mode)) +return -EAGAIN ; + rc =migrate_page_move_mapping (mapping, newpage, page,NULL , mode,0 );if (rc !=MIGRATEPAGE_SUCCESS ) -return rc; - -/* -* In the async case, migrate_page_move_mapping locked the buffers -* with an IRQ-safe spinlock held. In the sync case, the buffers -* need to be locked now -*/ -if (mode !=MIGRATE_ASYNC ) -BUG_ON (!buffer_migrate_lock_buffers (head, mode)); + goto unlock_buffers;ClearPagePrivate (page);set_page_private (newpage,page_private (page));
@@ -818,6 +803,8 @@ int buffer_migrate_page(struct address_space *mapping,else migrate_page_states (newpage, page); + rc =MIGRATEPAGE_SUCCESS ; +unlock_buffers: bh = head; do { unlock_buffer(bh);
@@ -826,7 +813,7 @@ int buffer_migrate_page(struct address_space *mapping, } while (bh != head); -return MIGRATEPAGE_SUCCESS ; +return rc; }EXPORT_SYMBOL (buffer_migrate_page);#endif
Signature · 1 line
2.16.4
Re: [PATCH 2/6] mm: migrate: Lock buffers before migrate_page_move_mapping()
Quoted 6 lines · Jan Kara
Lock buffers before calling into
migrate_page_move_mapping()so that that function doesn't have to know about buffers (which is somewhat unexpected anyway) and all the buffer head logic is inbuffer_migrate_page().Signed-off-by Jan Kara <[email protected]>
This is a much nicer flow.
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerPATCH 3/6 mm: migrate: Move migrate_page_lock_buffers()
In reply to Jan Karabuffer_migrate_page() is the only caller of migrate_page_lock_buffers() move it close to it and also drop the now unused stub for !CONFIG_BLOCK.
--- mm/migrate.c | 92 +++++++++++++++++++++++++++--------------------------------- 1 file changed, 42 insertions(+), 50 deletions(-)
mm/migrate.c +42 -50
@@ -378,56 +378,6 @@ void pmd_migration_entry_wait(struct mm_struct *mm, pmd_t *pmd) }#endif -#ifdef CONFIG_BLOCK -/* Returns true if all buffers are successfully locked */ -static bool buffer_migrate_lock_buffers (struct buffer_head *head, -enum migrate_mode mode) -{ -struct buffer_head *bh = head; - -/* Simple case, sync compaction */ -if (mode !=MIGRATE_ASYNC ) { -do { -get_bh (bh); -lock_buffer (bh); - bh = bh->b_this_page; - - }while (bh != head); - -return true; - } - -/* async case, we cannot block on lock_buffer so use trylock_buffer */ -do { -get_bh (bh); -if (!trylock_buffer (bh)) { -/* -* We failed to lock the buffer and cannot stall in -* async migration. Release the taken locks -*/ -struct buffer_head *failed_bh = bh; -put_bh (failed_bh); - bh = head; -while (bh != failed_bh) { -unlock_buffer (bh); -put_bh (bh); - bh = bh->b_this_page; - } -return false; - } - - bh = bh->b_this_page; - }while (bh != head); -return true; -} -#else -static inline bool buffer_migrate_lock_buffers (struct buffer_head *head, -enum migrate_mode mode) -{ -return true; -} -#endif /* CONFIG_BLOCK */ -static int expected_page_refs (struct page *page) {int expected_count =1 ;
@@ -755,6 +705,48 @@ int migrate_page(struct address_space *mapping,EXPORT_SYMBOL (migrate_page);#ifdef CONFIG_BLOCK +/* Returns true if all buffers are successfully locked */ +static bool buffer_migrate_lock_buffers (struct buffer_head *head, +enum migrate_mode mode) +{ +struct buffer_head *bh = head; + +/* Simple case, sync compaction */ +if (mode !=MIGRATE_ASYNC ) { +do { +get_bh (bh); +lock_buffer (bh); + bh = bh->b_this_page; + + }while (bh != head); + +return true; + } + +/* async case, we cannot block on lock_buffer so use trylock_buffer */ +do { +get_bh (bh); +if (!trylock_buffer (bh)) { +/* +* We failed to lock the buffer and cannot stall in +* async migration. Release the taken locks +*/ +struct buffer_head *failed_bh = bh; +put_bh (failed_bh); + bh = head; +while (bh != failed_bh) { +unlock_buffer (bh); +put_bh (bh); + bh = bh->b_this_page; + } +return false; + } + + bh = bh->b_this_page; + }while (bh != head); +return true; +} +/* * Migration function for pages with buffers. This function can only be used * if the underlying filesystem guarantees that no other references to "page"
Signature · 1 line
2.16.4
Re: [PATCH 3/6] mm: migrate: Move migrate_page_lock_buffers()
Quoted 4 lines · Jan Kara
buffer_migrate_page()is the only caller ofmigrate_page_lock_buffers()move it close to it and also drop the now unused stub for !CONFIG_BLOCK.Signed-off-by Jan Kara <[email protected]>
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerPATCH 4/6 mm: migrate: Provide buffer_migrate_page_norefs()
In reply to Jan KaraProvide a variant of buffer_migrate_page() that also checks whether there are no unexpected references to buffer heads. This function will then be safe to use for block device pages.
--- include/linux/fs.h | 4 ++++ mm/migrate.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 7 deletions(-)
include/linux/fs.h +4 -0
@@ -3264,8 +3264,12 @@ extern int generic_check_addressable(unsigned, u64);extern int buffer_migrate_page (struct address_space *,struct page *,struct page *,enum migrate_mode ); +extern int buffer_migrate_page_norefs (struct address_space *, +struct page *,struct page *, +enum migrate_mode );#else #define buffer_migrate_page NULL +#define buffer_migrate_page_norefs NULL#endif extern int setattr_prepare (struct dentry *,struct iattr *);
mm/migrate.c +54 -7
80 lines not on this page · raw message
Signature · 1 line
2.16.4
Re: [PATCH 4/6] mm: migrate: Provide buffer_migrate_page_norefs()
Quoted 5 lines · Jan Kara
Provide a variant of
buffer_migrate_page()that also checks whether there are no unexpected references to buffer heads. This function will then be safe to use for block device pages.Signed-off-by Jan Kara <[email protected]>
Signature · 2 lines
Mel Gorman SUSE Labs
Andrew Morton
maintainerRe: [PATCH 4/6] mm: migrate: Provide buffer_migrate_page_norefs()
In reply to Jan KaraQuoted 7 lines · On Tue, 11 Dec 2018 18:21:41 +0100 Jan Kara <[email protected]> wrote:
Provide a variant of
buffer_migrate_page()that also checks whether there are no unexpected references to buffer heads. This function will then be safe to use for block device pages....
+EXPORT_SYMBOL(buffer_migrate_page_norefs);
The export is presently unneeded and I don't think we expect that this will be used by anything other than fs/block_dev.c?
Jan Kara
reviewerRe: [PATCH 4/6] mm: migrate: Provide buffer_migrate_page_norefs()
Quoted 6 lines · Andrew Morton
Quoted 4 lines · On Tue, 11 Dec 2018 18:21:41 +0100 Jan Kara <[email protected]> wrote:
Provide a variant of
buffer_migrate_page()that also checks whether there are no unexpected references to buffer heads. This function will then be safe to use for block device pages.
Quoted 6 lines
Quoted 3 lines
...
+EXPORT_SYMBOL(buffer_migrate_page_norefs);
The export is presently unneeded and I don't think we expect that this will be used by anything other than
fs/block_dev.c?
Good point. We can always re-add the export if someone needs it. Thanks for removing it!
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Jan Kara
reviewerPATCH 5/6 blkdev: Avoid migration stalls for blkdev pages
In reply to Jan KaraCurrently, block device pages don't provide a ->migratepage callback and thus fallback_migrate_page() is used for them. This handler cannot deal with dirty pages in async mode and also with the case a buffer head is in the LRU buffer head cache (as it has elevated b_count). Thus such page can block memory offlining.
Fix the problem by using buffer_migrate_page_norefs() for migrating block device pages. That function takes care of dropping bh LRU in case migration would fail due to elevated buffer refcount to avoid stalls and can also migrate dirty pages without writing them.
--- fs/block_dev.c | 1 + 1 file changed, 1 insertion(+)
fs/block_dev.c +1 -0
@@ -1966,6 +1966,7 @@ static const struct address_space_operations def_blk_aops = { .writepages = blkdev_writepages, .releasepage = blkdev_releasepage, .direct_IO = blkdev_direct_IO, + .migratepage = buffer_migrate_page_norefs, .is_dirty_writeback = buffer_check_dirty_writeback, };
Signature · 1 line
2.16.4
Re: [PATCH 5/6] blkdev: Avoid migration stalls for blkdev pages
Quoted 6 lines · Jan Kara
Currently, block device pages don't provide a ->migratepage callback and thus
fallback_migrate_page()is used for them. This handler cannot deal with dirty pages in async mode and also with the case a buffer head is in the LRU buffer head cache (as it has elevatedb_count). Thus such page can block memory offlining.
Quoted 6 lines
Fix the problem by using
buffer_migrate_page_norefs()for migrating block device pages. That function takes care of dropping bh LRU in case migration would fail due to elevated buffer refcount to avoid stalls and can also migrate dirty pages without writing them.Signed-off-by Jan Kara <[email protected]>
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerPATCH 6/6 mm: migrate: Drop unused argument of migrate_page_move_mapping()
In reply to Jan KaraAll callers of migrate_page_move_mapping() now pass NULL for 'head' argument. Drop it.
--- fs/aio.c | 2 +- fs/f2fs/data.c | 2 +- fs/iomap.c | 2 +- fs/ubifs/file.c | 2 +- include/linux/migrate.h | 3 +-- mm/migrate.c | 7 +++---- 6 files changed, 8 insertions(+), 10 deletions(-)
fs/aio.c +1 -1
@@ -408,7 +408,7 @@ static int aio_migratepage(struct address_space *mapping, struct page *new,BUG_ON (PageWriteback (old));get_page (new); - rc =migrate_page_move_mapping (mapping, new, old,NULL , mode,1 ); + rc =migrate_page_move_mapping (mapping, new, old, mode,1 );if (rc !=MIGRATEPAGE_SUCCESS ) {put_page (new); goto out_unlock;
fs/f2fs/data.c +1 -1
@@ -2738,7 +2738,7 @@ int f2fs_migrate_page(struct address_space *mapping,*/ extra_count = (atomic_written ?1 :0 ) -page_has_private (page); rc =migrate_page_move_mapping (mapping, newpage, - page,NULL , mode, extra_count); + page, mode, extra_count);if (rc !=MIGRATEPAGE_SUCCESS ) {if (atomic_written)mutex_unlock (&fi->inmem_lock);
fs/iomap.c +1 -1
@@ -550,7 +550,7 @@ iomap_migrate_page(struct address_space *mapping, struct page *newpage, {int ret; - ret =migrate_page_move_mapping (mapping, newpage, page,NULL , mode,0 ); + ret =migrate_page_move_mapping (mapping, newpage, page, mode,0 );if (ret !=MIGRATEPAGE_SUCCESS )return ret;
fs/ubifs/file.c +1 -1
@@ -1481,7 +1481,7 @@ static int ubifs_migrate_page(struct address_space *mapping, {int rc; - rc =migrate_page_move_mapping (mapping, newpage, page,NULL , mode,0 ); + rc =migrate_page_move_mapping (mapping, newpage, page, mode,0 );if (rc !=MIGRATEPAGE_SUCCESS )return rc;
include/linux/migrate.h +1 -2
@@ -77,8 +77,7 @@ extern void migrate_page_copy(struct page *newpage, struct page *page);extern int migrate_huge_page_move_mapping (struct address_space *mapping,struct page *newpage,struct page *page);extern int migrate_page_move_mapping (struct address_space *mapping, -struct page *newpage,struct page *page, -struct buffer_head *head,enum migrate_mode mode, +struct page *newpage,struct page *page,enum migrate_mode mode,int extra_count);#else
mm/migrate.c +3 -4
@@ -403,8 +403,7 @@ static int expected_page_refs(struct page *page)* 3 for pages with a mapping and PagePrivate/PagePrivate2 set. */ int migrate_page_move_mapping (struct address_space *mapping, -struct page *newpage,struct page *page, -struct buffer_head *head,enum migrate_mode mode, +struct page *newpage,struct page *page,enum migrate_mode mode,int extra_count) {XA_STATE (xas, &mapping->i_pages,page_index (page));
@@ -691,7 +690,7 @@ int migrate_page(struct address_space *mapping,BUG_ON (PageWriteback (page));/* Writeback must be complete */ - rc =migrate_page_move_mapping (mapping, newpage, page,NULL , mode,0 ); + rc =migrate_page_move_mapping (mapping, newpage, page, mode,0 );if (rc !=MIGRATEPAGE_SUCCESS )return rc;
@@ -794,7 +793,7 @@ static int __buffer_migrate_page(struct address_space *mapping, } } - rc =migrate_page_move_mapping (mapping, newpage, page,NULL , mode,0 ); + rc =migrate_page_move_mapping (mapping, newpage, page, mode,0 );if (rc !=MIGRATEPAGE_SUCCESS ) goto unlock_buffers;
Signature · 1 line
2.16.4
Re: [PATCH 6/6] mm: migrate: Drop unused argument of migrate_page_move_mapping()
Quoted 4 lines · Jan Kara
All callers of
migrate_page_move_mapping()now pass NULL for 'head' argument. Drop it.Signed-off-by Jan Kara <[email protected]>
Signature · 2 lines
Mel Gorman SUSE Labs
Jan Kara
reviewerRe: [PATCH 6/6] mm: migrate: Drop unused argument of migrate_page_move_mapping()
Quoted 7 lines · Mel Gorman
Quoted 4 lines · Jan Kara
All callers of
migrate_page_move_mapping()now pass NULL for 'head' argument. Drop it.Signed-off-by Jan Kara <[email protected]>Acked-by Mel Gorman <[email protected]>
Thanks for review Mel! Andrew, can you please pick up the series? Thanks!
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
Jan Kara
reviewerRe: [PATCH 6/6] mm: migrate: Drop unused argument of migrate_page_move_mapping()
Quoted 10 lines · Jan Kara
Quoted 7 lines · Mel Gorman
Quoted 4 lines · Jan Kara
All callers of
migrate_page_move_mapping()now pass NULL for 'head' argument. Drop it.Signed-off-by Jan Kara <[email protected]>Acked-by Mel Gorman <[email protected]>Thanks for review Mel! Andrew, can you please pick up the series? Thanks!
Andrew, Mel has spotted a bug in patch 1/6 or this series. Can you please add the attached fixup to the patch 1? Thanks!
Honza
Signature · 2 lines
Jan Kara <[email protected]> SUSE Labs, CR
mm/migrate.c +1 -1
@@ -438,7 +438,7 @@ static int expected_page_refs(struct page *page)*/ expected_count +=is_device_private_page (page); expected_count +=is_device_public_page (page); -if (page->mapping) +if (page_mapping (page)) expected_count +=hpage_nr_pages (page) +page_has_private (page);return expected_count;