From: "M. Vefa Bicakci" <bicave@superonline.com>
To: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernationto hang
Date: Tue, 31 Aug 2010 14:25:49 +0300 [thread overview]
Message-ID: <4C7CE6BD.9040601@superonline.com> (raw)
In-Reply-To: <20100831155302.87E2.A69D9226@jp.fujitsu.com>
[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]
On 31/08/10 09:54 AM, KOSAKI Motohiro wrote:
>> Great!
>> I've attached more verbose debug message patch and trial bug fixing patch.
>> Could you please to try this?
>
> Oops, please apply attached patch instead 0002-add-gfp_noretry.patch.
>
> Thanks.
Hello!
I have applied the patches you mentioned, and rebuilt and tested the
2.6.35.4 kernel. I am really happy to say that your patches (cumulatively)
fixed the issue!
Unfortunately, because the hibernation is rather quick, I am having a
hard time getting screen-shots with my camera. If you would like, I can
try to put some sleeps around the code so that I can get the output for
you.
For the record, the attached patch is the cumulative version of all of
your patches. It applies cleanly to 2.6.35.4, and most importantly, it
fixes the issue.
All in all, thanks a lot!
Is there anything else I can do? Would you like me to try a trimmed
version of your patch, maybe without the debugging parts and the 5-pass
swap-out procedure, which I am not sure is essential or not?
Thanks again,
M. Vefa Bicakci
[-- Attachment #2: mm-patch-debug+fix-full.txt --]
[-- Type: text/plain, Size: 10387 bytes --]
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c
index 25ce010..c672931 100644
--- a/kernel/power/snapshot.c
+++ b/kernel/power/snapshot.c
@@ -1257,12 +1257,15 @@ static unsigned long minimum_image_size(unsigned long saveable)
int hibernate_preallocate_memory(void)
{
struct zone *zone;
- unsigned long saveable, size, max_size, count, highmem, pages = 0;
+ unsigned long saveable, max_size, count, highmem, pages = 0;
unsigned long alloc, save_highmem, pages_highmem;
struct timeval start, stop;
int error;
+ unsigned long additional_size, img_size;
+ unsigned long pages_fraction;
+ unsigned long img_pages;
- printk(KERN_INFO "PM: Preallocating image memory... ");
+ printk(KERN_INFO "PM: Preallocating image memory... \n");
do_gettimeofday(&start);
error = memory_bm_create(&orig_bm, GFP_IMAGE, PG_ANY);
@@ -1287,9 +1290,9 @@ int hibernate_preallocate_memory(void)
count = saveable;
saveable += save_highmem;
highmem = save_highmem;
- size = 0;
+ additional_size = 0;
for_each_populated_zone(zone) {
- size += snapshot_additional_pages(zone);
+ additional_size += snapshot_additional_pages(zone);
if (is_highmem(zone))
highmem += zone_page_state(zone, NR_FREE_PAGES);
else
@@ -1298,25 +1301,36 @@ int hibernate_preallocate_memory(void)
count += highmem;
count -= totalreserve_pages;
+ printk(KERN_INFO "PM: save_highmem(%lu), saveable(%lu) count=(%lu)\n",
+ save_highmem, saveable, count);
+
/* Compute the maximum number of saveable pages to leave in memory. */
- max_size = (count - (size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES;
- size = DIV_ROUND_UP(image_size, PAGE_SIZE);
- if (size > max_size)
- size = max_size;
+ max_size = (count - (additional_size + PAGES_FOR_IO)) / 2 - 2 * SPARE_PAGES;
+ img_size = DIV_ROUND_UP(image_size, PAGE_SIZE);
+ if (img_size > max_size)
+ img_size = max_size;
+
+ printk(KERN_INFO "PM: max_size(%lu), image_size(%lu), img_size(%lu)\n",
+ max_size, image_size, img_size);
+
/*
* If the maximum is not less than the current number of saveable pages
* in memory, allocate page frames for the image and we're done.
*/
- if (size >= saveable) {
+ if (img_size >= saveable) {
+ printk(KERN_INFO "PM: size >= saveable. skip \n");
pages = preallocate_image_highmem(save_highmem);
pages += preallocate_image_memory(saveable - pages);
goto out;
}
/* Estimate the minimum size of the image. */
- pages = minimum_image_size(saveable);
- if (size < pages)
- size = min_t(unsigned long, pages, max_size);
+ img_pages = minimum_image_size(saveable);
+ if (img_size < img_pages)
+ img_size = min_t(unsigned long, img_pages, max_size);
+
+ printk(KERN_INFO "PM: img_pages(%lu), img_size(%lu)\n",
+ img_pages, img_size);
/*
* Let the memory management subsystem know that we're going to need a
@@ -1324,7 +1338,7 @@ int hibernate_preallocate_memory(void)
* NOTE: If this is not done, performance will be hurt badly in some
* test cases.
*/
- shrink_all_memory(saveable - size);
+ shrink_all_memory(saveable - img_size);
/*
* The number of saveable pages in memory was too high, so apply some
@@ -1334,16 +1348,31 @@ int hibernate_preallocate_memory(void)
* highmem and non-highmem zones separately.
*/
pages_highmem = preallocate_image_highmem(highmem / 2);
+ printk(KERN_INFO "PM: preallocate_image_highmem %lu %lu free(%u/%lu)\n",
+ highmem, pages_highmem, nr_free_highpages(), global_page_state(NR_FREE_PAGES));
+
alloc = (count - max_size) - pages_highmem;
pages = preallocate_image_memory(alloc);
- if (pages < alloc)
+ printk(KERN_INFO "PM: preallocate_image_memory %lu %lu free(%u/%lu)\n",
+ alloc, pages, nr_free_highpages(), global_page_state(NR_FREE_PAGES));
+
+ if (pages < alloc) {
+ printk(KERN_INFO "PM: pages(%lu) < alloc(%lu). error. \n",
+ pages, alloc);
goto err_out;
- size = max_size - size;
- alloc = size;
- size = preallocate_highmem_fraction(size, highmem, count);
- pages_highmem += size;
- alloc -= size;
+ }
+
+ alloc = max_size - img_size;
+
+ pages_fraction = preallocate_highmem_fraction(alloc, highmem, count);
+ printk(KERN_INFO "PM: preallocate_highmem_fraction %lu %lu %lu -> %lu free(%u/%lu)\n",
+ alloc, highmem, count, pages_fraction, nr_free_highpages(), global_page_state(NR_FREE_PAGES));
+
+ pages_highmem += pages_fraction;
+ alloc -= pages_fraction;
pages += preallocate_image_memory(alloc);
+ printk(KERN_INFO "PM: preallocate_image_memory %lu %lu free(%u/%lu)\n",
+ alloc, pages, nr_free_highpages(), global_page_state(NR_FREE_PAGES));
pages += pages_highmem;
/*
@@ -1351,18 +1380,20 @@ int hibernate_preallocate_memory(void)
* pages in memory, but we have allocated more. Release the excessive
* ones now.
*/
+ printk(KERN_INFO "PM: free_unnecessary_pages() \n");
free_unnecessary_pages();
out:
do_gettimeofday(&stop);
- printk(KERN_CONT "done (allocated %lu pages)\n", pages);
+ printk(KERN_INFO "done (allocated %lu pages)\n", pages);
swsusp_show_speed(&start, &stop, pages, "Allocated");
return 0;
err_out:
- printk(KERN_CONT "\n");
+ printk(KERN_INFO "PM: err_out \n");
swsusp_free();
+ printk(KERN_INFO "PM: swsusp_free() end \n");
return -ENOMEM;
}
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index d24f761..3b72836 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -961,6 +961,43 @@ static struct ctl_table kern_table[] = {
{ }
};
+static int sysctl_shrink_all_memory;
+static int shrink_all_memory_handler(ctl_table *table, int write,
+ void __user *buffer, size_t *length,
+ loff_t *ppos)
+{
+ proc_dointvec_minmax(table, write, buffer, length, ppos);
+ if (write) {
+ shrink_all_memory(sysctl_shrink_all_memory);
+ }
+ return 0;
+}
+
+#include <linux/mm_types.h>
+#include <linux/mmzone.h>
+
+static int reset_reclaim_stat_handler(ctl_table *table, int write,
+ void __user *buffer, size_t *length,
+ loff_t *ppos)
+{
+ struct zone *zone;
+ struct zone_reclaim_stat *rstat;
+
+ if (write) {
+ for_each_populated_zone(zone) {
+ spin_lock_irq(&zone->lru_lock);
+ rstat = &zone->reclaim_stat;
+ rstat->recent_scanned[0] = 0;
+ rstat->recent_rotated[0] = 0;
+ rstat->recent_scanned[1] = 0;
+ rstat->recent_rotated[1] = 0;
+ spin_unlock_irq(&zone->lru_lock);
+ }
+
+ }
+ return 0;
+}
+
static struct ctl_table vm_table[] = {
{
.procname = "overcommit_memory",
@@ -1318,6 +1355,20 @@ static struct ctl_table vm_table[] = {
.extra2 = &one,
},
#endif
+ {
+ .procname = "shrink_all_memory",
+ .data = &sysctl_shrink_all_memory,
+ .maxlen = sizeof(sysctl_shrink_all_memory),
+ .mode = 0644,
+ .proc_handler = shrink_all_memory_handler,
+ },
+ {
+ .procname = "reset_reclaim_stat",
+ .data = &sysctl_shrink_all_memory,
+ .maxlen = sizeof(sysctl_shrink_all_memory),
+ .mode = 0644,
+ .proc_handler = reset_reclaim_stat_handler,
+ },
/*
* NOTE: do not add new entries to this table unless you have read
diff --git a/mm/vmscan.c b/mm/vmscan.c
index b94fe1b..100282c 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -40,6 +40,7 @@
#include <linux/memcontrol.h>
#include <linux/delayacct.h>
#include <linux/sysctl.h>
+#include <linux/oom.h>
#include <asm/tlbflush.h>
#include <asm/div64.h>
@@ -611,7 +612,7 @@ static enum page_references page_check_references(struct page *page,
}
/* Reclaim if clean, defer dirty pages to writeback */
- if (referenced_page)
+ if (referenced_page && !PageSwapBacked(page))
return PAGEREF_RECLAIM_CLEAN;
return PAGEREF_RECLAIM;
@@ -1879,7 +1880,7 @@ out:
return sc->nr_reclaimed;
/* top priority shrink_zones still had more to do? don't OOM, then */
- if (scanning_global_lru(sc) && !all_unreclaimable)
+ if (scanning_global_lru(sc) && !all_unreclaimable && !oom_killer_disabled)
return 1;
return 0;
@@ -2395,6 +2396,7 @@ unsigned long zone_reclaimable_pages(struct zone *zone)
*/
unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
{
+ int i;
struct reclaim_state reclaim_state;
struct scan_control sc = {
.gfp_mask = GFP_HIGHUSER_MOVABLE,
@@ -2410,17 +2412,36 @@ unsigned long shrink_all_memory(unsigned long nr_to_reclaim)
struct task_struct *p = current;
unsigned long nr_reclaimed;
+ printk(KERN_ERR "shrink_all_memory start\n");
+
p->flags |= PF_MEMALLOC;
lockdep_set_current_reclaim_state(sc.gfp_mask);
reclaim_state.reclaimed_slab = 0;
p->reclaim_state = &reclaim_state;
- nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
+ for (i = 1; i <= 5; i++) {
+ nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
+
+ printk(KERN_INFO "PM: shrink memory: pass=%d, req:%ld reclaimed:%ld free:%ld\n",
+ i,
+ nr_to_reclaim,
+ nr_reclaimed,
+ global_page_state(NR_FREE_PAGES));
+
+ if (nr_to_reclaim <= nr_reclaimed)
+ break;
+ nr_to_reclaim -= nr_reclaimed;
+ }
p->reclaim_state = NULL;
lockdep_clear_current_reclaim_state();
p->flags &= ~PF_MEMALLOC;
+ printk(KERN_ERR "shrink_all_memory: req:%ld reclaimed:%ld free:%ld\n",
+ nr_to_reclaim,
+ nr_reclaimed,
+ global_page_state(NR_FREE_PAGES));
+
return nr_reclaimed;
}
#endif /* CONFIG_HIBERNATION */
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 7759941..bee3ba3 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -860,6 +860,33 @@ static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
zone->prev_priority,
zone->zone_start_pfn,
zone->inactive_ratio);
+
+ {
+ extern int vm_swappiness;
+ int anon_prio = vm_swappiness;
+ int file_prio = 200 - vm_swappiness;
+ unsigned long ap;
+ unsigned long fp;
+ struct zone_reclaim_stat *reclaim_stat = &zone->reclaim_stat;
+
+ ap = (anon_prio + 1) * (reclaim_stat->recent_scanned[0] + 1);
+ ap /= reclaim_stat->recent_rotated[0] + 1;
+ fp = (file_prio + 1) * (reclaim_stat->recent_scanned[1] + 1);
+ fp /= reclaim_stat->recent_rotated[1] + 1;
+
+ seq_printf(m,
+ "\n recent_anon_rotated: %lu"
+ "\n recent_anon_scanned: %lu"
+ "\n recent_file_rotated: %lu"
+ "\n recent_file_scanned: %lu"
+ "\n anon_ratio: %lu"
+ ,
+ zone->reclaim_stat.recent_rotated[0],
+ zone->reclaim_stat.recent_scanned[0],
+ zone->reclaim_stat.recent_rotated[1],
+ zone->reclaim_stat.recent_scanned[1],
+ (ap * 100) / (ap + fp +1));
+ }
seq_putc(m, '\n');
}
next prev parent reply other threads:[~2010-08-31 11:26 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-08-15 5:25 [Bisected Regression in 2.6.35] A full tmpfs filesystem causes hibernationto hang M. Vefa Bicakci
2010-08-17 2:37 ` KOSAKI Motohiro
2010-08-22 11:06 ` KOSAKI Motohiro
2010-08-22 16:28 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernation to hang M. Vefa Bicakci
2010-08-25 8:55 ` KOSAKI Motohiro
2010-08-25 10:11 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernationto hang M. Vefa Bicakci
2010-08-25 17:31 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernation to hang Rafael J. Wysocki
2010-08-23 0:22 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causes hibernationto hang KOSAKI Motohiro
2010-08-23 6:27 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernation to hang M. Vefa Bicakci
2010-08-25 0:48 ` KOSAKI Motohiro
2010-08-25 8:39 ` KOSAKI Motohiro
2010-08-25 10:10 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernationto hang M. Vefa Bicakci
[not found] ` <4C74EB70.3080406@superonline.com>
[not found] ` <20100826134506.F676.A69D9226@jp.fujitsu.com>
2010-08-26 10:36 ` M. Vefa Bicakci
2010-08-30 2:28 ` KOSAKI Motohiro
2010-08-30 16:54 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernation to hang M. Vefa Bicakci
2010-08-31 6:35 ` KOSAKI Motohiro
2010-08-31 6:54 ` KOSAKI Motohiro
2010-08-31 11:25 ` M. Vefa Bicakci [this message]
2010-09-01 0:48 ` KOSAKI Motohiro
2010-09-01 22:02 ` Rafael J. Wysocki
2010-09-02 0:31 ` KOSAKI Motohiro
2010-09-02 19:57 ` Rafael J. Wysocki
2010-09-02 20:24 ` Rafael J. Wysocki
2010-09-03 0:13 ` KOSAKI Motohiro
2010-09-03 1:07 ` Rafael J. Wysocki
2010-09-03 1:53 ` KOSAKI Motohiro
2010-09-04 1:44 ` Rafael J. Wysocki
2010-09-06 2:08 ` KOSAKI Motohiro
2010-09-06 11:27 ` Important news regarding the two different patches M. Vefa Bicakci
2010-09-06 18:43 ` Rafael J. Wysocki
2010-09-07 1:34 ` M. Vefa Bicakci
2010-09-07 1:58 ` KOSAKI Motohiro
2010-09-07 21:44 ` Rafael J. Wysocki
2010-09-08 12:56 ` M. Vefa Bicakci
2010-09-08 21:34 ` [PATCH] PM / Hibernate: Avoid hitting OOM during preallocation of memory (was: Re: Important news ...) Rafael J. Wysocki
2010-09-11 18:12 ` PATCH: PM / Hibernate: Avoid hitting OOM during preallocationof memory M. Vefa Bicakci
2010-09-11 19:06 ` Rafael J. Wysocki
2010-09-11 22:27 ` [PATCH] PM / Hibernate: Make default image size depend on total RAM size (was: Re: PATCH: PM / Hibernate: Avoid hitting OOM ...) Rafael J. Wysocki
2010-09-13 15:40 ` [PATCH] PM / Hibernate: Make default image size depend on totalRAM size M. Vefa Bicakci
2010-09-13 17:52 ` Rafael J. Wysocki
2010-09-06 18:46 ` [Bisected Regression in 2.6.35] A full tmpfs filesystem causeshibernation to hang Rafael J. Wysocki
2010-09-06 19:54 ` Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C7CE6BD.9040601@superonline.com \
--to=bicave@superonline.com \
--cc=kosaki.motohiro@jp.fujitsu.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox