The patch titled Subject: mm: migration: factor out code to compute expected number of page references has been added to the -mm tree. Its filename is mm-migration-factor-out-code-to-compute-expected-number-of-page-references.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/mm-migration-factor-out-code-to-compute-expected-number-of-page-references.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/mm-migration-factor-out-code-to-compute-expected-number-of-page-references.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Jan Kara <jack@xxxxxxx> Subject: mm: migration: factor out code to compute expected number of page references Patch series "mm: migrate: Fix page migration stalls for blkdev pages". This patchset deals with page migration stalls that were reported by our customer due to a block device page that had a bufferhead that was in the bh LRU cache. The patchset modifies the page migration code so that bufferheads are completely handled inside buffer_migrate_page() and then provides a 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. This patch (of 6): 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. Link: http://lkml.kernel.org/r/20181211172143.7358-2-jack@xxxxxxx Signed-off-by: Jan Kara <jack@xxxxxxx> Acked-by: Mel Gorman <mgorman@xxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- --- a/mm/migrate.c~mm-migration-factor-out-code-to-compute-expected-number-of-page-references +++ a/mm/migrate.c @@ -424,6 +424,22 @@ static inline bool buffer_migrate_lock_b } #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. * @@ -440,14 +456,7 @@ int migrate_page_move_mapping(struct add 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 */ @@ -467,8 +476,6 @@ int migrate_page_move_mapping(struct add 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; _ Patches currently in -mm which might be from jack@xxxxxxx are mm-migration-factor-out-code-to-compute-expected-number-of-page-references.patch mm-migrate-lock-buffers-before-migrate_page_move_mapping.patch mm-migrate-move-migrate_page_lock_buffers.patch mm-migrate-provide-buffer_migrate_page_norefs.patch blkdev-avoid-migration-stalls-for-blkdev-pages.patch mm-migrate-drop-unused-argument-of-migrate_page_move_mapping.patch