From nobody Mon Apr 6 14:54:59 2026 Received: from out-185.mta0.migadu.com (out-185.mta0.migadu.com [91.218.175.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 533F136BCDC for ; Thu, 19 Mar 2026 06:59:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.185 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773903584; cv=none; b=cJw5RCeeZGBX6ADhWZvy4gP1LTvj3vCsDX8s4jdrWjXLMBtDBCQitDkICqRIaegp+TwI/twHnaR/T4aOEgrvhNJWYPLpVGzy9N7HPFe0cnDmU9bpSyKzNWPFuZbtV2mQ7QLas0P6WrPaQpqgACy9GK5mmXC0oV/Kcw2Cvf+gcHA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773903584; c=relaxed/simple; bh=eSG6YQm67YlGR13wN8SfLpH7gcfc4/82iVVEgg0s5Fw=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=mNWUnLjEs3K0UzQJqDi9SO3i1Y6HLUilCoEUyymEionl/ZaBewamDNf1OYi3AKeCqFhhoy/W972vEXKNCICSY8gzf6pv97Hm5Rv3uva1vZ6oZVdRD1VeCtLzb4xMfhYNH44ZZg/+2bRdxbNSF41zPcrGEs3QdgKLKA0UYyqDsqo= 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=f77AfviT; arc=none smtp.client-ip=91.218.175.185 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="f77AfviT" X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773903578; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=MqgwjOgYAgCvdM+KEzOVlrYDCZwrzcZ5oUrc3PxO6ls=; b=f77AfviTCa3A2iLW9blXxrDruz8cCYgr5yLo+h5gX+KDVCyDyen+xKEyIMFeTcErPpXZDq GP+/ve/NhwcNVBZlo/A/+g5O0lglmhg8Hsd8Ns63Ts7xpZpr2UxNIDvtH4cksMYyd5nAIn dYcDs87YHhTdNadxnFQ+PlohXiTJOJI= From: Hui Zhu To: Minchan Kim , Sergey Senozhatsky , Andrew Morton , linux-mm@kvack.org, linux-kernel@vger.kernel.org Cc: teawater Subject: [PATCH v3] zsmalloc: return -EBUSY for zspage migration lock contention Date: Thu, 19 Mar 2026 14:59:24 +0800 Message-ID: <20260319065924.69337-1-hui.zhu@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: quoted-printable X-Migadu-Flow: FLOW_OUT Content-Type: text/plain; charset="utf-8" From: teawater movable_operations::migrate_page() should return an appropriate error code for temporary migration failures so the migration core can handle them correctly. zs_page_migrate() currently returns -EINVAL when zspage_write_trylock() fails. That path reflects transient lock contention, not invalid input, so -EINVAL is clearly wrong. However, -EAGAIN is also inappropriate here: the zspage's reader-lock owner may hold the lock for an unbounded duration due to slow decompression or reader-lock owner preemption. Since migration retries are bounded by NR_MAX_MIGRATE_PAGES_RETRY and performed with virtually no delay between attempts, there is no guarantee the lock will be released in time for a retry to succeed. -EAGAIN implies "try again soon", which does not hold in this case. Return -EBUSY instead, which more accurately conveys that the resource is occupied and migration cannot proceed at this time. Acked-by: Sergey Senozhatsky Signed-off-by: teawater --- Changelog: v3: According to the comments of Sergey Senozhatsky, update the comments. v2: According to the comments of Sergey Senozhatsky, change from -EAGAIN to -EBUSY and add comments. mm/zsmalloc.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c index 2c1430bf8d57..e7417ece1c12 100644 --- a/mm/zsmalloc.c +++ b/mm/zsmalloc.c @@ -1727,7 +1727,19 @@ static int zs_page_migrate(struct page *newpage, str= uct page *page, if (!zspage_write_trylock(zspage)) { spin_unlock(&class->lock); write_unlock(&pool->lock); - return -EINVAL; + /* + * Return -EBUSY but not -EAGAIN: the zspage's reader-lock + * owner may hold the lock for an unbounded duration due to a + * slow decompression or reader-lock owner preemption. + * Since migration retries are bounded by + * NR_MAX_MIGRATE_PAGES_RETRY and performed with virtually no + * delay between attempts, there is no guarantee the lock will + * be released in time for a retry to succeed. + * -EAGAIN implies "try again soon", which does not hold here. + * -EBUSY more accurately conveys "resource is occupied, + * migration cannot proceed". + */ + return -EBUSY; } =20 /* We're committed, tell the world that this is a Zsmalloc page. */ --=20 2.43.0