From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 893B8C28B30 for ; Wed, 26 Mar 2025 04:03:19 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6C028280059; Wed, 26 Mar 2025 00:03:17 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 66F69280056; Wed, 26 Mar 2025 00:03:17 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5116B280059; Wed, 26 Mar 2025 00:03:17 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 2EDC2280056 for ; Wed, 26 Mar 2025 00:03:17 -0400 (EDT) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 257D7BAEFD for ; Wed, 26 Mar 2025 04:03:18 +0000 (UTC) X-FDA: 83262357276.15.79DB9D4 Received: from mail-pl1-f170.google.com (mail-pl1-f170.google.com [209.85.214.170]) by imf06.hostedemail.com (Postfix) with ESMTP id 2467D18000F for ; Wed, 26 Mar 2025 04:03:15 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Cs7l0VLj; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of richardycc@google.com designates 209.85.214.170 as permitted sender) smtp.mailfrom=richardycc@google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1742961796; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=qwNtDSof3cHXFHVcfHNPtdaXTxRkadKyo1hZxNKgJvE=; b=a+HtcNRnkXdWW1KNCUzUqqt2WJbvzHdM+4C7Jg0HOc7fZRYMFrIKE1b+9LGzPDyFBg27/b RStUEOBjfwuRcrEGJjUcO+7L2XVOWjlU5+hVq61ECdSRl7pdNELDtSRBuvXYP4UtHdmYPk wHnowXSnOAPHgjj6IfP/4LkDkSa9syI= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=google.com header.s=20230601 header.b=Cs7l0VLj; dmarc=pass (policy=reject) header.from=google.com; spf=pass (imf06.hostedemail.com: domain of richardycc@google.com designates 209.85.214.170 as permitted sender) smtp.mailfrom=richardycc@google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1742961796; a=rsa-sha256; cv=none; b=Qy8HKlgJGojXgI8U1SNqHv3JogBmxNcg+TiTsFzz4ruwZPlV9EIGdBcN9Dd1l/vFhus+TZ 2YKaWCR3U90gU0LtA+8sB8ZdAoMn4FM8MLHJrbp85JXIIbIyMFff6yehqNjRgP208lDIHT gx3WqEhpWDRLlzx2FoxUtZnNHHixr5E= Received: by mail-pl1-f170.google.com with SMTP id d9443c01a7336-2263428c8baso85185ad.1 for ; Tue, 25 Mar 2025 21:03:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1742961795; x=1743566595; darn=kvack.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=qwNtDSof3cHXFHVcfHNPtdaXTxRkadKyo1hZxNKgJvE=; b=Cs7l0VLjTFeayvJ9KXvdWuTkjUrv6XuL7kqkJoxIgBatAlCw+E5dlbKDfPmkJOWu5K OOiHgqebcKfOyMUAUVT+aHiEP3gPtHrLvjYhOXa48eO0aS7Gd2kGLdBNT8mbsZT5Us8g FvAhPXwxXT465anypFLk0N6Ndo29Iv9Jzm0gI4/oh/Rq3Q1MXXiDUnwH6/ST+AhC9IFH 8ein305oQSNJFLi0JVOLCzrxCScLatGVu7CMVS3LD3aVz61WEu8o6pkl/ECPcGdSxY6l 79Qy61Y+JmUgzvZ4TLUDQ0EcKw0JBSPpX/bYUGqOuLTNuDSXaIkEd5+77lht4DGzAdG4 oOwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742961795; x=1743566595; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qwNtDSof3cHXFHVcfHNPtdaXTxRkadKyo1hZxNKgJvE=; b=PwYTEFcZr1pue5CTCwxVnrR9463hfFrj8DDG6G0RBxwA4jxY4nHBxWUrG3K2O+2pB2 UVINfwDX79fGjRmqMzXkvtidHBSleFelRElffAQkOHG8f9lo+/NyTkBHOZF2p5J1gv8f Kcd42xgv2Nn6YoCnNe7eyCA8oI+I4rAIsf2Ok31x/urlSX/QnIobrzfZdN6lzFQpcREq jR3eJ+aRi5MOQsT6oiBdZz96mTHtbX/t7VIHlNqGdVEG28sznlWhuU05PJ6ice0GRrDk HfbVuo4k2M5WNStaOSeo/wqH8E/1kjlx/3DYbb6h7mD2McCSnQNJVByT5Ja63A7UMi4/ w/AQ== X-Forwarded-Encrypted: i=1; AJvYcCX1Lffxt/7lY178z6Pv9/BcuUjUlFJY9oHQa0iT/L9GIlfgaEir6LJlqTpVftAQoQDPiH3uDRYfkA==@kvack.org X-Gm-Message-State: AOJu0YxCUXfrCwpXgbQd+MvDUYMD1OiBPLm0RRxGn0eHrJb8otod5C3h 09EKMrjXwwD+pp7kyQ2Pl87KWlfbWc3EB6EW4pHSpLOG149r1ytb9/ygH6xrVcO8xuWANGxsifB QqUpyEuM5YOJ673xrpZLtHbYt8PqPtr8lX3w= X-Gm-Gg: ASbGncsRxGp+0kTzgJwHvD9ounYvQSrymSmNODa+xkFO+JFwVQUmLYxI5F/UQFyfuiI Y3zxQP1UXjUoIMjDzH/zuJceDqMqxVhYT7+mffrYci71VvUBoFOMD8x2D8CrH0ooUgsILphliGI lF09ksPJceeXYId6YXTufue0738Gy8IEKgffFaRDmFGGnu3jwzBNTzENU= X-Google-Smtp-Source: AGHT+IH15nHM32sadtbp7RdLa4dNsA2koMfipOSAHMIQKQSQ+vzPQ5l8QXWN7pMwJHsvxTNXsDBxdK45REfcIuP+css= X-Received: by 2002:a17:902:c94f:b0:21f:3f5c:d24c with SMTP id d9443c01a7336-227f3395b21mr792355ad.0.1742961794337; Tue, 25 Mar 2025 21:03:14 -0700 (PDT) MIME-Version: 1.0 References: <20250325034210.3337080-1-senozhatsky@chromium.org> In-Reply-To: From: Richard Chang Date: Wed, 26 Mar 2025 12:03:01 +0800 X-Gm-Features: AQ5f1Jrhoxq3b1PQNHYaqAX9y8uQmHyyoefKyW9Afpy38YjPwTCRerZefhpdKWA Message-ID: Subject: Re: [PATCH] zram: modernize writeback interface To: Minchan Kim Cc: Sergey Senozhatsky , Andrew Morton , Brian Geffon , linux-mm@kvack.org, linux-kernel@vger.kernel.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Rspamd-Server: rspam11 X-Rspamd-Queue-Id: 2467D18000F X-Stat-Signature: bub9fquytcyubfz6oy1z4gcyt6dyteg6 X-Rspam-User: X-HE-Tag: 1742961795-636318 X-HE-Meta: U2FsdGVkX18zEsQlZAC3jldRbXmIGjFcxTK7UseLy/IRa4Dh0Tt9Syps0q3dL/51YDhsXEiieRBFl8egFAFOjHUVn2YcmYocTrUhviGlEVei/ABz20alfYLouYf6qMzQCmtudsR8I7DXIcgJsbt0PtRSZxFjwO568EndUrB2ycNXlY4ZRBPzUAIdI5nifC412vddGrkE29/GW9cYxitEtrG8nDpXL1mY47RbuAspxqVvSGkQjUE81e6OUfYhEoAAkgg9VnH9SHtDABez9jk6ePvqL9dXoD2bTwf1Cd4f/M10TuyZ2krVMSFK2X2x7urm1wiy64+k9ZXPJ9Ni9XMG47WY3TRI7WBIBDyii68WSBD6W+YFU+GVz+U8AaACxTnHI6FrcnqnoFYrEaXcjvwZNCizqP9hJ0X6+nZlhBAmFj+MgTu9okxgwnT2cCXJ8HtlBNv6mah31vXRjPZj1F2i6NFMAsvZPahby6fasx6OM6VRFojUPJJVefYTj7jiBVVxvXDW1e5P/HYQRoDpNQyuM23qujecIelXaZo0cS4TCBalM8pozRxCZ0oTqhlQQu6vQKu1fOqEvSUHhkX9/y8rit+r5pSanAJcNK5too62V8krHeZQHhZ/CbCkOkRlZ5JFxFECFYkfnsl4kVXq4rtQKJcfvOO1di1QUafoWa3HCKRciiw5wvMOvhVgFJYmvvoPjK5hdUKWRtL2KlBm4IwZinJ/Afcy/mYDPymgUjh4lQzp9J5zVJc5aSsSa19L289h59zJIcVyrJu968tr7Kz6mcdNT+yn1ONzD2Gfu0N1fK1hhZaOlqb859cvruqUoB8CWTOY/pzyETHW9B83DlAKapsd42D/UlcFpcZNkhezb+yloGpgWG2v30LwSRRlbWoCTAM9hP2Sshw/hPhsGE5TZe3wbqnlGP8ueHuX15b+1hYubxv+afqEMY9X/O2MSR4GgvkdQ2XqCFtJp74tRRI Ic+TmaqG qLKShXqMuNIW4dCedjxo7mzi+oARciphlKaQvYkrfSC7kXWfyckad83u0Yp/C9nSM4Ho36GX89mXPIvR4VN00/UNFiCMnrl5evZswyUXH3tZGtomezqclprYYlpTK1C970KA29m3dxIwTTLM+HX6626eZRgKSmv9vp/AR6JNsyHHsTv2wL/rU8sOCvR/Nvs+CmvGwW1LV62P2pkBuXayw6o/mvSz2pgLzKs2rcEjeXv7xs9WPKzOkso4BM5ztf3mPDPJY X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Hi Sergey, Since the input buffer length is only PAGE_SIZE long, can we reduce the duplicated "page_index_range=3D" strings? Eg: Turn echo page_index_range=3D100-200 \ page_index_range=3D500-700 > zram0/writeback To: echo page_index_range=3D100-200,500-700 > zram0/writeback On Wed, Mar 26, 2025 at 5:52=E2=80=AFAM Minchan Kim wr= ote: > > Ccing richardycc@google.com since he has working on this: > > On Tue, Mar 25, 2025 at 12:42:04PM +0900, Sergey Senozhatsky wrote: > > The writeback interface supports a page_index=3DN parameter which > > performs writeback of the given page. Since we rarely need to > > writeback just one single page, the typical use case involves > > a number of writeback calls, each performing writeback of one > > page: > > > > echo page_index=3D100 > zram0/writeback > > ... > > echo page_index=3D200 > zram0/writeback > > echo page_index=3D500 > zram0/writeback > > ... > > echo page_index=3D700 > zram0/writeback > > > > One obvious downside of this is that it increases the number of > > syscalls. Less obvious, but a significantly more important downside, > > is that when given only one page to post-process zram cannot perform > > an optimal target selection. This becomes a critical limitation > > when writeback_limit is enabled, because under writeback_limit we > > want to guarantee the highest memory savings hence we first need > > to writeback pages that release the highest amount of zsmalloc pool > > memory. > > > > This patch adds page_index_range=3DLOW-HIGH parameter to the writeback > > interface: > > > > echo page_index_range=3D100-200 \ > > page_index_range=3D500-700 > zram0/writeback > > > > This gives zram a chance to apply an optimal target selection > > strategy on each iteration of the writeback loop. > > > > Apart from that the patch also unifies parameters passing and resembles > > other "modern" zram device attributes (e.g. recompression), while the > > old interface used a mixed scheme: values-less parameters for mode and > > a key=3Dvalue format for page_index. We still support the "old" value-= less > > format for compatibility reasons. > > > > Signed-off-by: Sergey Senozhatsky > > --- > > Documentation/admin-guide/blockdev/zram.rst | 11 + > > drivers/block/zram/zram_drv.c | 321 +++++++++++++------- > > 2 files changed, 227 insertions(+), 105 deletions(-) > > > > diff --git a/Documentation/admin-guide/blockdev/zram.rst b/Documentatio= n/admin-guide/blockdev/zram.rst > > index 9bdb30901a93..9dca86365a4d 100644 > > --- a/Documentation/admin-guide/blockdev/zram.rst > > +++ b/Documentation/admin-guide/blockdev/zram.rst > > @@ -369,6 +369,17 @@ they could write a page index into the interface:: > > > > echo "page_index=3D1251" > /sys/block/zramX/writeback > > > > +In Linux 6.16 this interface underwent some rework. First, the interf= ace > > +now supports `key=3Dvalue` format for all of its parameters (`type=3Dh= uge_idle`, > > +etc.) Second, the support for `page_index_range` was introduced, whic= h > > +specify `LOW-HIGH` range (or ranges) of pages to be written-back. Thi= s > > +reduces the number of syscalls, but more importantly this enables opti= mal > > +post-processing target selection strategy. Usage example:: > > + > > + echo "type=3Didle" > /sys/block/zramX/writeback > > + echo "page_index_range=3D1-100 page_index_range=3D200-300" > \ > > + /sys/block/zramX/writeback > > + > > If there are lots of write IO with flash device, potentially, it has > > flash wearout problem so that admin needs to design write limitation > > to guarantee storage health for entire product life. > > diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_dr= v.c > > index fda7d8624889..2c39d12bd2d4 100644 > > --- a/drivers/block/zram/zram_drv.c > > +++ b/drivers/block/zram/zram_drv.c > > @@ -734,114 +734,19 @@ static void read_from_bdev_async(struct zram *zr= am, struct page *page, > > submit_bio(bio); > > } > > > > -#define PAGE_WB_SIG "page_index=3D" > > - > > -#define PAGE_WRITEBACK 0 > > -#define HUGE_WRITEBACK (1<<0) > > -#define IDLE_WRITEBACK (1<<1) > > -#define INCOMPRESSIBLE_WRITEBACK (1<<2) > > - > > -static int scan_slots_for_writeback(struct zram *zram, u32 mode, > > - unsigned long nr_pages, > > - unsigned long index, > > - struct zram_pp_ctl *ctl) > > +static int zram_writeback_slots(struct zram *zram, struct zram_pp_ctl = *ctl) > > { > > - for (; nr_pages !=3D 0; index++, nr_pages--) { > > - bool ok =3D true; > > - > > - zram_slot_lock(zram, index); > > - if (!zram_allocated(zram, index)) > > - goto next; > > - > > - if (zram_test_flag(zram, index, ZRAM_WB) || > > - zram_test_flag(zram, index, ZRAM_SAME)) > > - goto next; > > - > > - if (mode & IDLE_WRITEBACK && > > - !zram_test_flag(zram, index, ZRAM_IDLE)) > > - goto next; > > - if (mode & HUGE_WRITEBACK && > > - !zram_test_flag(zram, index, ZRAM_HUGE)) > > - goto next; > > - if (mode & INCOMPRESSIBLE_WRITEBACK && > > - !zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) > > - goto next; > > - > > - ok =3D place_pp_slot(zram, ctl, index); > > -next: > > - zram_slot_unlock(zram, index); > > - if (!ok) > > - break; > > - } > > - > > - return 0; > > -} > > - > > -static ssize_t writeback_store(struct device *dev, > > - struct device_attribute *attr, const char *buf, size_t le= n) > > -{ > > - struct zram *zram =3D dev_to_zram(dev); > > - unsigned long nr_pages =3D zram->disksize >> PAGE_SHIFT; > > - struct zram_pp_ctl *ctl =3D NULL; > > + unsigned long blk_idx =3D 0; > > + struct page *page =3D NULL; > > struct zram_pp_slot *pps; > > - unsigned long index =3D 0; > > - struct bio bio; > > struct bio_vec bio_vec; > > - struct page *page =3D NULL; > > - ssize_t ret =3D len; > > - int mode, err; > > - unsigned long blk_idx =3D 0; > > - > > - if (sysfs_streq(buf, "idle")) > > - mode =3D IDLE_WRITEBACK; > > - else if (sysfs_streq(buf, "huge")) > > - mode =3D HUGE_WRITEBACK; > > - else if (sysfs_streq(buf, "huge_idle")) > > - mode =3D IDLE_WRITEBACK | HUGE_WRITEBACK; > > - else if (sysfs_streq(buf, "incompressible")) > > - mode =3D INCOMPRESSIBLE_WRITEBACK; > > - else { > > - if (strncmp(buf, PAGE_WB_SIG, sizeof(PAGE_WB_SIG) - 1)) > > - return -EINVAL; > > - > > - if (kstrtol(buf + sizeof(PAGE_WB_SIG) - 1, 10, &index) || > > - index >=3D nr_pages) > > - return -EINVAL; > > - > > - nr_pages =3D 1; > > - mode =3D PAGE_WRITEBACK; > > - } > > - > > - down_read(&zram->init_lock); > > - if (!init_done(zram)) { > > - ret =3D -EINVAL; > > - goto release_init_lock; > > - } > > - > > - /* Do not permit concurrent post-processing actions. */ > > - if (atomic_xchg(&zram->pp_in_progress, 1)) { > > - up_read(&zram->init_lock); > > - return -EAGAIN; > > - } > > - > > - if (!zram->backing_dev) { > > - ret =3D -ENODEV; > > - goto release_init_lock; > > - } > > + struct bio bio; > > + int ret, err; > > + u32 index; > > > > page =3D alloc_page(GFP_KERNEL); > > - if (!page) { > > - ret =3D -ENOMEM; > > - goto release_init_lock; > > - } > > - > > - ctl =3D init_pp_ctl(); > > - if (!ctl) { > > - ret =3D -ENOMEM; > > - goto release_init_lock; > > - } > > - > > - scan_slots_for_writeback(zram, mode, nr_pages, index, ctl); > > + if (!page) > > + return -ENOMEM; > > > > while ((pps =3D select_pp_slot(ctl))) { > > spin_lock(&zram->wb_limit_lock); > > @@ -929,10 +834,216 @@ static ssize_t writeback_store(struct device *de= v, > > > > if (blk_idx) > > free_block_bdev(zram, blk_idx); > > - > > -release_init_lock: > > if (page) > > __free_page(page); > > + > > + return ret; > > +} > > + > > +#define PAGE_WRITEBACK 0 > > +#define HUGE_WRITEBACK (1 << 0) > > +#define IDLE_WRITEBACK (1 << 1) > > +#define INCOMPRESSIBLE_WRITEBACK (1 << 2) > > + > > +static int parse_page_index(char *val, unsigned long nr_pages, > > + unsigned long *lo, unsigned long *hi) > > +{ > > + int ret; > > + > > + ret =3D kstrtoul(val, 10, lo); > > + if (ret) > > + return ret; > > + *hi =3D *lo + 1; > > + if (*lo >=3D nr_pages || *hi > nr_pages) > > + return -ERANGE; > > + return 0; > > +} > > + > > +static int parse_page_index_range(char *val, unsigned long nr_pages, > > + unsigned long *lo, unsigned long *hi) > > +{ > > + char *delim; > > + int ret; > > + > > + delim =3D strchr(val, '-'); > > + if (!delim) > > + return -EINVAL; > > + > > + *delim =3D 0x00; > > + ret =3D kstrtoul(val, 10, lo); > > + if (ret) > > + return ret; > > + if (*lo >=3D nr_pages) > > + return -ERANGE; > > + > > + ret =3D kstrtoul(delim + 1, 10, hi); > > + if (ret) > > + return ret; > > + if (*hi >=3D nr_pages || *lo > *hi) > > + return -ERANGE; > > + *hi +=3D 1; > > + return 0; > > +} > > + > > +static int parse_mode(char *val, u32 *mode) > > +{ > > + *mode =3D 0; > > + > > + if (!strcmp(val, "idle")) > > + *mode =3D IDLE_WRITEBACK; > > + if (!strcmp(val, "huge")) > > + *mode =3D HUGE_WRITEBACK; > > + if (!strcmp(val, "huge_idle")) > > + *mode =3D IDLE_WRITEBACK | HUGE_WRITEBACK; > > + if (!strcmp(val, "incompressible")) > > + *mode =3D INCOMPRESSIBLE_WRITEBACK; > > + > > + if (*mode =3D=3D 0) > > + return -EINVAL; > > + return 0; > > +} > > + > > +static int scan_slots_for_writeback(struct zram *zram, u32 mode, > > + unsigned long lo, unsigned long hi, > > + struct zram_pp_ctl *ctl) > > +{ > > + u32 index =3D lo; > > + > > + while (index < hi) { > > + bool ok =3D true; > > + > > + zram_slot_lock(zram, index); > > + if (!zram_allocated(zram, index)) > > + goto next; > > + > > + if (zram_test_flag(zram, index, ZRAM_WB) || > > + zram_test_flag(zram, index, ZRAM_SAME)) > > + goto next; > > + > > + if (mode & IDLE_WRITEBACK && > > + !zram_test_flag(zram, index, ZRAM_IDLE)) > > + goto next; > > + if (mode & HUGE_WRITEBACK && > > + !zram_test_flag(zram, index, ZRAM_HUGE)) > > + goto next; > > + if (mode & INCOMPRESSIBLE_WRITEBACK && > > + !zram_test_flag(zram, index, ZRAM_INCOMPRESSIBLE)) > > + goto next; > > + > > + ok =3D place_pp_slot(zram, ctl, index); > > +next: > > + zram_slot_unlock(zram, index); > > + if (!ok) > > + break; > > + index++; > > + } > > + > > + return 0; > > +} > > + > > +static ssize_t writeback_store(struct device *dev, > > + struct device_attribute *attr, > > + const char *buf, size_t len) > > +{ > > + struct zram *zram =3D dev_to_zram(dev); > > + u64 nr_pages =3D zram->disksize >> PAGE_SHIFT; > > + unsigned long lo =3D 0, hi =3D nr_pages; > > + struct zram_pp_ctl *ctl =3D NULL; > > + char *args, *param, *val; > > + ssize_t ret =3D len; > > + int err, mode =3D 0; > > + > > + down_read(&zram->init_lock); > > + if (!init_done(zram)) { > > + up_read(&zram->init_lock); > > + return -EINVAL; > > + } > > + > > + /* Do not permit concurrent post-processing actions. */ > > + if (atomic_xchg(&zram->pp_in_progress, 1)) { > > + up_read(&zram->init_lock); > > + return -EAGAIN; > > + } > > + > > + if (!zram->backing_dev) { > > + ret =3D -ENODEV; > > + goto release_init_lock; > > + } > > + > > + ctl =3D init_pp_ctl(); > > + if (!ctl) { > > + ret =3D -ENOMEM; > > + goto release_init_lock; > > + } > > + > > + args =3D skip_spaces(buf); > > + while (*args) { > > + args =3D next_arg(args, ¶m, &val); > > + > > + /* > > + * Workaround to support the old writeback interface. > > + * > > + * The old writeback interface has a minor inconsistency = and > > + * requires key=3Dvalue only for page_index parameter, wh= ile the > > + * writeback mode is a valueless parameter. > > + * > > + * This is not the case anymore and now all parameters ar= e > > + * required to have values, however, we need to support t= he > > + * legacy writeback interface format so we check if we ca= n > > + * recognize a valueless parameter as the (legacy) writeb= ack > > + * mode. > > + */ > > + if (!val || !*val) { > > + err =3D parse_mode(param, &mode); > > + if (err) { > > + ret =3D err; > > + goto release_init_lock; > > + } > > + > > + scan_slots_for_writeback(zram, mode, lo, hi, ctl)= ; > > + break; > > + } > > + > > + if (!strcmp(param, "type")) { > > + err =3D parse_mode(val, &mode); > > + if (err) { > > + ret =3D err; > > + goto release_init_lock; > > + } > > + > > + scan_slots_for_writeback(zram, mode, lo, hi, ctl)= ; > > + break; > > + } > > + > > + if (!strcmp(param, "page_index")) { > > + err =3D parse_page_index(val, nr_pages, &lo, &hi)= ; > > + if (err) { > > + ret =3D err; > > + goto release_init_lock; > > + } > > + > > + scan_slots_for_writeback(zram, mode, lo, hi, ctl)= ; > > + break; > > + } > > + > > + /* There can be several page index ranges */ > > + if (!strcmp(param, "page_index_range")) { > > + err =3D parse_page_index_range(val, nr_pages, &lo= , &hi); > > + if (err) { > > + ret =3D err; > > + goto release_init_lock; > > + } > > + > > + scan_slots_for_writeback(zram, mode, lo, hi, ctl)= ; > > + continue; > > + } > > + } > > + > > + err =3D zram_writeback_slots(zram, ctl); > > + if (err) > > + ret =3D err; > > + > > +release_init_lock: > > release_pp_ctl(zram, ctl); > > atomic_set(&zram->pp_in_progress, 0); > > up_read(&zram->init_lock); > > -- > > 2.49.0.395.g12beb8f557-goog > >