From nobody Tue Apr 7 02:56:25 2026 Received: from mail-yw1-f169.google.com (mail-yw1-f169.google.com [209.85.128.169]) (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 BC76834CFBD for ; Tue, 17 Mar 2026 02:51:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773715862; cv=none; b=hr1CUQNuS0o6JzRzd2O1PjrdAzZYiL3Rn//DbUA9cCMqEFeW5FzkO9d68JNX/a/q3+qFNq3HK47sVIayMqLKVtv0ELaUiPGQpGnEiN4q/bjyRxuk9WPLWD6ktCxX3mQ67FXQ6vdF9iZoVYPjBRrWOHq3u0XSKFtD3bWY4KCaFN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773715862; c=relaxed/simple; bh=vS7QcUz0WEMkqtEepJCwXdIhd/NFaUveowsZh47nX+s=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=S4fdCx6jb8V/iGFcsjDuXVmcW1yJedb3C8tJotfGHUwhYazBuvgr8gJD/FldonEOxj9r5kHDOG2kFk9F+BDTvIKJbIHXAdftGnknUCW27pdewwVHGHh88PdeVaQhTAdBwK4hmXOOi7AGoVNHoO/XJtCX4pT+DNAceGAPGhr580o= 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=fE/i7cxG; arc=none smtp.client-ip=209.85.128.169 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="fE/i7cxG" Received: by mail-yw1-f169.google.com with SMTP id 00721157ae682-79a46260385so18167777b3.3 for ; Mon, 16 Mar 2026 19:51:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=soleen.com; s=google; t=1773715860; x=1774320660; 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=DDyewP1AZHpe5wDxr4egwn4qSBkMsagV6JEmGWYwO1o=; b=fE/i7cxGY8UT9KI3CN/IcYqfcm+MNzFTbaMfhOz0099vmHo2qDiFpnjpWr5z8z0Y9p it//d3BXoymUMTsBaW6Ykw5vaKCnYCr9l9yFwWZRwCoPZ0uEIfkV6Gp5YkibUC+rjvD+ zFzeJToqgUIU7/siswBQI3tCVUAVIBooF6ZnCFQSeK3XCj5ixUjTDS6dtRD4I54pDGec VLbBcHrJNDD03MRd+RHiS/C98R4GxqSQ8JNs7gdLgyvMs4YVTOwke4Scy+bK0NWtfCCu GijHAKODuuVuwWIb2nYDre3b1aT/ExmyerTzUOgOMJU8F1p2j4HzRyk6X7C8KFEbOk08 0IYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773715860; x=1774320660; 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=DDyewP1AZHpe5wDxr4egwn4qSBkMsagV6JEmGWYwO1o=; b=gppaUNFxPNrdzfSGJYxY4c7cwvj+1ccMsd2zwe4+tXwafZL+l/it1PVFgnh/A+zRYQ FRwtGJry5jRQ266ht8RyOG5RwuEpuZflmjNU1Wh0zTIq+qYFQAiUMzg94awlaQhXvXuM 5m1A09uhP3LL9MwlvsIuHsdY2h09SU8oOPXq+aWo5y90/xeWQKN10PhK5MoWsRlYF5ZT Sxf6bDGlOpiAwAD5U6ENU0cJ/0lhTKAmaC9tGYFywLLXPLwUIMF0NIpoQV9gFP5LZKFL +ZB21pYHwjH2dzq/j7+KAnJMVs8AuMmCqd0eSOIL4FGqkIRytWaxL5xLAiWmx7xLnqls /DxQ== X-Forwarded-Encrypted: i=1; AJvYcCU75BJYHFKk4H8lpj4iwGfLcZXEab/0EcdMQPmZ+Pnk+VMgZFSFF8MSpbDJ3KBRQlFM1gEUhHXTFqyt9TQ=@vger.kernel.org X-Gm-Message-State: AOJu0Ywt/MWi9aj2zFKj18Xqup+09R3NNxpDgySTnsVQUH5s12z5Vq+2 VPJcx+OW1b9VA9OeifJEne+goN0Sw8bCQVLAM5NMl/6u+LoQWI/Wt0KJwaHCeo39okg= X-Gm-Gg: ATEYQzz/lPiS+I8HthDv9fe9w3sr1mh3VkmGjAbC2w/CzVkqBhSyCmm8R1A0qaM62fR +zr2I30EZZKrpICz53t/Ldb2VTMjyIUUjTLiqQAyiQb85wRix88xvgg6A7w9/zTIPnEjT/JBVwz 8LD9lzj8QBZ83tUCDtoIBgQJALJa1qBTS+zqumV4PB3IgvRsyV7rvmQwYfW8wvsQjJC1jVQ+i2g y6kWs4mtbqlPjFQDtR9Jh7LD2tkL7/ryeowspiAclAilpwKi4MjAbSYJAbHbFzxfgMTG9IrRuCN jEAKkJHyK2D4N+IGWw7HFNKzTl6WXV9lpCV1DWITV1crIIRYxcmOraouYgtXQ433ZMPY6zbCu6y gZr4G5bqy/TKeQJf/EM6fjH65fecOTXeS4x6nwLYwUIlxVUl11NbeyEtfWgZVbQKH6cjDMrKD9v /dNU/bXCIBI3yGabcIVVSDS2JBI+q00ncIqhALAVlVv9l3txokZEGxAxGrGcK5K8CLQjB3G7r8V tna/YDpXl0TaEfJbxqRwdgJjgKcbiLPZ/OIwNqwNeQlFMtJkQ== X-Received: by 2002:a05:690c:6d10:b0:797:d386:44c9 with SMTP id 00721157ae682-79a1c17b181mr153296457b3.32.1773715859783; Mon, 16 Mar 2026 19:50:59 -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.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 16 Mar 2026 19:50:58 -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 5/6] liveupdate: Make unregister functions return void Date: Mon, 16 Mar 2026 22:50:48 -0400 Message-ID: <20260317025049.494931-6-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" Change liveupdate_unregister_file_handler and liveupdate_unregister_flb to return void instead of an error code. If they fail to unregister due to dangling references, print a warning instead of aborting. As pointed out by Jason Gunthorpe and Alex Williamson, returning an error from a "destroy" or unregister function during a module unload is a poor API choice since the unload cannot be stopped at that point. Signed-off-by: Pasha Tatashin --- include/linux/liveupdate.h | 13 ++++++------ kernel/liveupdate/luo_file.c | 27 +++++++++++------------- kernel/liveupdate/luo_flb.c | 40 ++++++++++-------------------------- lib/tests/liveupdate.c | 8 ++------ 4 files changed, 31 insertions(+), 57 deletions(-) diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h index 8394fb2d8774..293df26b9e7f 100644 --- a/include/linux/liveupdate.h +++ b/include/linux/liveupdate.h @@ -231,12 +231,12 @@ bool liveupdate_enabled(void); int liveupdate_reboot(void); =20 int liveupdate_register_file_handler(struct liveupdate_file_handler *fh); -int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh); +void liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh= ); =20 int liveupdate_register_flb(struct liveupdate_file_handler *fh, struct liveupdate_flb *flb); -int liveupdate_unregister_flb(struct liveupdate_file_handler *fh, - struct liveupdate_flb *flb); +void liveupdate_unregister_flb(struct liveupdate_file_handler *fh, + struct liveupdate_flb *flb); =20 int liveupdate_flb_get_incoming(struct liveupdate_flb *flb, void **objp); int liveupdate_flb_get_outgoing(struct liveupdate_flb *flb, void **objp); @@ -258,9 +258,8 @@ static inline int liveupdate_register_file_handler(stru= ct liveupdate_file_handle return -EOPNOTSUPP; } =20 -static inline int liveupdate_unregister_file_handler(struct liveupdate_fil= e_handler *fh) +static inline void liveupdate_unregister_file_handler(struct liveupdate_fi= le_handler *fh) { - return -EOPNOTSUPP; } =20 static inline int liveupdate_register_flb(struct liveupdate_file_handler *= fh, @@ -269,8 +268,8 @@ static inline int liveupdate_register_flb(struct liveup= date_file_handler *fh, return -EOPNOTSUPP; } =20 -static inline int liveupdate_unregister_flb(struct liveupdate_file_handler= *fh, - struct liveupdate_flb *flb) +static inline void liveupdate_unregister_flb(struct liveupdate_file_handle= r *fh, + struct liveupdate_flb *flb) { return -EOPNOTSUPP; } diff --git a/kernel/liveupdate/luo_file.c b/kernel/liveupdate/luo_file.c index 6b2b49cb375e..0fe2f8be8bd1 100644 --- a/kernel/liveupdate/luo_file.c +++ b/kernel/liveupdate/luo_file.c @@ -907,21 +907,17 @@ int liveupdate_register_file_handler(struct liveupdat= e_file_handler *fh) * reverses the operations of liveupdate_register_file_handler(). * * It ensures safe removal by checking that: - * No live update session is currently in progress. * No FLB registered with this file handler. * * If the unregistration fails, the internal test state is reverted. * - * Return: 0 Success. -EOPNOTSUPP when live update is not enabled. -EBUSY = A live - * update is in progress, can't quiesce live update or FLB is registred wi= th - * this file handler. */ -int liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh) +void liveupdate_unregister_file_handler(struct liveupdate_file_handler *fh) { - int err =3D -EBUSY; + bool is_empty; =20 if (!liveupdate_enabled()) - return -EOPNOTSUPP; + return; =20 liveupdate_test_unregister(fh); =20 @@ -929,18 +925,19 @@ int liveupdate_unregister_file_handler(struct liveupd= ate_file_handler *fh) goto err_register; =20 scoped_guard(rwsem_write, &luo_file_handler_lock) { - if (!list_empty(&ACCESS_PRIVATE(fh, flb_list))) - goto err_resume; - - list_del(&ACCESS_PRIVATE(fh, list)); + is_empty =3D list_empty(&ACCESS_PRIVATE(fh, flb_list)); + if (is_empty) + list_del(&ACCESS_PRIVATE(fh, list)); } luo_session_resume(); =20 - return 0; + if (!is_empty) { + pr_warn("Failed to unregister file handler '%s': FLB list not empty\n", + fh->compatible); + liveupdate_test_register(fh); + } + return; =20 -err_resume: - luo_session_resume(); err_register: liveupdate_test_register(fh); - return err; } diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c index daa852abdedd..23fa6e0c6083 100644 --- a/kernel/liveupdate/luo_flb.c +++ b/kernel/liveupdate/luo_flb.c @@ -436,31 +436,17 @@ int liveupdate_register_flb(struct liveupdate_file_ha= ndler *fh, * the FLB is removed from the global registry and the reference to its * owner module (acquired during registration) is released. * - * Context: This function ensures the session is quiesced (no active FDs - * being created) during the update. It is typically called from a - * subsystem's module exit function. - * Return: 0 on success. - * -EOPNOTSUPP if live update is disabled. - * -EBUSY if the live update session is active and cannot be quies= ced. - * -ENOENT if the FLB was not found in the file handler's list. */ -int liveupdate_unregister_flb(struct liveupdate_file_handler *fh, - struct liveupdate_flb *flb) +void liveupdate_unregister_flb(struct liveupdate_file_handler *fh, + struct liveupdate_flb *flb) { struct luo_flb_private *private =3D luo_flb_get_private(flb); struct list_head *flb_list =3D &ACCESS_PRIVATE(fh, flb_list); struct luo_flb_link *iter; - int err =3D -ENOENT; + bool found =3D false; =20 if (!liveupdate_enabled()) - return -EOPNOTSUPP; - - /* - * Ensure the system is quiescent (no active sessions). - * This acts as a global lock for unregistration. - */ - if (!luo_session_quiesce()) - return -EBUSY; + return; =20 guard(rwsem_write)(&luo_flb_lock); guard(rwsem_write)(&ACCESS_PRIVATE(fh, flb_lock)); @@ -470,15 +456,19 @@ int liveupdate_unregister_flb(struct liveupdate_file_= handler *fh, if (iter->flb =3D=3D flb) { list_del(&iter->list); kfree(iter); - err =3D 0; + found =3D true; break; } } =20 - if (err) - goto err_resume; + if (!found) { + pr_warn("Failed to unregister FLB '%s': not found in file handler '%s'\n= ", + flb->compatible, fh->compatible); + return; + } =20 private->users--; + /* * If this is the last file-handler with which we are registred, remove * from the global list, and relese module reference. @@ -487,14 +477,6 @@ int liveupdate_unregister_flb(struct liveupdate_file_h= andler *fh, list_del_init(&private->list); luo_flb_global.count--; } - - luo_session_resume(); - - return 0; - -err_resume: - luo_session_resume(); - return err; } =20 /** diff --git a/lib/tests/liveupdate.c b/lib/tests/liveupdate.c index 496d6ef91a30..5b6abf779f87 100644 --- a/lib/tests/liveupdate.c +++ b/lib/tests/liveupdate.c @@ -137,16 +137,12 @@ void liveupdate_test_register(struct liveupdate_file_= handler *fh) =20 void liveupdate_test_unregister(struct liveupdate_file_handler *fh) { - int err, i; + int i; =20 for (i =3D 0; i < TEST_NFLBS; i++) { struct liveupdate_flb *flb =3D &test_flbs[i]; =20 - err =3D liveupdate_unregister_flb(fh, flb); - if (err) { - pr_err("Failed to unregister %s %pe\n", - flb->compatible, ERR_PTR(err)); - } + liveupdate_unregister_flb(fh, flb); } =20 pr_info("Unregistered %d FLBs from file handler: [%s]\n", --=20 2.53.0.851.ga537e3e6e9-goog