From nobody Tue Apr 7 02:56:17 2026 Received: from mail-yw1-f176.google.com (mail-yw1-f176.google.com [209.85.128.176]) (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 DCA792BEFEE for ; Tue, 17 Mar 2026 02:50:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773715858; cv=none; b=M+gFWn/AKkGjxVQyE1LdRKHB5XgBWdf72T/AZSpN/rCac43iruJKXmjehv53Uug6EPHDj3ofVRBoMpOuszqc14WicBWitJDD2fSBB1RNJvn8xkqLb6966WfJJOjsU8sdMBIF85tUks7t12OBRtx/cjCxrhK12i8Wt5hUmQyTrjo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773715858; c=relaxed/simple; bh=wJhLhkPnFixEl7Kib5viyl1tW+lOTiNSaZw/tXvxEcU=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rPfT3duPNVlbwGkApxsaGtOIR6Zu+kLx7NXd0Eqd5vHUgg5TWS70YQ/G4VUAlJ/BgjSPsMfRce6UsYBeW5OO1VUMIwzThLVzjlflA0ZVX1+/iwsh0kNuge9ldzta1jd9BhegU1/S8DLnzrAqWcifOOaSaLfOUshoQO7REK0P5Qc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com; spf=pass smtp.mailfrom=soleen.com; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b=Ahr5xTQe; arc=none smtp.client-ip=209.85.128.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=soleen.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=soleen.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=soleen.com header.i=@soleen.com header.b="Ahr5xTQe" Received: by mail-yw1-f176.google.com with SMTP id 00721157ae682-798374d0f44so4813277b3.0 for ; Mon, 16 Mar 2026 19:50:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1773715856; x=1774320656; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=YtIBMXQB5r0gT6fB7kIdzkfYk2CIFHQnbepfnHEfiSo=; b=Ahr5xTQeQp6IuaBeyE/f51i9jzxF2lXmFgxJmmtfW6wVOE4Aim8ZGInHRo9qou23k5 5yP5wrk/aYDMAuWcWctIyzTudHzoX6EaVTAm+qIcVAZihO5cvtv8cPBzWQLxz+0Gllsf Xv/A/Ff3uPtFrckBsrdVZUQcv0aRnYxDS0pgDrlz0N03dcq3yaCxDOt0QOfEIA5R985I FEH+dQE3W0BgCcdlX9I8i9asTDv4m4osUsOTUDO4i/PcSRnKijYTQ7inUSg8clcmNz1O ve0JlBOUQb/7sdyi1FxHHju0LKT93qsZXpt/Wi1KX6Nb1FqQ/caqK9tUk1GFHl1lbLF7 jzZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773715856; x=1774320656; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=YtIBMXQB5r0gT6fB7kIdzkfYk2CIFHQnbepfnHEfiSo=; b=MAyYXNGaqFTd/Shyp69ptCMEc7JFvS3E3YDik6AnFwSZpRlCHBoHYwiazT3b3wKg1c jhA54e0MNxOleROCwPIOtwcbxkxqHnEssxF6sz84rEyFYhCb0Gx2APr2HW7GIoYi5Yc3 I1hGLhz33ssMM7c2KtdBfMQXc78oYaK0mz91UDz/jt/e2Mj5d5pZBY8XacX5dkgpkmzO 5AQY6Dz3o/NDQcHYiz4mGtEJd6nEvMCvjqBV97315u9rWUPLoSZSHihu2420tvlBmrRe b2jaGDJIQpeg2Jkx7vEIlOX9o9j1sd8jOgqe5Bjfs8+BJZgf6dHTQ0Sp+6wHCzsZGpHK gsUQ== X-Forwarded-Encrypted: i=1; AJvYcCXscXVhg0xwlUk+iYe/qpJ4Xx2SltVzlZhePwPLqIbzZep9xaaUG/RPpQbv0yrwo6gtUbmxadY8VRdEHak=@vger.kernel.org X-Gm-Message-State: AOJu0YxqjWeEI66dQr27DtTm5Qh5AIY46y7GdeBQfSgnsWG7gQxHFk6E BIUP8rIbo4+WKDPvrOxvGXSeYvQJkDRcr9nr1K4iobAbzb+H5dvrgxZg/XQBc3InS/782I6gzsu wy89W X-Gm-Gg: ATEYQzwKxfV5WgBO2RewdzglSOoCnqPtoCQHpz8r9Ag/qO15Kd4jMnvv7ic/2p0JZD0 4KwCnakCcEQXdbVOKqBWWqwY3iXCHSQxjC1q+UMOjaInCjIHNVvshGh9KadW1vOy6wcn4iquD4X ilh1uf8Exc2ZBKb20TUHhy8TsSrgvSIWaDFwECEYBtdCkhOtlyE5FdYdtI8UlyJ1cvldzW757gn 2TuAiS1fBAR8U4YUenxxvHKkSj8lxqc1vI3DqRaG/dSOJpAbZHt8O4fUvPrG40aoPNKIDUdUyQ6 1JdbReahPfOx+cFdSqSn1pu3v4jRG/XHkCPXZGIgwip/wkHGRZFnp7SKrmxQ7ObLXkdU1ujPMoc Qvu0ZNISdU8apuoSdpWFaHCMPIn35Q5ZWnxRMHXkiga4IvmFi2N3UaHk7dhIVRQ+P06On5lQbkw 4N7AqYXrNEjf9U6S06MaMOOPsDPEDaIh5VdJ+zb3cGMp2QBLwxayPbKWCzID2ZxukNP0xif33K+ MBZ7H78z6VcSWOPlzeQht6axLfcXPczwBL/Z9kNFy0X4Elv2g== X-Received: by 2002:a05:690c:67c7:b0:796:335a:895 with SMTP id 00721157ae682-79a61789c43mr17250767b3.6.1773715855932; Mon, 16 Mar 2026 19:50:55 -0700 (PDT) Received: from soleen.c.googlers.com.com (57.233.150.34.bc.googleusercontent.com. [34.150.233.57]) by smtp.gmail.com with ESMTPSA id 00721157ae682-79a5a866c85sm14951757b3.35.2026.03.16.19.50.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Mar 2026 19:50:55 -0700 (PDT) From: Pasha Tatashin To: pasha.tatashin@soleen.com, rppt@kernel.org, pratyush@kernel.org, linux-kernel@vger.kernel.org, dmatlack@google.com, akpm@linux-foundation.org, linux-mm@kvack.org Subject: [PATCH 2/6] liveupdate: Protect FLB lists with rwsem Date: Mon, 16 Mar 2026 22:50:45 -0400 Message-ID: <20260317025049.494931-3-pasha.tatashin@soleen.com> X-Mailer: git-send-email 2.53.0.851.ga537e3e6e9-goog In-Reply-To: <20260317025049.494931-1-pasha.tatashin@soleen.com> References: <20260317025049.494931-1-pasha.tatashin@soleen.com> 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 Content-Type: text/plain; charset="utf-8" Because liveupdate FLB objects will soon drop their persistent module references when registered, list traversals must be protected against concurrent module unloading. Introduce two read-write semaphores to provide this protection: 1. A global luo_flb_lock protects the global registry of FLBs. 2. A per-handler flb_lock protects the handler's specific list of FLB dependencies. Read locks are used during concurrent list traversals (e.g., during preservation and serialization). Write locks are taken during registration and unregistration. When both locks are required, the global luo_flb_lock is strictly acquired before the per-handler flb_lock to prevent deadlocks. Signed-off-by: Pasha Tatashin --- include/linux/liveupdate.h | 3 +++ kernel/liveupdate/luo_flb.c | 16 ++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index dd11fdc76a5f..8394fb2d8774 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include =20 @@ -107,6 +108,8 @@ struct liveupdate_file_handler { struct list_head __private list; /* A list of FLB dependencies. */ struct list_head __private flb_list; + /* Protects flb_list */ + struct rw_semaphore __private flb_lock; }; =20 /** diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index f52e8114837e..91910d806d1d 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include "luo_internal.h" @@ -70,6 +71,7 @@ struct luo_flb_global { long count; }; =20 +static DECLARE_RWSEM(luo_flb_lock); static struct luo_flb_global luo_flb_global =3D { .list =3D LIST_HEAD_INIT(luo_flb_global.list), }; @@ -240,6 +242,8 @@ int luo_flb_file_preserve(struct liveupdate_file_handle= r *fh) struct luo_flb_link *iter; int err =3D 0; =20 + guard(rwsem_read)(&ACCESS_PRIVATE(fh, flb_lock)); + list_for_each_entry(iter, flb_list, list) { err =3D luo_flb_file_preserve_one(iter->flb); if (err) @@ -272,6 +276,8 @@ void luo_flb_file_unpreserve(struct liveupdate_file_han= dler *fh) struct list_head *flb_list =3D &ACCESS_PRIVATE(fh, flb_list); struct luo_flb_link *iter; =20 + guard(rwsem_read)(&ACCESS_PRIVATE(fh, flb_lock)); + list_for_each_entry_reverse(iter, flb_list, list) luo_flb_file_unpreserve_one(iter->flb); } @@ -292,6 +298,8 @@ void luo_flb_file_finish(struct liveupdate_file_handler= *fh) struct list_head *flb_list =3D &ACCESS_PRIVATE(fh, flb_list); struct luo_flb_link *iter; =20 + guard(rwsem_read)(&ACCESS_PRIVATE(fh, flb_lock)); + list_for_each_entry_reverse(iter, flb_list, list) luo_flb_file_finish_one(iter->flb); } @@ -355,6 +363,9 @@ int liveupdate_register_flb(struct liveupdate_file_hand= ler *fh, if (!luo_session_quiesce()) return -EBUSY; =20 + guard(rwsem_write)(&luo_flb_lock); + guard(rwsem_write)(&ACCESS_PRIVATE(fh, flb_lock)); + /* Check that this FLB is not already linked to this file handler */ err =3D -EEXIST; list_for_each_entry(iter, flb_list, list) { @@ -444,6 +455,9 @@ int liveupdate_unregister_flb(struct liveupdate_file_ha= ndler *fh, if (!luo_session_quiesce()) return -EBUSY; =20 + guard(rwsem_write)(&luo_flb_lock); + guard(rwsem_write)(&ACCESS_PRIVATE(fh, flb_lock)); + /* Find and remove the link from the file handler's list */ list_for_each_entry(iter, flb_list, list) { if (iter->flb =3D=3D flb) { @@ -638,6 +652,8 @@ void luo_flb_serialize(void) struct liveupdate_flb *gflb; int i =3D 0; =20 + guard(rwsem_read)(&luo_flb_lock); + list_private_for_each_entry(gflb, &luo_flb_global.list, private.list) { struct luo_flb_private *private =3D luo_flb_get_private(gflb); =20 --=20 2.53.0.851.ga537e3e6e9-goog