diff mbox series

[04/10] mm/khugepaged: collapse_shmem() stop if punched or truncated

Message ID alpine.LSU.2.11.1811261522040.2275@eggly.anvils (mailing list archive)
State New, archived
Headers show
Series huge_memory,khugepaged tmpfs split/collapse fixes | expand

Commit Message

Hugh Dickins Nov. 26, 2018, 11:23 p.m. UTC
Huge tmpfs testing showed that although collapse_shmem() recognizes a
concurrently truncated or hole-punched page correctly, its handling of
holes was liable to refill an emptied extent.  Add check to stop that.

Fixes: f3f0e1d2150b2 ("khugepaged: add support of collapse for tmpfs/shmem pages")
Signed-off-by: Hugh Dickins <hughd@google.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: stable@vger.kernel.org # 4.8+
---
 mm/khugepaged.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

Comments

Kirill A. Shutemov Nov. 27, 2018, 7:31 a.m. UTC | #1
On Mon, Nov 26, 2018 at 03:23:37PM -0800, Hugh Dickins wrote:
> Huge tmpfs testing showed that although collapse_shmem() recognizes a
> concurrently truncated or hole-punched page correctly, its handling of
> holes was liable to refill an emptied extent.  Add check to stop that.
> 
> Fixes: f3f0e1d2150b2 ("khugepaged: add support of collapse for tmpfs/shmem pages")
> Signed-off-by: Hugh Dickins <hughd@google.com>
> Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
> Cc: stable@vger.kernel.org # 4.8+

I'm not yet comfortable with XArray API. Matthew, what is your take on the patch?

> ---
>  mm/khugepaged.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index c13625c1ad5e..2070c316f06e 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -1359,6 +1359,17 @@ static void collapse_shmem(struct mm_struct *mm,
>  
>  		VM_BUG_ON(index != xas.xa_index);
>  		if (!page) {
> +			/*
> +			 * Stop if extent has been truncated or hole-punched,
> +			 * and is now completely empty.
> +			 */
> +			if (index == start) {
> +				if (!xas_next_entry(&xas, end - 1)) {
> +					result = SCAN_TRUNCATED;
> +					break;
> +				}
> +				xas_set(&xas, index);
> +			}
>  			if (!shmem_charge(mapping->host, 1)) {
>  				result = SCAN_FAIL;
>  				break;
> -- 
> 2.20.0.rc0.387.gc7a69e6b6c-goog
>
Matthew Wilcox Nov. 27, 2018, 1:26 p.m. UTC | #2
On Mon, Nov 26, 2018 at 03:23:37PM -0800, Hugh Dickins wrote:
>  		VM_BUG_ON(index != xas.xa_index);
>  		if (!page) {
> +			/*
> +			 * Stop if extent has been truncated or hole-punched,
> +			 * and is now completely empty.
> +			 */
> +			if (index == start) {
> +				if (!xas_next_entry(&xas, end - 1)) {
> +					result = SCAN_TRUNCATED;
> +					break;
> +				}
> +				xas_set(&xas, index);
> +			}
>  			if (!shmem_charge(mapping->host, 1)) {

Reviewed-by: Matthew Wilcox <willy@infradead.org>

I'd use xas_find() directly here; I don't think it warrants the inlined
version of xas_next_entry().  But I'm happy either way.
diff mbox series

Patch

diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index c13625c1ad5e..2070c316f06e 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1359,6 +1359,17 @@  static void collapse_shmem(struct mm_struct *mm,
 
 		VM_BUG_ON(index != xas.xa_index);
 		if (!page) {
+			/*
+			 * Stop if extent has been truncated or hole-punched,
+			 * and is now completely empty.
+			 */
+			if (index == start) {
+				if (!xas_next_entry(&xas, end - 1)) {
+					result = SCAN_TRUNCATED;
+					break;
+				}
+				xas_set(&xas, index);
+			}
 			if (!shmem_charge(mapping->host, 1)) {
 				result = SCAN_FAIL;
 				break;