Commit d936cf9b39b06c8d2e0d7fb5e7b4f176e18dec69
Committed by
Linus Torvalds
1 parent
edc315fd22
Exists in
master
and in
4 other branches
badpage: ratelimit print_bad_pte and bad_page
print_bad_pte() and bad_page() might each need ratelimiting - especially for their dump_stacks, almost never of interest, yet not quite dispensible. Correlating corruption across neighbouring entries can be very helpful, so allow a burst of 60 reports before keeping quiet for the remainder of that minute (or allow a steady drip of one report per second). Signed-off-by: Hugh Dickins <hugh@veritas.com> Cc: Nick Piggin <nickpiggin@yahoo.com.au> Cc: Christoph Lameter <cl@linux-foundation.org> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Rik van Riel <riel@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 48 additions and 1 deletions Side-by-side Diff
mm/memory.c
... | ... | @@ -383,6 +383,29 @@ |
383 | 383 | pmd_t *pmd = pmd_offset(pud, addr); |
384 | 384 | struct address_space *mapping; |
385 | 385 | pgoff_t index; |
386 | + static unsigned long resume; | |
387 | + static unsigned long nr_shown; | |
388 | + static unsigned long nr_unshown; | |
389 | + | |
390 | + /* | |
391 | + * Allow a burst of 60 reports, then keep quiet for that minute; | |
392 | + * or allow a steady drip of one report per second. | |
393 | + */ | |
394 | + if (nr_shown == 60) { | |
395 | + if (time_before(jiffies, resume)) { | |
396 | + nr_unshown++; | |
397 | + return; | |
398 | + } | |
399 | + if (nr_unshown) { | |
400 | + printk(KERN_EMERG | |
401 | + "Bad page map: %lu messages suppressed\n", | |
402 | + nr_unshown); | |
403 | + nr_unshown = 0; | |
404 | + } | |
405 | + nr_shown = 0; | |
406 | + } | |
407 | + if (nr_shown++ == 0) | |
408 | + resume = jiffies + 60 * HZ; | |
386 | 409 | |
387 | 410 | mapping = vma->vm_file ? vma->vm_file->f_mapping : NULL; |
388 | 411 | index = linear_page_index(vma, addr); |
mm/page_alloc.c
... | ... | @@ -223,6 +223,30 @@ |
223 | 223 | |
224 | 224 | static void bad_page(struct page *page) |
225 | 225 | { |
226 | + static unsigned long resume; | |
227 | + static unsigned long nr_shown; | |
228 | + static unsigned long nr_unshown; | |
229 | + | |
230 | + /* | |
231 | + * Allow a burst of 60 reports, then keep quiet for that minute; | |
232 | + * or allow a steady drip of one report per second. | |
233 | + */ | |
234 | + if (nr_shown == 60) { | |
235 | + if (time_before(jiffies, resume)) { | |
236 | + nr_unshown++; | |
237 | + goto out; | |
238 | + } | |
239 | + if (nr_unshown) { | |
240 | + printk(KERN_EMERG | |
241 | + "Bad page state: %lu messages suppressed\n", | |
242 | + nr_unshown); | |
243 | + nr_unshown = 0; | |
244 | + } | |
245 | + nr_shown = 0; | |
246 | + } | |
247 | + if (nr_shown++ == 0) | |
248 | + resume = jiffies + 60 * HZ; | |
249 | + | |
226 | 250 | printk(KERN_EMERG "Bad page state in process %s pfn:%05lx\n", |
227 | 251 | current->comm, page_to_pfn(page)); |
228 | 252 | printk(KERN_EMERG |
... | ... | @@ -232,7 +256,7 @@ |
232 | 256 | printk(KERN_EMERG "Trying to fix it up, but a reboot is needed\n"); |
233 | 257 | |
234 | 258 | dump_stack(); |
235 | - | |
259 | +out: | |
236 | 260 | /* Leave bad fields for debug, except PageBuddy could make trouble */ |
237 | 261 | __ClearPageBuddy(page); |
238 | 262 | add_taint(TAINT_BAD_PAGE); |