From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mta1.migadu.com (out-62.mta1.migadu.com [95.215.58.62]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2B8D8260565 for ; Tue, 6 Oct 2026 00:23:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.62 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791246200; cv=none; b=nrQ1wGF9dPN/A68iq/hp29lSrZNqy1bellS1H+IXZRhWesioy4QTta6nChA4BU6QGNjeVRLJCh07eYcUTNu5G68F4VDZ0wARchxevExDTV2Eb7RZwqxp/9AguUSbuCLCTLWPLfbMdVNFkaO0R8otMVrusouXmfaP79yNZHoB7RQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1791246200; c=relaxed/simple; bh=nbJqiGn5pFkuXQBzYRivhDJLdV+pjGcePbifZ588ksg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tA1kGodn5+D0MbzPMuMXqJjlu1sMKVjHa7K4mtHE1yWz+jnwjCOcTT1NNNDJiI5cC/FMbbOqp7O8nFRszyruQVrvxoLOmtPWMXrjcLdhOVrfp4kCu8mlhymFAIY//xOc5g+vXg4cZnSUmFrhVi9vPSNXFiIG3XIVeJgja/HXVX0= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=YonuEzSv; arc=none smtp.client-ip=95.215.58.62 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="YonuEzSv" X-Envelope-To: linux-kernel@vger.kernel.org DKIM-Signature: a=rsa-sha256; bh=nbJqiGn5pFkuXQBzYRivhDJLdV+pjGcePbifZ588ksg=; c=simple/simple; d=linux.dev; h=from:to:subject:date:message-id:mime-version:content-type; s=key1; t=1791246196; v=1; x=1791850996; b=YonuEzSv6V1v6uLsWV1icfYMJZIDBdS3eiCoHZ/IFoawKjlt19ojM8GpCMaQelsqxqAtg2RB k0Y8d9PXDVp1aH0Q75280aKj5aWAEgHvAq6jGW5Iai8i4DNIrYi5zRUqht2ZkAcJh0lh9bV5bP/ ihkDOOTO3+SrrUfzkxbSFOvQ= X-Envelope-To: linux-kernel@vger.kernel.org Received: by mta12.migadu.com with ESMTPS id 99567cebb8f6a1d1; Tue, 06 Oct 2026 00:23:16 +0000 X-Mizu-Trace-ID: 99567cebb8f6a1d1 X-Migadu-Flow: FLOW_OUT From: Usama Arif To: Andrew Morton , chengming.zhou@linux.dev, dsterba@suse.com, hannes@cmpxchg.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, nphamcs@gmail.com, terrelln@fb.com, yosry@kernel.org, riel@surriel.com, shakeel.butt@linux.dev, alex@ghiti.fr, senozhatsky@chromium.org, kernel-team@meta.com Cc: Usama Arif Subject: [PATCH 2/2] mm: zswap: use stack requests for synchronous decompression Date: Mon, 5 Oct 2026 17:22:51 -0700 Message-ID: <20261006002307.2669023-3-usama.arif@linux.dev> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20261006002307.2669023-1-usama.arif@linux.dev> References: <20261006002307.2669023-1-usama.arif@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit With separate requests for compression and decompression, loads still serialize on the per-CPU decompression mutex. A low-priority load that is preempted after the codec drops its stream lock keeps holding the mutex and stalls every other load on that CPU, including higher-priority ones. Synchronous algorithms whose requests need no extra context can use an on-stack request, so decompress with one and take no zswap lock. All in-tree software compressors qualify. Asynchronous algorithms, and synchronous ones with request context, keep the per-CPU request and mutex, which is still taken before the zsmalloc read lock. Reading the per-CPU context without the mutex is safe. Since commit ef3c0f6cb798e ("mm: zswap: tie per-CPU acomp_ctx lifetime to the pool"), it is set up before its CPU comes online and is not torn down until the pool is destroyed. The codecs keep their own stream locks, and crypto_acomp_decompress() rejects on-stack requests only for asynchronous transforms, which never take this path. For software compressors this drops the heap request added by the previous patch. The on-stack request and wait take 216 bytes, which makes the load path about 270 bytes deeper on x86-64. Asynchronous algorithms pay this too. Signed-off-by: Usama Arif --- mm/zswap.c | 65 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/mm/zswap.c b/mm/zswap.c index 54187b1ef751d..7e7fb6e7ec24c 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -147,7 +147,7 @@ struct zswap_acomp_req { struct crypto_acomp_ctx { struct crypto_acomp *acomp; struct zswap_acomp_req comp; - struct zswap_acomp_req decomp; + struct zswap_acomp_req decomp; /* unused by synchronous algorithms */ u8 *buffer; }; @@ -851,15 +851,20 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node) goto fail; } - if (zswap_acomp_req_init(&acomp_ctx->comp, acomp_ctx->acomp) || - zswap_acomp_req_init(&acomp_ctx->decomp, acomp_ctx->acomp)) { - pr_err("could not alloc crypto acomp_request %s\n", - pool->tfm_name); - goto fail; + if (zswap_acomp_req_init(&acomp_ctx->comp, acomp_ctx->acomp)) + goto req_fail; + + /* Synchronous algorithms decompress with an on-stack request. */ + if (acomp_is_async(acomp_ctx->acomp) || + crypto_acomp_reqsize(acomp_ctx->acomp) > MAX_SYNC_COMP_REQSIZE) { + if (zswap_acomp_req_init(&acomp_ctx->decomp, acomp_ctx->acomp)) + goto req_fail; } return 0; +req_fail: + pr_err("could not alloc crypto acomp_request %s\n", pool->tfm_name); fail: acomp_ctx_free(acomp_ctx); return ret; @@ -951,19 +956,14 @@ static bool zswap_compress(struct folio *folio, long index, return comp_ret == 0 && alloc_ret == 0; } -static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio) +static bool __zswap_decompress(struct zswap_entry *entry, + struct zswap_pool *pool, struct acomp_req *req, + struct crypto_wait *wait, struct folio *folio) { - struct zswap_pool *pool = zswap_entry_pool(entry); struct scatterlist input[2]; /* zsmalloc returns an SG list 1-2 entries */ struct scatterlist output; - struct crypto_acomp_ctx *acomp_ctx; int ret = 0, dlen; - if (WARN_ON_ONCE(!pool)) - return false; - - acomp_ctx = raw_cpu_ptr(pool->acomp_ctx); - mutex_lock(&acomp_ctx->decomp.mutex); zs_obj_read_sg_begin(pool->zs_pool, entry->handle, input, entry->length); /* zswap entries of length PAGE_SIZE are not compressed. */ @@ -980,15 +980,14 @@ static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio) } else { sg_init_table(&output, 1); sg_set_folio(&output, folio, PAGE_SIZE, 0); - acomp_request_set_params(acomp_ctx->decomp.req, input, &output, - entry->length, PAGE_SIZE); - ret = crypto_acomp_decompress(acomp_ctx->decomp.req); - ret = crypto_wait_req(ret, &acomp_ctx->decomp.wait); - dlen = acomp_ctx->decomp.req->dlen; + acomp_request_set_params(req, input, &output, entry->length, + PAGE_SIZE); + ret = crypto_acomp_decompress(req); + ret = crypto_wait_req(ret, wait); + dlen = req->dlen; } zs_obj_read_sg_end(pool->zs_pool, entry->handle); - mutex_unlock(&acomp_ctx->decomp.mutex); if (!ret && dlen == PAGE_SIZE) return true; @@ -1002,6 +1001,32 @@ static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio) return false; } +static bool zswap_decompress(struct zswap_entry *entry, struct folio *folio) +{ + struct zswap_pool *pool = zswap_entry_pool(entry); + struct crypto_acomp_ctx *acomp_ctx; + bool ret; + + if (WARN_ON_ONCE(!pool)) + return false; + + acomp_ctx = raw_cpu_ptr(pool->acomp_ctx); + if (!acomp_ctx->decomp.req) { + ACOMP_REQUEST_ON_STACK(req, acomp_ctx->acomp); + DECLARE_CRYPTO_WAIT(wait); + + acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, + crypto_req_done, &wait); + return __zswap_decompress(entry, pool, req, &wait, folio); + } + + mutex_lock(&acomp_ctx->decomp.mutex); + ret = __zswap_decompress(entry, pool, acomp_ctx->decomp.req, + &acomp_ctx->decomp.wait, folio); + mutex_unlock(&acomp_ctx->decomp.mutex); + return ret; +} + /********************************* * writeback code **********************************/ -- 2.53.0-Meta