From nobody Mon Feb 9 10:27:23 2026 Received: from mail-pf1-f177.google.com (mail-pf1-f177.google.com [209.85.210.177]) (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 A965D2EE5FC for ; Sun, 25 Jan 2026 17:58:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.210.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769363901; cv=none; b=HXrJpMakCqjHLXvfEFyZNGwGbZd6zVH6btd06t3azr0ZtjZHnT9VD0lnEMvDHYGYqaGDthuknzRr3Lfp4rFE9SsZE7DAkNE42K4t1VXLACYxZZZ1aVAGiHnjccNk9B1knMz0ILzy9Wy8qnMnQdqctv65RbcMG+CDkfY9I3DGS90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769363901; c=relaxed/simple; bh=OWJY00Wf2dIBc05Nz8hzedH27aMPMMOuwTeZeud6eu0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=dWjkVq/uRy7GOb8ndF2k9+WywbTWzlsc94LZHbJZJG6nV8EyjhHonXH+1GGKEDsgeGlsMzNpx+k7Spq0YGHU3nMk8HTw13utVMT1jsR0g5ltuxpKaZ877RDUXE8WphN+iGyKxLa82W2i5VJumMII9UNWYNr5p378Cuk7LnExj58= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=AnxR/oP+; arc=none smtp.client-ip=209.85.210.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AnxR/oP+" Received: by mail-pf1-f177.google.com with SMTP id d2e1a72fcca58-81345800791so2447198b3a.0 for ; Sun, 25 Jan 2026 09:58:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1769363899; x=1769968699; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=aAw5ZLwfH3aOqNw+8qnqKgdPaynl21dDWoO/xPxb8Vc=; b=AnxR/oP+WCkTQ/6usIFyz39FnUyCkCUZvqiAQK1YYfbjdd13FS0ocR3+gr3iSNWJ6M byee5aVlHWW+WM4FvHYlUmkdduQOBMcl6ZoM1lxuHwTTNAhoAIWFUsGTGgCGZF1A3lYE PYPbeslWAwdGRF1933hAEX1jfNoi/Eomx0yR+2wb0K+352QVxwS5zLcjA/O9kMu88gBH vm3ScnwZln0i84JYr9mQc8HKQtL1yyc2jbTViV/nocOA4Hgg3m692rThFvf1iquIFSi/ 6CnR6s2fbfQR7f0o7x7Jyag7I7TnzOghikHsRkKD3zcS3tRHbadzloJVBXLFPp9AQ5em qW1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1769363899; x=1769968699; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=aAw5ZLwfH3aOqNw+8qnqKgdPaynl21dDWoO/xPxb8Vc=; b=RuOlpPzqKbyVAZknUVl6mZa3e2xFg8k1rqD6A3DfTZI4B7VkT/H/x4upPl6FfRak41 YJ0rtrfKb5jhLhdDmotLGRrdH9w8z0MV5inJ1jfifFSUH6xUFLbrjY6uIcRlhPO3V4xP 2DDo8HDf83LdFMqU4s3Jg9aKvtlABT9a0VKWJBRrWwN3l4uPM+dcTA5EkkEq95Uhmnoh s86WRpEfJ7CYLmh0f+sxfb3/gye11S76KZE9Min390Ps4Ao9+GCNegvoy1VTUfkDAIMt tR0oA8ZbK/LkHH1yOxskh74wHnI5fp2+m+X8AoFT0HeasX6yV19Ymq4UjmA4kWY44zMM 9owA== X-Forwarded-Encrypted: i=1; AJvYcCUZ6Esu1vSguPzC7L4BsJpLAtih+72+IMaHNZl4mZMHnHdx+3aPOjrKJ7sbBxtXFJiCS91KmSk/P5zbHVw=@vger.kernel.org X-Gm-Message-State: AOJu0YyJ8OyQyKZnAoB9T0+5k8KPE8cDqfPraYnXRmxuhR5cYOGRRQEJ ajG4Fc973bJfGU2kG4yYMchnaIF9e9B8+8aPsSEk23WPJqX4UcJIh0cm X-Gm-Gg: AZuq6aLtnC9WAMvKALRgQDzJVlPOLU86r8fWKua5E5rNMHcxmCbnHw5jLsjQ7yH0Vsx rNZ2mXO+Bf7ZLzanMbcooAAmbo/X8Mn39gDK8Gj9muwpg1xLP3uaA6dcmiFoaiu9KNo1gO6a0CK qKg4ZdL9aGg3LKy4cnE74UWCHRKDnm9yfDvdlEarryAyfwUy5t3jby7ajqyPCJCnS2NXhuMNcm1 8RSIhmkIVOxskFORObSJXUpaZBTnUSvT8AXvB2lTAkegZymAUKtfaFi0rFqkZtmOKcqI+AIJATl Qsajkb3Bl4bniOUmGTsXHZnFOisOnus32jhtw0Y+plS0F4hR8UAIJaJj88Q0WZMxFA1chf1ZwYj Gu2DCsABWTG2HHOx/J8HNr/LvCrCXre3iQVtlC5dgidOvXv5wd82FRoRlZpo0KTpQzvLWnouxp+ UZAe7I4TjXcmg/T75JgNPHjQpdXoEcn+m5ZUxOlm2awITlyLS2 X-Received: by 2002:a05:6a00:3c93:b0:821:807a:e427 with SMTP id d2e1a72fcca58-823411dad08mr1660383b3a.21.1769363899012; Sun, 25 Jan 2026 09:58:19 -0800 (PST) Received: from [127.0.0.1] ([101.32.222.185]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-8231876e718sm7405963b3a.62.2026.01.25.09.58.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jan 2026 09:58:18 -0800 (PST) From: Kairui Song Date: Mon, 26 Jan 2026 01:57:27 +0800 Subject: [PATCH 04/12] mm, swap: consolidate bad slots setup and make it more robust Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260126-swap-table-p3-v1-4-a74155fab9b0@tencent.com> References: <20260126-swap-table-p3-v1-0-a74155fab9b0@tencent.com> In-Reply-To: <20260126-swap-table-p3-v1-0-a74155fab9b0@tencent.com> To: linux-mm@kvack.org Cc: Andrew Morton , Kemeng Shi , Nhat Pham , Baoquan He , Barry Song , Johannes Weiner , David Hildenbrand , Lorenzo Stoakes , linux-kernel@vger.kernel.org, Chris Li , Kairui Song X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1769363877; l=4411; i=kasong@tencent.com; s=kasong-sign-tencent; h=from:subject:message-id; bh=OidTajkMc0iGAT4CQSZ4FaMMIJHOoz6IAuhiV5n7RgI=; b=22h05Pvce5AkmGELBrC+VspfwsX4gVHJPoaq21bkR6YV6t5rRkvi2X8Y59JOGt3EG4xfxQBNi wV6+WfpY79sDSPNwBbtLq6PengLrG0audQ8Rc0lvcP8R/0MM3pRKruN X-Developer-Key: i=kasong@tencent.com; a=ed25519; pk=kCdoBuwrYph+KrkJnrr7Sm1pwwhGDdZKcKrqiK8Y1mI= From: Kairui Song In preparation for using the swap table to track bad slots directly, move the bad slot setup to one place, set up the swap_map mark, and cluster counter update together. While at it, provide more informative logs and a more robust fallback if any bad slot info looks incorrect. Fixes a potential issue that a malformed swap file may cause the cluster to be unusable upon swapon, and provides a more verbose warning on a malformed swap file Signed-off-by: Kairui Song --- mm/swapfile.c | 68 +++++++++++++++++++++++++++++++++----------------------= ---- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index 80bf0ea098f6..df8b13eecab1 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -743,13 +743,37 @@ static void relocate_cluster(struct swap_info_struct = *si, * slot. The cluster will not be added to the free cluster list, and its * usage counter will be increased by 1. Only used for initialization. */ -static int swap_cluster_setup_bad_slot(struct swap_cluster_info *cluster_i= nfo, - unsigned long offset) +static int swap_cluster_setup_bad_slot(struct swap_info_struct *si, + struct swap_cluster_info *cluster_info, + unsigned int offset, bool mask) { unsigned long idx =3D offset / SWAPFILE_CLUSTER; struct swap_table *table; struct swap_cluster_info *ci; =20 + /* si->max may got shrunk by swap swap_activate() */ + if (offset >=3D si->max && !mask) { + pr_debug("Ignoring bad slot %u (max: %u)\n", offset, si->max); + return 0; + } + /* + * Account it, skip header slot: si->pages is initiated as + * si->max - 1. Also skip the masking of last cluster, + * si->pages doesn't include that part. + */ + if (offset && !mask) + si->pages -=3D 1; + if (!si->pages) { + pr_warn("Empty swap-file\n"); + return -EINVAL; + } + /* Check for duplicated bad swap slots. */ + if (si->swap_map[offset]) { + pr_warn("Duplicated bad slot offset %d\n", offset); + return -EINVAL; + } + + si->swap_map[offset] =3D SWAP_MAP_BAD; ci =3D cluster_info + idx; if (!ci->table) { table =3D swap_table_alloc(GFP_KERNEL); @@ -3216,30 +3240,12 @@ static int setup_swap_map(struct swap_info_struct *= si, union swap_header *swap_header, unsigned long maxpages) { - unsigned long i; unsigned char *swap_map; =20 swap_map =3D vzalloc(maxpages); si->swap_map =3D swap_map; if (!swap_map) return -ENOMEM; - - swap_map[0] =3D SWAP_MAP_BAD; /* omit header page */ - for (i =3D 0; i < swap_header->info.nr_badpages; i++) { - unsigned int page_nr =3D swap_header->info.badpages[i]; - if (page_nr =3D=3D 0 || page_nr > swap_header->info.last_page) - return -EINVAL; - if (page_nr < maxpages) { - swap_map[page_nr] =3D SWAP_MAP_BAD; - si->pages--; - } - } - - if (!si->pages) { - pr_warn("Empty swap-file\n"); - return -EINVAL; - } - return 0; } =20 @@ -3270,26 +3276,28 @@ static int setup_swap_clusters_info(struct swap_inf= o_struct *si, } =20 /* - * Mark unusable pages as unavailable. The clusters aren't - * marked free yet, so no list operations are involved yet. - * - * See setup_swap_map(): header page, bad pages, - * and the EOF part of the last cluster. + * Mark unusable pages (header page, bad pages, and the EOF part of + * the last cluster) as unavailable. The clusters aren't marked free + * yet, so no list operations are involved yet. */ - err =3D swap_cluster_setup_bad_slot(cluster_info, 0); + err =3D swap_cluster_setup_bad_slot(si, cluster_info, 0, false); if (err) goto err; for (i =3D 0; i < swap_header->info.nr_badpages; i++) { unsigned int page_nr =3D swap_header->info.badpages[i]; =20 - if (page_nr >=3D maxpages) - continue; - err =3D swap_cluster_setup_bad_slot(cluster_info, page_nr); + if (!page_nr || page_nr > swap_header->info.last_page) { + pr_warn("Bad slot offset is out of border: %d (last_page: %d)\n", + page_nr, swap_header->info.last_page); + err =3D -EINVAL; + goto err; + } + err =3D swap_cluster_setup_bad_slot(si, cluster_info, page_nr, false); if (err) goto err; } for (i =3D maxpages; i < round_up(maxpages, SWAPFILE_CLUSTER); i++) { - err =3D swap_cluster_setup_bad_slot(cluster_info, i); + err =3D swap_cluster_setup_bad_slot(si, cluster_info, i, true); if (err) goto err; } --=20 2.52.0