From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 41A6E397B1B for ; Tue, 12 May 2026 13:50:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778593802; cv=none; b=fb5wcWIvE3xly2PS3sdd+kJVuu7BtKWpCBX8uI4KDoPCNr3nYwwJYVqlpezRUx83qONPk2q5S0+qyfFs+yb4yqjEIosHM+8d2L0mUCPLupnsNIBqbNkL3KImJQRBE6wZ/Kdhmd1xiIWOR3zwtXuATdzMjaAocyMF6/xL71xDAQI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778593802; c=relaxed/simple; bh=/IrE2X/ChtbsCAqyD7eEuZdbSQgtcgol+vm8r9sXbTI=; h=Subject:To:Cc:From:Date:Message-ID:MIME-Version:Content-Type; b=feMd4dFUawCxxtxArUuyAJUlo7UB3TyA0VyJqJLklUV0tMzaDAM4XuglufrVq3CVhoMSO9uhV2shNIXaSeVHw+XXGc/iwLx6ANt9e2x9i6xrO5haBdYMfxBXYsAmwqph4fw1y/ZH204O0m/4rVwEjwJWE697K6Ng7e7vARjedcc= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=QS6QLFHM; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="QS6QLFHM" Received: by smtp.kernel.org (Postfix) with ESMTPSA id B04EAC2BCB0; Tue, 12 May 2026 13:50:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1778593802; bh=/IrE2X/ChtbsCAqyD7eEuZdbSQgtcgol+vm8r9sXbTI=; h=Subject:To:Cc:From:Date:From; b=QS6QLFHMom6XHE9/AwwRLUvisoev9tcd+otoRTIHu6Lm3Wjs2JPYvDRrVcdDdCU6a lY7qFOtMemqzQl8lN/VCOM/mOoGPgBP6RwAQY3UacN8yqwC9Bkm9C/a8JI7CIorRag ZwhJD4tNY1PYgPa0waRQvHc3hYIPHt18Fc799pJY= Subject: FAILED: patch "[PATCH] tracing/fprobe: Remove fprobe from hash in failure path" failed to apply to 6.18-stable tree To: mhiramat@kernel.org Cc: From: Date: Tue, 12 May 2026 15:50:06 +0200 Message-ID: <2026051206-mocker-bonfire-ac1c@gregkh> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=ANSI_X3.4-1968 Content-Transfer-Encoding: 8bit The patch below does not apply to the 6.18-stable tree. If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to . To reproduce the conflict and resubmit, you may use the following commands: git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y git checkout FETCH_HEAD git cherry-pick -x 845947aca6814f5723ed65e556eb5ee09493f05b # git commit -s git send-email --to '' --in-reply-to '2026051206-mocker-bonfire-ac1c@gregkh' --subject-prefix 'PATCH 6.18.y' HEAD^.. Possible dependencies: thanks, greg k-h ------------------ original commit in Linus's tree ------------------ >From 845947aca6814f5723ed65e556eb5ee09493f05b Mon Sep 17 00:00:00 2001 From: "Masami Hiramatsu (Google)" Date: Mon, 20 Apr 2026 23:01:04 +0900 Subject: [PATCH] tracing/fprobe: Remove fprobe from hash in failure path When register_fprobe_ips() fails, it tries to remove a list of fprobe_hash_node from fprobe_ip_table, but it missed to remove fprobe itself from fprobe_table. Moreover, when removing the fprobe_hash_node which is added to rhltable once, it must use kfree_rcu() after removing from rhltable. To fix these issues, this reuses unregister_fprobe() internal code to rollback the half-way registered fprobe. Link: https://lore.kernel.org/all/177669366417.132053.17874946321744910456.stgit@mhiramat.tok.corp.google.com/ Fixes: 4346ba160409 ("fprobe: Rewrite fprobe on function-graph tracer") Cc: stable@vger.kernel.org Signed-off-by: Masami Hiramatsu (Google) diff --git a/kernel/trace/fprobe.c b/kernel/trace/fprobe.c index a2b659006e0e..621477ad0947 100644 --- a/kernel/trace/fprobe.c +++ b/kernel/trace/fprobe.c @@ -79,20 +79,27 @@ static const struct rhashtable_params fprobe_rht_params = { }; /* Node insertion and deletion requires the fprobe_mutex */ -static int insert_fprobe_node(struct fprobe_hlist_node *node) +static int insert_fprobe_node(struct fprobe_hlist_node *node, struct fprobe *fp) { + int ret; + lockdep_assert_held(&fprobe_mutex); - return rhltable_insert(&fprobe_ip_table, &node->hlist, fprobe_rht_params); + ret = rhltable_insert(&fprobe_ip_table, &node->hlist, fprobe_rht_params); + /* Set the fprobe pointer if insertion was successful. */ + if (!ret) + WRITE_ONCE(node->fp, fp); + return ret; } /* Return true if there are synonims */ static bool delete_fprobe_node(struct fprobe_hlist_node *node) { - lockdep_assert_held(&fprobe_mutex); bool ret; - /* Avoid double deleting */ + lockdep_assert_held(&fprobe_mutex); + + /* Avoid double deleting and non-inserted nodes */ if (READ_ONCE(node->fp) != NULL) { WRITE_ONCE(node->fp, NULL); rhltable_remove(&fprobe_ip_table, &node->hlist, @@ -756,7 +763,6 @@ static int fprobe_init(struct fprobe *fp, unsigned long *addrs, int num) fp->hlist_array = hlist_array; hlist_array->fp = fp; for (i = 0; i < num; i++) { - hlist_array->array[i].fp = fp; addr = ftrace_location(addrs[i]); if (!addr) { fprobe_fail_cleanup(fp); @@ -820,6 +826,8 @@ int register_fprobe(struct fprobe *fp, const char *filter, const char *notfilter } EXPORT_SYMBOL_GPL(register_fprobe); +static int unregister_fprobe_nolock(struct fprobe *fp); + /** * register_fprobe_ips() - Register fprobe to ftrace by address. * @fp: A fprobe data structure to be registered. @@ -846,28 +854,25 @@ int register_fprobe_ips(struct fprobe *fp, unsigned long *addrs, int num) if (ret) return ret; - hlist_array = fp->hlist_array; if (fprobe_is_ftrace(fp)) ret = fprobe_ftrace_add_ips(addrs, num); else ret = fprobe_graph_add_ips(addrs, num); - - if (!ret) { - add_fprobe_hash(fp); - for (i = 0; i < hlist_array->size; i++) { - ret = insert_fprobe_node(&hlist_array->array[i]); - if (ret) - break; - } - /* fallback on insert error */ - if (ret) { - for (i--; i >= 0; i--) - delete_fprobe_node(&hlist_array->array[i]); - } + if (ret) { + fprobe_fail_cleanup(fp); + return ret; } - if (ret) - fprobe_fail_cleanup(fp); + hlist_array = fp->hlist_array; + ret = add_fprobe_hash(fp); + for (i = 0; i < hlist_array->size && !ret; i++) + ret = insert_fprobe_node(&hlist_array->array[i], fp); + + if (ret) { + unregister_fprobe_nolock(fp); + /* In error case, wait for clean up safely. */ + synchronize_rcu(); + } return ret; } @@ -911,27 +916,12 @@ bool fprobe_is_registered(struct fprobe *fp) return true; } -/** - * unregister_fprobe() - Unregister fprobe. - * @fp: A fprobe data structure to be unregistered. - * - * Unregister fprobe (and remove ftrace hooks from the function entries). - * - * Return 0 if @fp is unregistered successfully, -errno if not. - */ -int unregister_fprobe(struct fprobe *fp) +static int unregister_fprobe_nolock(struct fprobe *fp) { - struct fprobe_hlist *hlist_array; + struct fprobe_hlist *hlist_array = fp->hlist_array; unsigned long *addrs = NULL; - int ret = 0, i, count; + int i, count; - mutex_lock(&fprobe_mutex); - if (!fp || !fprobe_registered(fp)) { - ret = -EINVAL; - goto out; - } - - hlist_array = fp->hlist_array; addrs = kcalloc(hlist_array->size, sizeof(unsigned long), GFP_KERNEL); /* * This will remove fprobe_hash_node from the hash table even if @@ -957,12 +947,26 @@ int unregister_fprobe(struct fprobe *fp) kfree_rcu(hlist_array, rcu); fp->hlist_array = NULL; - -out: - mutex_unlock(&fprobe_mutex); - kfree(addrs); - return ret; + + return 0; +} + +/** + * unregister_fprobe() - Unregister fprobe. + * @fp: A fprobe data structure to be unregistered. + * + * Unregister fprobe (and remove ftrace hooks from the function entries). + * + * Return 0 if @fp is unregistered successfully, -errno if not. + */ +int unregister_fprobe(struct fprobe *fp) +{ + guard(mutex)(&fprobe_mutex); + if (!fp || !fprobe_registered(fp)) + return -EINVAL; + + return unregister_fprobe_nolock(fp); } EXPORT_SYMBOL_GPL(unregister_fprobe);