From nobody Sun Feb 8 20:13:06 2026 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (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 C5C8D1FF7B6; Tue, 4 Mar 2025 08:57:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741078629; cv=none; b=SIGlKZpmMzmANtedc+nJb0vRzrEmyfodUcW5tZZ+OBgBGQ/Nu9J5VSxzFgTMkErmO8hFprQg2s6spJCeibQv9wKo9QfJ8ALQwewS2vfwgSdhO+90ydJ/de8hbjYbWlkF+iwAIKZx3Q66RHDmKc2nIYDZw27nBYi/BseHWZcu39M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741078629; c=relaxed/simple; bh=tTLNkw9UR+Ew91hPZTxYJLMyrNyvgny45PnO1KMRiwM=; h=Date:From:To:Subject:Cc:In-Reply-To:References:MIME-Version: Message-ID:Content-Type; b=POhQhGnlUWZIfzE2k2XljuhXanHz4Xv3FyLedkoljDyvN4CjQMJlDdgXb9LVhjrUUUmkhCwe/XYuq1mFRICAp5kNX3ntOoBwiZM/KLGbLI/Quuepg6q3bs84aNsv+qfncdOIwHdxK+OYVz3cRDLV1orwEPIychC7mvjPaSGQsxE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jl3miD1h; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wZd472jg; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jl3miD1h"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wZd472jg" Date: Tue, 04 Mar 2025 08:57:05 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1741078626; h=from:from:sender:sender:reply-to: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=fm7MIFN8rUstK8p3ENSxLJzP9FkW7uMauaXM6M9XaMg=; b=jl3miD1hjDqERHBmvrD/o1UYGcRLOF6SACmPqtnDiNQYXf5m+md7vXsUFfwFRB+cJTVYaZ lh84O7D+7y6SWNyoa7uBb26zxrBsmuckct5MYe3Vxy53mxTXydWYJPwS7kTfPQyyUV8C+W MBNOHMMhygHUjngKmUhqKUEVXMi7dmj6ODMptSEK4oi4atnSFhdzk08R2MwWmLY5kUtYZq a3RjKW+WopJO3CDrtEcFYVX/z2KFbbl/NdZtDvuUfLVZySheHRHBpJuOel8mjVP4OVBphZ QzWHjRapmuYNMrEGqpFy8BeGSzao9H6zOEZRtEDlA2D3xjp8W4W7uRt8wHCEpw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1741078626; h=from:from:sender:sender:reply-to: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=fm7MIFN8rUstK8p3ENSxLJzP9FkW7uMauaXM6M9XaMg=; b=wZd472jgKDZl2E+oWWT03kceb0OcwTkZF+1bAiCECBHaKs2Stb+JAgKnys6DTcP3zXkWwK c1H4CSpBGnIhJiDg== From: "tip-bot2 for Peter Zijlstra" Sender: tip-bot2@linutronix.de Reply-to: linux-kernel@vger.kernel.org To: linux-tip-commits@vger.kernel.org Subject: [tip: perf/core] perf/core: Simplify perf_pmu_register() Cc: "Peter Zijlstra (Intel)" , Ingo Molnar , Ravi Bangoria , x86@kernel.org, linux-kernel@vger.kernel.org In-Reply-To: <20241104135518.198937277@infradead.org> References: <20241104135518.198937277@infradead.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-ID: <174107862567.14745.10433977133332362551.tip-bot2@tip-bot2> Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails Precedence: bulk Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The following commit has been merged into the perf/core branch of tip: Commit-ID: 6c8b0b835f003647e593c08331a4dd2150d5eb0e Gitweb: https://git.kernel.org/tip/6c8b0b835f003647e593c08331a4dd215= 0d5eb0e Author: Peter Zijlstra AuthorDate: Mon, 04 Nov 2024 14:39:15 +01:00 Committer: Ingo Molnar CommitterDate: Tue, 04 Mar 2025 09:42:29 +01:00 perf/core: Simplify perf_pmu_register() Using the previously introduced perf_pmu_free() and a new IDR helper, simplify the perf_pmu_register error paths. Signed-off-by: Peter Zijlstra (Intel) Signed-off-by: Ingo Molnar Acked-by: Ravi Bangoria Link: https://lore.kernel.org/r/20241104135518.198937277@infradead.org --- include/linux/idr.h | 17 ++++++++++- kernel/events/core.c | 71 +++++++++++++++++-------------------------- 2 files changed, 46 insertions(+), 42 deletions(-) diff --git a/include/linux/idr.h b/include/linux/idr.h index da5f5fa..cd729be 100644 --- a/include/linux/idr.h +++ b/include/linux/idr.h @@ -15,6 +15,7 @@ #include #include #include +#include =20 struct idr { struct radix_tree_root idr_rt; @@ -124,6 +125,22 @@ void *idr_get_next_ul(struct idr *, unsigned long *nex= tid); void *idr_replace(struct idr *, void *, unsigned long id); void idr_destroy(struct idr *); =20 +struct __class_idr { + struct idr *idr; + int id; +}; + +#define idr_null ((struct __class_idr){ NULL, -1 }) +#define take_idr_id(id) __get_and_null(id, idr_null) + +DEFINE_CLASS(idr_alloc, struct __class_idr, + if (_T.id >=3D 0) idr_remove(_T.idr, _T.id), + ((struct __class_idr){ + .idr =3D idr, + .id =3D idr_alloc(idr, ptr, start, end, gfp), + }), + struct idr *idr, void *ptr, int start, int end, gfp_t gfp); + /** * idr_init_base() - Initialise an IDR. * @idr: IDR handle. diff --git a/kernel/events/core.c b/kernel/events/core.c index ee5cdd6..215dad5 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -11914,52 +11914,49 @@ static void perf_pmu_free(struct pmu *pmu) free_percpu(pmu->cpu_pmu_context); } =20 -int perf_pmu_register(struct pmu *pmu, const char *name, int type) +DEFINE_FREE(pmu_unregister, struct pmu *, if (_T) perf_pmu_free(_T)) + +int perf_pmu_register(struct pmu *_pmu, const char *name, int type) { - int cpu, ret, max =3D PERF_TYPE_MAX; + int cpu, max =3D PERF_TYPE_MAX; =20 - pmu->type =3D -1; + struct pmu *pmu __free(pmu_unregister) =3D _pmu; + guard(mutex)(&pmus_lock); =20 - mutex_lock(&pmus_lock); - ret =3D -ENOMEM; pmu->pmu_disable_count =3D alloc_percpu(int); if (!pmu->pmu_disable_count) - goto unlock; + return -ENOMEM; =20 - if (WARN_ONCE(!name, "Can not register anonymous pmu.\n")) { - ret =3D -EINVAL; - goto free; - } + if (WARN_ONCE(!name, "Can not register anonymous pmu.\n")) + return -EINVAL; =20 - if (WARN_ONCE(pmu->scope >=3D PERF_PMU_MAX_SCOPE, "Can not register a pmu= with an invalid scope.\n")) { - ret =3D -EINVAL; - goto free; - } + if (WARN_ONCE(pmu->scope >=3D PERF_PMU_MAX_SCOPE, + "Can not register a pmu with an invalid scope.\n")) + return -EINVAL; =20 pmu->name =3D name; =20 if (type >=3D 0) max =3D type; =20 - ret =3D idr_alloc(&pmu_idr, NULL, max, 0, GFP_KERNEL); - if (ret < 0) - goto free; + CLASS(idr_alloc, pmu_type)(&pmu_idr, NULL, max, 0, GFP_KERNEL); + if (pmu_type.id < 0) + return pmu_type.id; =20 - WARN_ON(type >=3D 0 && ret !=3D type); + WARN_ON(type >=3D 0 && pmu_type.id !=3D type); =20 - pmu->type =3D ret; + pmu->type =3D pmu_type.id; atomic_set(&pmu->exclusive_cnt, 0); =20 if (pmu_bus_running && !pmu->dev) { - ret =3D pmu_dev_alloc(pmu); + int ret =3D pmu_dev_alloc(pmu); if (ret) - goto free; + return ret; } =20 - ret =3D -ENOMEM; pmu->cpu_pmu_context =3D alloc_percpu(struct perf_cpu_pmu_context); if (!pmu->cpu_pmu_context) - goto free; + return -ENOMEM; =20 for_each_possible_cpu(cpu) { struct perf_cpu_pmu_context *cpc; @@ -12000,32 +11997,22 @@ int perf_pmu_register(struct pmu *pmu, const char= *name, int type) /* * Now that the PMU is complete, make it visible to perf_try_init_event(). */ - if (!idr_cmpxchg(&pmu_idr, pmu->type, NULL, pmu)) { - ret =3D -EINVAL; - goto free; - } + if (!idr_cmpxchg(&pmu_idr, pmu->type, NULL, pmu)) + return -EINVAL; list_add_rcu(&pmu->entry, &pmus); =20 - ret =3D 0; -unlock: - mutex_unlock(&pmus_lock); - - return ret; - -free: - if (pmu->type >=3D 0) - idr_remove(&pmu_idr, pmu->type); - perf_pmu_free(pmu); - goto unlock; + take_idr_id(pmu_type); + _pmu =3D no_free_ptr(pmu); // let it rip + return 0; } EXPORT_SYMBOL_GPL(perf_pmu_register); =20 void perf_pmu_unregister(struct pmu *pmu) { - mutex_lock(&pmus_lock); - list_del_rcu(&pmu->entry); - idr_remove(&pmu_idr, pmu->type); - mutex_unlock(&pmus_lock); + scoped_guard (mutex, &pmus_lock) { + list_del_rcu(&pmu->entry); + idr_remove(&pmu_idr, pmu->type); + } =20 /* * We dereference the pmu list under both SRCU and regular RCU, so