From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-189.mta0.migadu.com (out-189.mta0.migadu.com [91.218.175.189]) (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 EBAD0248880 for ; Tue, 7 Jul 2026 08:27:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.189 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783412832; cv=none; b=KuuofBV/YMUmkN5n79UNYXQJ7vAI2qGj8ltv34M4cVmWzhFnAqas8cUPwvKVpmwQhU62VmIfxUsosuMs6aQ8KR1pUBWc708cGVlJpxgSVHnXtvprcv+OYzu74pItj2kP+dQUrbUwRkdVtINSWRVXYs/avq1U0jhsIlmPE/wZleI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783412832; c=relaxed/simple; bh=Ln+z8w/6qk3U9m5fhMm8NeFqLshB3yQZTJaDEV45wbQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-type; b=cFhz+lof8eV9GZh4d9DXIhMBTBhO4wT8t4iCJWIqlfMj/XLRMDY3tCBnh79uBu+kG0IEwNtsvy8CTRqY1G6Q0hJp1MbXTXyaOie/qKXJ8r5HsANmRAv88m2UlqS2mbo6Dwdh0R5bRj1Q7YxnnZ5Ff7L2oZQeJK97B5yeu25rGJ0= 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=E1ToZpjs; arc=none smtp.client-ip=91.218.175.189 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="E1ToZpjs" 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=1783412829; h=from:from: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; bh=kunGe7C6xhIHkVZkIf+Bq+1kDqvK88lHrFnSbrffnn0=; b=E1ToZpjs6T/cz+vDQt6MGrXm0A7R15ZuLJLHP4nKgxCUu3MT0YHbr1Fvv5KfvXYEesKeuN twvE70zBSHlua21537cPep3rtagx0khoSpr9TlMyVr9aCYDw8HJIib1ziY0arOYVKXVn8h MxPYicDyDEXojEh259wHRFVndpnD6yI= From: Baoquan He To: linux-mm@kvack.org Cc: akpm@linux-foundation.org, chrisl@kernel.org, kasong@tencent.com, shikemeng@huaweicloud.com, nphamcs@gmail.com, baohua@kernel.org, youngjun.park@lge.com, hannes@cmpxchg.org, yosry@kernel.org, chengming.zhou@linux.dev, linux-kernel@vger.kernel.org, Baoquan He Subject: [RFC PATCH 05/10] mm/swap_state: restore Redirect entry when swap cache folio is removed Date: Tue, 7 Jul 2026 16:26:07 +0800 Message-ID: <20260707082614.95030-6-baoquan.he@linux.dev> In-Reply-To: <20260707082614.95030-1-baoquan.he@linux.dev> References: <20260707082614.95030-1-baoquan.he@linux.dev> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-type: text/plain Content-Transfer-Encoding: 8bit X-Migadu-Flow: FLOW_OUT When a swap cache folio is removed from a ghost swap device, __swap_cache_do_del_folio() normally restores a Shadow entry with the preserved swap count. For ghost devices, the entry may have originated from a Redirect (zswap writeback to a physical device). Check the redirect_xa before restoring a Shadow: if a redirect mapping exists, restore the Redirect entry instead. This ensures future swapins are correctly forwarded to the physical device. The redirect mapping is stored in the xarray during zswap writeback (see zswap_writeback_ghost()) and persists across the swap-cache PFN lifecycle. Signed-off-by: Baoquan He --- mm/swap_state.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/mm/swap_state.c b/mm/swap_state.c index 5fb893cc7fce..cb2ed2a18f9f 100644 --- a/mm/swap_state.c +++ b/mm/swap_state.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -329,6 +330,26 @@ static void __swap_cache_do_del_folio(struct swap_cluster_info *ci, folio_swapped = true; else need_free = true; + /* + * For ghost swap devices with a redirect mapping, + * restore the Redirect entry so future swapins + * are forwarded to the physical device. + */ + if (si->flags & SWP_GHOST) { + swp_entry_t phys_entry; + void *val; + + val = xa_load(&si->redirect_xa, + (swp_offset(entry) - + swp_cluster_offset(entry)) + + ci_off); + if (val && !xa_is_err(val)) { + phys_entry.val = xa_to_value(val); + __swap_table_set(ci, ci_off, + swp_entry_to_redirect(phys_entry)); + continue; + } + } /* If shadow is NULL, we set an empty shadow. */ __swap_table_set(ci, ci_off, shadow_to_swp_tb(shadow, __swp_tb_get_flags(old_tb))); -- 2.54.0