The patch titled Subject: mm: warn on deleting redirtied only if accounted has been added to the -mm tree. Its filename is mm-warn-on-deleting-redirtied-only-if-accounted.patch This patch should soon appear at https://ozlabs.org/~akpm/mmots/broken-out/mm-warn-on-deleting-redirtied-only-if-accounted.patch and later at https://ozlabs.org/~akpm/mmotm/broken-out/mm-warn-on-deleting-redirtied-only-if-accounted.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: Hugh Dickins <hughd@xxxxxxxxxx> Subject: mm: warn on deleting redirtied only if accounted filemap_unaccount_folio() has a WARN_ON_ONCE(folio_test_dirty(folio)). It is good to warn of late dirtying on a persistent filesystem, but late dirtying on tmpfs can only lose data which is expected to be thrown away; and it's a pity if that warning comes ONCE on tmpfs, then hides others which really matter. Make it conditional on mapping_cap_writeback(). Cleanup: then folio_account_cleaned() no longer needs to check that for itself, and so no longer needs to know the mapping. Link: https://lkml.kernel.org/r/b5a1106c-7226-a5c6-ad41-ad4832cae1f@xxxxxxxxxx Signed-off-by: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Matthew Wilcox <willy@xxxxxxxxxxxxx> Cc: Jan Kara <jack@xxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/pagemap.h | 3 +-- mm/filemap.c | 14 +++++++++----- mm/page-writeback.c | 18 ++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) --- a/include/linux/pagemap.h~mm-warn-on-deleting-redirtied-only-if-accounted +++ a/include/linux/pagemap.h @@ -991,8 +991,7 @@ static inline void __set_page_dirty(stru { __folio_mark_dirty(page_folio(page), mapping, warn); } -void folio_account_cleaned(struct folio *folio, struct address_space *mapping, - struct bdi_writeback *wb); +void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb); void __folio_cancel_dirty(struct folio *folio); static inline void folio_cancel_dirty(struct folio *folio) { --- a/mm/filemap.c~mm-warn-on-deleting-redirtied-only-if-accounted +++ a/mm/filemap.c @@ -193,16 +193,20 @@ static void filemap_unaccount_folio(stru /* * At this point folio must be either written or cleaned by * truncate. Dirty folio here signals a bug and loss of - * unwritten data. + * unwritten data - on ordinary filesystems. * - * This fixes dirty accounting after removing the folio entirely + * But it's harmless on in-memory filesystems like tmpfs; and can + * occur when a driver which did get_user_pages() sets page dirty + * before putting it, while the inode is being finally evicted. + * + * Below fixes dirty accounting after removing the folio entirely * but leaves the dirty flag set: it has no effect for truncated * folio and anyway will be cleared before returning folio to * buddy allocator. */ - if (WARN_ON_ONCE(folio_test_dirty(folio))) - folio_account_cleaned(folio, mapping, - inode_to_wb(mapping->host)); + if (WARN_ON_ONCE(folio_test_dirty(folio) && + mapping_can_writeback(mapping))) + folio_account_cleaned(folio, inode_to_wb(mapping->host)); } /* --- a/mm/page-writeback.c~mm-warn-on-deleting-redirtied-only-if-accounted +++ a/mm/page-writeback.c @@ -2548,16 +2548,14 @@ static void folio_account_dirtied(struct * * Caller must hold lock_page_memcg(). */ -void folio_account_cleaned(struct folio *folio, struct address_space *mapping, - struct bdi_writeback *wb) +void folio_account_cleaned(struct folio *folio, struct bdi_writeback *wb) { - if (mapping_can_writeback(mapping)) { - long nr = folio_nr_pages(folio); - lruvec_stat_mod_folio(folio, NR_FILE_DIRTY, -nr); - zone_stat_mod_folio(folio, NR_ZONE_WRITE_PENDING, -nr); - wb_stat_mod(wb, WB_RECLAIMABLE, -nr); - task_io_account_cancelled_write(nr * PAGE_SIZE); - } + long nr = folio_nr_pages(folio); + + lruvec_stat_mod_folio(folio, NR_FILE_DIRTY, -nr); + zone_stat_mod_folio(folio, NR_ZONE_WRITE_PENDING, -nr); + wb_stat_mod(wb, WB_RECLAIMABLE, -nr); + task_io_account_cancelled_write(nr * PAGE_SIZE); } /* @@ -2768,7 +2766,7 @@ void __folio_cancel_dirty(struct folio * wb = unlocked_inode_to_wb_begin(inode, &cookie); if (folio_test_clear_dirty(folio)) - folio_account_cleaned(folio, mapping, wb); + folio_account_cleaned(folio, wb); unlocked_inode_to_wb_end(inode, &cookie); folio_memcg_unlock(folio); _ Patches currently in -mm which might be from hughd@xxxxxxxxxx are mm-fs-delete-pf_swapwrite.patch tmpfs-support-for-file-creation-time-fix.patch shmem-mapping_set_exiting-to-help-mapped-resilience.patch mm-_install_special_mapping-apply-vm_locked_clear_mask.patch mm-thp-refix-__split_huge_pmd_locked-for-migration-pmd.patch mm-thp-clearpagedoublemap-in-first-page_add_file_rmap.patch mm-delete-__clearpagewaiters.patch mm-filemap_unaccount_folio-large-skip-mapcount-fixup.patch mm-thp-fix-nr_file_mapped-accounting-in-page__file_rmap.patch mm-warn-on-deleting-redirtied-only-if-accounted.patch