diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 6ddaeba..f130d02 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -3757,6 +3757,9 @@ void mem_cgroup_wb_stats(struct bdi_writeback *wb, unsigned long *pavail, unsigned long file_pages; *pdirty = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_DIRTY); + WARN(*pdirty > (1<<30), "%s() huge dirty: %ld\n", __func__, *pdirty); + if (*pdirty > (1<<30)) + *pdirty = 0; /* this should eventually include NR_UNSTABLE_NFS */ *pwriteback = mem_cgroup_read_stat(memcg, MEM_CGROUP_STAT_WRITEBACK); @@ -4607,6 +4610,8 @@ static int mem_cgroup_move_account(struct page *page, nr_pages); __this_cpu_add(to->stat->count[MEM_CGROUP_STAT_DIRTY], nr_pages); + WARN_ONCE(__this_cpu_read(from->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); + WARN_ONCE(__this_cpu_read( to->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); } } diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 0a931cd..9dfd8fa 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -1546,6 +1546,7 @@ static void balance_dirty_pages(struct address_space *mapping, global_page_state(NR_UNSTABLE_NFS); gdtc->avail = global_dirtyable_memory(); gdtc->dirty = nr_reclaimable + global_page_state(NR_WRITEBACK); + WARN(gdtc->dirty > (1<<30), "%s() huge dirty: %ld\n", __func__, gdtc->dirty); domain_dirty_limits(gdtc); @@ -1570,6 +1571,7 @@ static void balance_dirty_pages(struct address_space *mapping, */ mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty, &writeback); + WARN(mdtc->dirty > (1<<30), "%s() huge dirty: %ld\n", __func__, mdtc->dirty); mdtc_cap_avail(mdtc); mdtc->dirty += writeback; @@ -1884,6 +1886,7 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) gdtc->avail = global_dirtyable_memory(); gdtc->dirty = global_page_state(NR_FILE_DIRTY) + global_page_state(NR_UNSTABLE_NFS); + WARN(gdtc->dirty > (1<<30), "%s() huge dirty: %ld\n", __func__, gdtc->dirty); domain_dirty_limits(gdtc); if (gdtc->dirty > gdtc->bg_thresh) @@ -1896,6 +1899,7 @@ bool wb_over_bg_thresh(struct bdi_writeback *wb) unsigned long writeback; mem_cgroup_wb_stats(wb, &mdtc->avail, &mdtc->dirty, &writeback); + WARN(mdtc->dirty > (1<<30), "%s() huge dirty: %ld\n", __func__, mdtc->dirty); mdtc_cap_avail(mdtc); domain_dirty_limits(mdtc); /* ditto, ignore writeback */ @@ -2404,7 +2408,9 @@ void account_page_dirtied(struct page *page, struct address_space *mapping, inode_attach_wb(inode, page); wb = inode_to_wb(inode); + WARN_ONCE(__this_cpu_read(memcg->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); mem_cgroup_inc_page_stat(memcg, MEM_CGROUP_STAT_DIRTY); + WARN_ONCE(__this_cpu_read(memcg->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); __inc_zone_page_state(page, NR_FILE_DIRTY); __inc_zone_page_state(page, NR_DIRTIED); __inc_wb_stat(wb, WB_RECLAIMABLE); @@ -2426,6 +2432,7 @@ void account_page_cleaned(struct page *page, struct address_space *mapping, { if (mapping_cap_account_dirty(mapping)) { mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_DIRTY); + WARN_ONCE(__this_cpu_read(memcg->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); dec_zone_page_state(page, NR_FILE_DIRTY); dec_wb_stat(wb, WB_RECLAIMABLE); task_io_account_cancelled_write(PAGE_CACHE_SIZE); @@ -2686,6 +2693,7 @@ int clear_page_dirty_for_io(struct page *page) wb = unlocked_inode_to_wb_begin(inode, &locked); if (TestClearPageDirty(page)) { mem_cgroup_dec_page_stat(memcg, MEM_CGROUP_STAT_DIRTY); + WARN_ONCE(__this_cpu_read(memcg->stat->count[MEM_CGROUP_STAT_DIRTY]) > (1UL<<30), "MEM_CGROUP_STAT_DIRTY bogus"); dec_zone_page_state(page, NR_FILE_DIRTY); dec_wb_stat(wb, WB_RECLAIMABLE); ret = 1;