Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282997
b: refs/heads/master
c: f90ac39
h: refs/heads/master
i:
  282995: 2ea35dd
v: v3
  • Loading branch information
Mel Gorman authored and Linus Torvalds committed Jan 11, 2012
1 parent 1002d1b commit 528e9f6
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 938929f14cb595f43cd1a4e63e22d36cab1e4a1f
refs/heads/master: f90ac3982a78d36f894824636beeef13361d7c59
16 changes: 16 additions & 0 deletions trunk/include/linux/gfp.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,25 @@ void drain_zone_pages(struct zone *zone, struct per_cpu_pages *pcp);
void drain_all_pages(void);
void drain_local_pages(void *dummy);

/*
* gfp_allowed_mask is set to GFP_BOOT_MASK during early boot to restrict what
* GFP flags are used before interrupts are enabled. Once interrupts are
* enabled, it is set to __GFP_BITS_MASK while the system is running. During
* hibernation, it is used by PM to avoid I/O during memory allocation while
* devices are suspended.
*/
extern gfp_t gfp_allowed_mask;

extern void pm_restrict_gfp_mask(void);
extern void pm_restore_gfp_mask(void);

#ifdef CONFIG_PM_SLEEP
extern bool pm_suspended_storage(void);
#else
static inline bool pm_suspended_storage(void)
{
return false;
}
#endif /* CONFIG_PM_SLEEP */

#endif /* __LINUX_GFP_H */
30 changes: 22 additions & 8 deletions trunk/mm/page_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@ void pm_restrict_gfp_mask(void)
saved_gfp_mask = gfp_allowed_mask;
gfp_allowed_mask &= ~GFP_IOFS;
}

bool pm_suspended_storage(void)
{
if ((gfp_allowed_mask & GFP_IOFS) == GFP_IOFS)
return false;
return true;
}
#endif /* CONFIG_PM_SLEEP */

#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
Expand Down Expand Up @@ -1786,12 +1793,25 @@ void warn_alloc_failed(gfp_t gfp_mask, int order, const char *fmt, ...)

static inline int
should_alloc_retry(gfp_t gfp_mask, unsigned int order,
unsigned long did_some_progress,
unsigned long pages_reclaimed)
{
/* Do not loop if specifically requested */
if (gfp_mask & __GFP_NORETRY)
return 0;

/* Always retry if specifically requested */
if (gfp_mask & __GFP_NOFAIL)
return 1;

/*
* Suspend converts GFP_KERNEL to __GFP_WAIT which can prevent reclaim
* making forward progress without invoking OOM. Suspend also disables
* storage devices so kswapd will not help. Bail if we are suspending.
*/
if (!did_some_progress && pm_suspended_storage())
return 0;

/*
* In this implementation, order <= PAGE_ALLOC_COSTLY_ORDER
* means __GFP_NOFAIL, but that may not be true in other
Expand All @@ -1810,13 +1830,6 @@ should_alloc_retry(gfp_t gfp_mask, unsigned int order,
if (gfp_mask & __GFP_REPEAT && pages_reclaimed < (1 << order))
return 1;

/*
* Don't let big-order allocations loop unless the caller
* explicitly requests that.
*/
if (gfp_mask & __GFP_NOFAIL)
return 1;

return 0;
}

Expand Down Expand Up @@ -2209,7 +2222,8 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,

/* Check if we should retry the allocation */
pages_reclaimed += did_some_progress;
if (should_alloc_retry(gfp_mask, order, pages_reclaimed)) {
if (should_alloc_retry(gfp_mask, order, did_some_progress,
pages_reclaimed)) {
/* Wait for some write requests to complete then retry */
wait_iff_congested(preferred_zone, BLK_RW_ASYNC, HZ/50);
goto rebalance;
Expand Down
6 changes: 3 additions & 3 deletions trunk/mm/swapfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -667,10 +667,10 @@ int try_to_free_swap(struct page *page)
* original page might be freed under memory pressure, then
* later read back in from swap, now with the wrong data.
*
* Hibernation clears bits from gfp_allowed_mask to prevent
* memory reclaim from writing to disk, so check that here.
* Hibration suspends storage while it is writing the image
* to disk so check that here.
*/
if (!(gfp_allowed_mask & __GFP_IO))
if (pm_suspended_storage())
return 0;

delete_from_swap_cache(page);
Expand Down

0 comments on commit 528e9f6

Please sign in to comment.