All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Sergey Senozhatsky" <senozhatsky@chromium.org>,
	"Andrew Morton" <akpm@linux-foundation.org>
Cc: "Nhat Pham" <nphamcs@gmail.com>,
	"Yosry Ahmed" <yosry.ahmed@linux.dev>,
	"Johannes Weiner" <hannes@cmpxchg.org>,
	"Brian Geffon" <bgeffon@google.com>,
	"Minchan Kim" <minchan@kernel.org>,
	"Richard Chang" <richardycc@google.com>,
	linux-mm@kvack.org
Subject: Re: [PATCH 4/7] zram: allocate zsmalloc object under slot lock
Date: Fri, 06 Nov 2026 04:48:41 +0000	[thread overview]
Message-ID: <sashiko-outbox-200764@kernel.org> (raw)
In-Reply-To: <20261105044752.1997895-5-senozhatsky@chromium.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] zram: data loss on write failure after slot_free() in zram_write_page()
--

commit e7f04891f4b67054972cd177192ff9867fcbceb7
Author: Sergey Senozhatsky <senozhatsky@chromium.org>

zram: allocate zsmalloc object under slot lock

This commit moves slot_lock() and slot_free() before zs_malloc() in
write_incompressible_page() and zram_write_page() so that the old slot is
freed under the slot lock prior to allocating a new zsmalloc object.

> diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
> index 2c2e11b2b6638..e2710ce35b1f5 100644
> --- a/drivers/block/zram/zram_drv.c
> +++ b/drivers/block/zram/zram_drv.c
> @@ -2260,14 +2260,19 @@ static int write_incompressible_page(struct zram *zram, struct page *page,
>  	struct zs_handle *handle;
>  	void *src;
>  
> +	slot_lock(zram, index);
> +	slot_free(zram, index);
>  	handle = zs_malloc(zram->mem_pool, PAGE_SIZE,
>  			   GFP_NOIO | __GFP_NOWARN |
>  			   __GFP_HIGHMEM | __GFP_MOVABLE, page_to_nid(page));
> -	if (IS_ERR(handle))
> +	if (IS_ERR(handle)) {
> +		slot_unlock(zram, index);
>  		return PTR_ERR(handle);
> +	}
>  
>  	if (!zram_can_store_page(zram)) {
>  		zs_free(zram->mem_pool, handle);
> +		slot_unlock(zram, index);
>  		return -ENOMEM;
>  	}
>  
> @@ -2275,8 +2280,6 @@ static int write_incompressible_page(struct zram *zram, struct page *page,
>  	zs_obj_write(zram->mem_pool, handle, src, PAGE_SIZE);
>  	kunmap_local(src);
>  
> -	slot_lock(zram, index);
> -	slot_free(zram, index);
>  	set_slot_flag(zram, index, ZRAM_HUGE);
>  	zram->table[index].handle = handle;
>  	set_slot_size(zram, index, PAGE_SIZE);
> @@ -2325,25 +2328,27 @@ static int zram_write_page(struct zram *zram, struct page *page,
>  		return write_incompressible_page(zram, page, index);
>  	}
>  
> +	slot_lock(zram, index);
> +	slot_free(zram, index);
>  	handle = zs_malloc(zram->mem_pool, comp_len,
>  			   GFP_NOIO | __GFP_NOWARN |
>  			   __GFP_HIGHMEM | __GFP_MOVABLE, page_to_nid(page));
>  	if (IS_ERR(handle)) {
>  		zcomp_cstrm_put(zstrm);
> +		slot_unlock(zram, index);
>  		return PTR_ERR(handle);
>  	}
>  
>  	if (!zram_can_store_page(zram)) {
>  		zcomp_cstrm_put(zstrm);
>  		zs_free(zram->mem_pool, handle);
> +		slot_unlock(zram, index);
>  		return -ENOMEM;
>  	}

[Severity: Critical]
Does calling slot_free() before zs_malloc() and zram_can_store_page() in
write_incompressible_page() and zram_write_page() cause existing data in the
slot to be lost if the allocation or memory limit check fails?

Previously, both functions allocated and populated the new handle before
calling slot_free(zram, index), so a failed write left the old slot contents
intact. With slot_free() called first, the existing handle (or backing device
block when ZRAM_WB is set, or ZRAM_SAME entry) is freed and
zram->table[index].element is reset to 0 before the new allocation is
attempted.

If zs_malloc() fails under GFP_NOIO memory pressure or zram_can_store_page()
returns false because zram->limit_pages is exceeded, the write returns an
error while leaving the slot empty. Subsequent reads via read_from_zspool()
then see !zram->table[index].handle:

drivers/block/zram/zram_drv.c:read_from_zspool() {
	if (test_slot_flag(zram, index, ZRAM_SAME) ||
	    !zram->table[index].handle)
		return read_same_filled_page(zram, page, index);
}

and silently return a zero-filled page instead of the previous data.

Additionally, on systems with PAGE_SIZE > 4096, a single slot holds multiple
4KB logical blocks, and partial writes go through zram_bvec_write_partial():

drivers/block/zram/zram_drv.c:zram_bvec_write_partial() {
	ret = zram_read_page(zram, page, index, NULL);
	if (!ret) {
		memcpy_from_bvec(page_address(page) + offset, bvec);
		ret = zram_write_page(zram, page, index);
	}
}

If zram_write_page() fails after slot_free() here, wouldn't that also wipe
out all the other unmodified 4KB logical blocks sharing the same PAGE_SIZE
slot?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261105044752.1997895-1-senozhatsky@chromium.org?part=4


  reply	other threads:[~2026-11-06  4:48 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-05  4:47 [PATCH 0/7] zsmalloc: redesign object alloc API Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 1/7] zram: drop stale comment in write_incompressible_page() Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 2/7] zram: drop get_slot_handle() and set_slot_handle() Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 3/7] zsmalloc: switch handle type to struct zs_handle Sergey Senozhatsky
2026-11-05 17:03   ` Yosry Ahmed
2026-11-10  2:42     ` Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 4/7] zram: allocate zsmalloc object under slot lock Sergey Senozhatsky
2026-11-06  4:48   ` sashiko-bot [this message]
2026-11-10  3:01     ` Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 5/7] zsmalloc: embed struct zs_handle into zram and zswap entries Sergey Senozhatsky
2026-11-05 17:19   ` Yosry Ahmed
2026-11-10  2:51     ` Sergey Senozhatsky
2026-11-10  3:12       ` Sergey Senozhatsky
2026-11-05 17:30   ` Yosry Ahmed
2026-11-10  2:44     ` Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 6/7] zsmalloc: fold zs_obj_write() into zs_store() Sergey Senozhatsky
2026-11-05 17:29   ` Yosry Ahmed
2026-11-10  2:45     ` Sergey Senozhatsky
2026-11-10  5:09       ` Sergey Senozhatsky
2026-11-05  4:47 ` [PATCH 7/7] zsmalloc: constify struct zs_handle pointer in read-only functions Sergey Senozhatsky
2026-11-05 17:31 ` [PATCH 0/7] zsmalloc: redesign object alloc API Yosry Ahmed
2026-11-05 17:36   ` Nhat Pham
2026-11-05 17:39     ` Yosry Ahmed
2026-11-10  5:49       ` Sergey Senozhatsky

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=sashiko-outbox-200764@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=bgeffon@google.com \
    --cc=hannes@cmpxchg.org \
    --cc=linux-mm@kvack.org \
    --cc=minchan@kernel.org \
    --cc=nphamcs@gmail.com \
    --cc=richardycc@google.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=senozhatsky@chromium.org \
    --cc=yosry.ahmed@linux.dev \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.