Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 167851
b: refs/heads/master
c: e43c3af
h: refs/heads/master
i:
  167849: 4387efb
  167847: eb241d3
v: v3
  • Loading branch information
Wu Fengguang authored and Andi Kleen committed Oct 19, 2009
1 parent 8ac4c74 commit 24175a7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 26 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: f58ee00f1547ceb17b610ecfce2aa9097f1f9737
refs/heads/master: e43c3afb367112a5b357f9adfac7817255129c88
49 changes: 24 additions & 25 deletions trunk/mm/memory-failure.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,6 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)
int ret = FAILED;
struct address_space *mapping;

if (!isolate_lru_page(p))
page_cache_release(p);

/*
* For anonymous pages we're done the only reference left
* should be the one m_f() holds.
Expand Down Expand Up @@ -498,30 +495,18 @@ static int me_pagecache_dirty(struct page *p, unsigned long pfn)
*/
static int me_swapcache_dirty(struct page *p, unsigned long pfn)
{
int ret = FAILED;

ClearPageDirty(p);
/* Trigger EIO in shmem: */
ClearPageUptodate(p);

if (!isolate_lru_page(p)) {
page_cache_release(p);
ret = DELAYED;
}

return ret;
return DELAYED;
}

static int me_swapcache_clean(struct page *p, unsigned long pfn)
{
int ret = FAILED;

if (!isolate_lru_page(p)) {
page_cache_release(p);
ret = RECOVERED;
}
delete_from_swap_cache(p);
return ret;

return RECOVERED;
}

/*
Expand Down Expand Up @@ -611,8 +596,6 @@ static struct page_state {
{ 0, 0, "unknown page state", me_unknown },
};

#undef lru

static void action_result(unsigned long pfn, char *msg, int result)
{
struct page *page = NULL;
Expand Down Expand Up @@ -664,9 +647,6 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,
if (PageReserved(p) || PageCompound(p) || PageSlab(p))
return;

if (!PageLRU(p))
lru_add_drain_all();

/*
* This check implies we don't kill processes if their pages
* are in the swap cache early. Those are always late kills.
Expand Down Expand Up @@ -738,6 +718,7 @@ static void hwpoison_user_mappings(struct page *p, unsigned long pfn,

int __memory_failure(unsigned long pfn, int trapno, int ref)
{
unsigned long lru_flag;
struct page_state *ps;
struct page *p;
int res;
Expand Down Expand Up @@ -774,6 +755,24 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
return PageBuddy(compound_head(p)) ? 0 : -EBUSY;
}

/*
* We ignore non-LRU pages for good reasons.
* - PG_locked is only well defined for LRU pages and a few others
* - to avoid races with __set_page_locked()
* - to avoid races with __SetPageSlab*() (and more non-atomic ops)
* The check (unnecessarily) ignores LRU pages being isolated and
* walked by the page reclaim code, however that's not a big loss.
*/
if (!PageLRU(p))
lru_add_drain_all();
lru_flag = p->flags & lru;
if (isolate_lru_page(p)) {
action_result(pfn, "non LRU", IGNORED);
put_page(p);
return -EBUSY;
}
page_cache_release(p);

/*
* Lock the page and wait for writeback to finish.
* It's very difficult to mess with pages currently under IO
Expand All @@ -790,15 +789,15 @@ int __memory_failure(unsigned long pfn, int trapno, int ref)
/*
* Torn down by someone else?
*/
if (PageLRU(p) && !PageSwapCache(p) && p->mapping == NULL) {
if ((lru_flag & lru) && !PageSwapCache(p) && p->mapping == NULL) {
action_result(pfn, "already truncated LRU", IGNORED);
res = 0;
goto out;
}

res = -EBUSY;
for (ps = error_states;; ps++) {
if ((p->flags & ps->mask) == ps->res) {
if (((p->flags | lru_flag)& ps->mask) == ps->res) {
res = page_action(ps, p, pfn, ref);
break;
}
Expand Down

0 comments on commit 24175a7

Please sign in to comment.