diff options
Diffstat (limited to 'mm/memory-failure.c')
| -rw-r--r-- | mm/memory-failure.c | 14 | 
1 files changed, 10 insertions, 4 deletions
diff --git a/mm/memory-failure.c b/mm/memory-failure.c index eefd823deb67..e1f87cf13235 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -866,7 +866,7 @@ static int me_pagecache_clean(struct page *p, unsigned long pfn)  	/*  	 * Truncation is a bit tricky. Enable it per file system for now.  	 * -	 * Open: to take i_mutex or not for this? Right now we don't. +	 * Open: to take i_rwsem or not for this? Right now we don't.  	 */  	ret = truncate_error_page(p, pfn, mapping);  out: @@ -1146,7 +1146,7 @@ static int __get_hwpoison_page(struct page *page)  	 * unexpected races caused by taking a page refcount.  	 */  	if (!HWPoisonHandlable(head)) -		return 0; +		return -EBUSY;  	if (PageTransHuge(head)) {  		/* @@ -1199,9 +1199,15 @@ try_again:  			}  			goto out;  		} else if (ret == -EBUSY) { -			/* We raced with freeing huge page to buddy, retry. */ -			if (pass++ < 3) +			/* +			 * We raced with (possibly temporary) unhandlable +			 * page, retry. +			 */ +			if (pass++ < 3) { +				shake_page(p, 1);  				goto try_again; +			} +			ret = -EIO;  			goto out;  		}  	}  | 
