* Re: [PATCH 2/3] tracing: add more symbols to whitelist
From: Vincent Donnefort @ 2026-03-12 13:40 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Marc Zyngier, Steven Rostedt, Oliver Upton, Catalin Marinas,
Will Deacon, Arnd Bergmann, Masami Hiramatsu, Mathieu Desnoyers,
linux-kernel, linux-trace-kernel
In-Reply-To: <20260312123601.625063-2-arnd@kernel.org>
On Thu, Mar 12, 2026 at 01:35:43PM +0100, Arnd Bergmann wrote:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Randconfig builds show a number of cryptic build errors from
> hitting undefined symbols in simple_ring_buffer.o:
>
> make[7]: *** [/home/arnd/arm-soc/kernel/trace/Makefile:147: kernel/trace/simple_ring_buffer.o.checked] Error 1
>
> These happen with CONFIG_TRACE_BRANCH_PROFILING, CONFIG_KASAN_HW_TAGS,
> CONFIG_STACKPROTECTOR, CONFIG_DEBUG_IRQFLAGS and indirectly from WARN_ON().
>
> Add exceptions for each one that I have hit so far on arm64, x86_64 and arm
> randconfig builds.
>
> Other architectures likely hit additional ones, so it would be nice
> to produce a little more verbose output that include the name of the
> missing symbols directly.
>
> Fixes: a717943d8ecc ("tracing: Check for undefined symbols in simple_ring_buffer")
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
> kernel/trace/Makefile | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
> index 3182e1bc1cf7..e3f8d6e619d2 100644
> --- a/kernel/trace/Makefile
> +++ b/kernel/trace/Makefile
> @@ -138,6 +138,8 @@ obj-$(CONFIG_TRACE_REMOTE_TEST) += remote_test.o
> #
> UNDEFINED_ALLOWLIST := memset alt_cb_patch_nops __x86 __ubsan __asan __kasan __gcov __aeabi_unwind
> UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer
> +UNDEFINED_ALLOWLIST += ftrace_likely_update __hwasan_load __hwasan_store __hwasan_tag_memory
> +UNDEFINED_ALLOWLIST += warn_bogus_irq_restore warn_slowpath_fmt __stack_chk_guard
> UNDEFINED_ALLOWLIST := $(addprefix -e , $(UNDEFINED_ALLOWLIST))
>
> quiet_cmd_check_undefined = NM $<
> --
> 2.39.5
>
Thanks for the patch.
Most of those ones are covered here
https://lore.kernel.org/all/20260312113535.2213350-1-vdonnefort@google.com/.
This should fix allmodconfig.
For the ones not covered, I'm working on a follow-up patch using a different
approach which should fix them. I'll be able to share it today or tomorrow. Not
sure if we want to take this temporarily?
^ permalink raw reply
* Re: [PATCH v7 14/15] rv: Add deadline monitors
From: Juri Lelli @ 2026-03-12 13:37 UTC (permalink / raw)
To: Gabriele Monaco
Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
Jonathan Corbet, Masami Hiramatsu, linux-trace-kernel, linux-doc,
Peter Zijlstra, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <20260310105627.332044-15-gmonaco@redhat.com>
Hello,
On 10/03/26 11:56, Gabriele Monaco wrote:
...
> +/* Used by other monitors */
> +struct sched_class *rv_ext_sched_class;
> +
> +static int __init register_deadline(void)
> +{
> + if (IS_ENABLED(CONFIG_SCHED_CLASS_EXT))
> + rv_ext_sched_class = (void *)kallsyms_lookup_name("ext_sched_class");
Looks like the above look up can fail. I don't actually see how/why if
would fail if things build correctly and EXT tasks are around. But,
theoretically, we could end up with rv_ext_sched_class = NULL ?
...
> +static inline bool task_is_scx_enabled(struct task_struct *tsk)
> +{
> + return IS_ENABLED(CONFIG_SCHED_CLASS_EXT) &&
> + tsk->sched_class == rv_ext_sched_class;
> +}
> +
> +/* Expand id and target as arguments for da functions */
> +#define EXPAND_ID(dl_se, cpu, type) get_entity_id(dl_se, cpu, type), dl_se
> +#define EXPAND_ID_TASK(tsk) get_entity_id(&tsk->dl, task_cpu(tsk), DL_TASK), &tsk->dl
> +
> +static inline uint8_t get_server_type(struct task_struct *tsk)
> +{
> + if (tsk->policy == SCHED_NORMAL || tsk->policy == SCHED_EXT ||
> + tsk->policy == SCHED_BATCH || tsk->policy == SCHED_IDLE)
> + return task_is_scx_enabled(tsk) ? DL_SERVER_EXT : DL_SERVER_FAIR;
> + return DL_OTHER;
> +}
Considering that, if that happens, get_server_type() will return
DL_SERVER_FAIR for scx tasks as well (possibly confusing monitors?),
shall we add a warn or something just in case. A 'no we don't need that
because it can't happen' works for me, just thought I should still
mention this. :)
Thanks,
Juri
^ permalink raw reply
* Re: [PATCH] tracing: Update undefined symbols allow list for simple_ring_buffer
From: Steven Rostedt @ 2026-03-12 13:33 UTC (permalink / raw)
To: Vincent Donnefort
Cc: maz, linux-trace-kernel, kvmarm, kernel-team, Nathan Chancellor
In-Reply-To: <20260312113535.2213350-1-vdonnefort@google.com>
On Thu, 12 Mar 2026 11:35:35 +0000
Vincent Donnefort <vdonnefort@google.com> wrote:
> Undefined symbols are not allowed for simple_ring_buffer.c. But some
> compiler emitted symbols are missing in the allowlist. Update it.
>
Should add:
Fixes: a717943d8ecc ("tracing: Check for undefined symbols in simple_ring_buffer")
Closes: https://lore.kernel.org/all/20260311221816.GA316631@ax162/
> Reported-by: Nathan Chancellor <nathan@kernel.org>
> Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Should this go through the arm tree or mine?
I'm fine with either, and in case the arm tree:
Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>
-- Steve
>
> diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
> index 3182e1bc1cf7..3cc490aadc99 100644
> --- a/kernel/trace/Makefile
> +++ b/kernel/trace/Makefile
> @@ -137,7 +137,8 @@ obj-$(CONFIG_TRACE_REMOTE_TEST) += remote_test.o
> # to all kernel symbols. Fail the build if forbidden symbols are found.
> #
> UNDEFINED_ALLOWLIST := memset alt_cb_patch_nops __x86 __ubsan __asan __kasan __gcov __aeabi_unwind
> -UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer
> +UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer llvm_gcda llvm_gcov
> +UNDEFINED_ALLOWLIST += .TOC\. __clear_pages_unrolled __memmove copy_page warn_slowpath_fmt
> UNDEFINED_ALLOWLIST := $(addprefix -e , $(UNDEFINED_ALLOWLIST))
>
> quiet_cmd_check_undefined = NM $<
>
> base-commit: 455baa581922086f1ad44c76d4a3b03c265ee950
^ permalink raw reply
* Re: [PATCH v7 12/15] sched: Add deadline tracepoints
From: Juri Lelli @ 2026-03-12 13:07 UTC (permalink / raw)
To: Gabriele Monaco
Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
Masami Hiramatsu, Ingo Molnar, Peter Zijlstra, linux-trace-kernel,
Phil Auld, Tomas Glozar, Clark Williams, John Kacur
In-Reply-To: <20260310105627.332044-13-gmonaco@redhat.com>
Hello,
On 10/03/26 11:56, Gabriele Monaco wrote:
> Add the following tracepoints:
>
> * sched_dl_throttle(dl_se, cpu, type):
> Called when a deadline entity is throttled
> * sched_dl_replenish(dl_se, cpu, type):
> Called when a deadline entity's runtime is replenished
> * sched_dl_update(dl_se, cpu, type):
> Called when a deadline entity updates without throttle or replenish
> * sched_dl_server_start(dl_se, cpu, type):
> Called when a deadline server is started
> * sched_dl_server_stop(dl_se, cpu, type):
> Called when a deadline server is stopped
>
> Those tracepoints can be useful to validate the deadline scheduler with
> RV and are not exported to tracefs.
>
> Reviewed-by: Phil Auld <pauld@redhat.com>
> Signed-off-by: Gabriele Monaco <gmonaco@redhat.com>
Looks good to me.
Acked-by: Juri Lelli <juri.lelli@redhat.com>
Best,
Juri
^ permalink raw reply
* Re: [PATCH 00/61] treewide: Use IS_ERR_OR_NULL over manual NULL check - refactor
From: Jason Gunthorpe @ 2026-03-12 12:57 UTC (permalink / raw)
To: Kuan-Wei Chiu
Cc: Philipp Hahn, amd-gfx, apparmor, bpf, ceph-devel, cocci, dm-devel,
dri-devel, gfs2, intel-gfx, intel-wired-lan, iommu, kvm,
linux-arm-kernel, linux-block, linux-bluetooth, linux-btrfs,
linux-cifs, linux-clk, linux-erofs, linux-ext4, linux-fsdevel,
linux-gpio, linux-hyperv, linux-input, linux-kernel, linux-leds,
linux-media, linux-mips, linux-mm, linux-modules, linux-mtd,
linux-nfs, linux-omap, linux-phy, linux-pm, linux-rockchip,
linux-s390, linux-scsi, linux-sctp, linux-security-module,
linux-sh, linux-sound, linux-stm32, linux-trace-kernel, linux-usb,
linux-wireless, netdev, ntfs3, samba-technical, sched-ext,
target-devel, tipc-discussion, v9fs
In-Reply-To: <abBlpGKO842B3yl9@google.com>
On Wed, Mar 11, 2026 at 02:40:36AM +0800, Kuan-Wei Chiu wrote:
> IMHO, the necessity of IS_ERR_OR_NULL() often highlights a confusing or
> flawed API design. It usually implies that the caller is unsure whether
> a failure results in an error pointer or a NULL pointer.
+1
IS_ERR_OR_NULL() should always be looked on with suspicion. Very
little should be returning some tri-state 'ERR' 'NULL' 'SUCCESS'
pointer. What does the middle condition even mean? IS_ERR_OR_NULL()
implies ERR and NULL are semanticly the same, so fix the things to
always use ERR.
If you want to improve things work to get rid of the NULL checks this
script identifies. Remove ERR or NULL because only one can ever
happen, or fix the source to consistently return ERR.
Jason
^ permalink raw reply
* Re: [PATCH bpf-next] ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod
From: Jiri Olsa @ 2026-03-12 12:38 UTC (permalink / raw)
To: bot+bpf-ci
Cc: rostedt, ast, bpf, linux-kernel, linux-trace-kernel, daniel,
andrii, menglong8.dong, song, martin.lau, eddyz87, yonghong.song,
clm, ihor.solodrai
In-Reply-To: <ab12d6dc347ea5a2ffe8705e1538043beb0f497b4a906410a10fabeceeb10e70@mail.kernel.org>
On Thu, Mar 12, 2026 at 12:24:24PM +0000, bot+bpf-ci@kernel.org wrote:
> > diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> > index 8df69e702706..71dcbfeac86c 100644
> > --- a/kernel/trace/ftrace.c
> > +++ b/kernel/trace/ftrace.c
> > @@ -6608,7 +6608,7 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b
> >
> > /* Enable the tmp_ops to have the same functions as the direct ops */
> > ftrace_ops_init(&tmp_ops);
> > - tmp_ops.func_hash = ops->func_hash;
> > + tmp_ops.func_hash->filter_hash = hash;
>
> The comment above says "Enable the tmp_ops to have the same functions
> as the direct ops", but after this change tmp_ops only gets the
> modified subset via the hash argument, not all of the direct ops
> functions. Should the comment be updated to reflect this?
>
> Also, the commit message has a minor grammar issue:
>
> > which contains only the modified sites is always a subset of the
> > ops->func_hash.
>
> Reads like it is missing an "and" between "sites" and "is".
yep, sent v2
jirka
^ permalink raw reply
* [PATCHv2 bpf-next] ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod
From: Jiri Olsa @ 2026-03-12 12:37 UTC (permalink / raw)
To: Steven Rostedt, Alexei Starovoitov
Cc: bpf, linux-kernel, linux-trace-kernel, Daniel Borkmann,
Andrii Nakryiko, Menglong Dong, Song Liu
The modify logic registers temporary ftrace_ops object (tmp_ops) to trigger
the slow path for all direct callers to be able to safely modify attached
addresses.
At the moment we use ops->func_hash for tmp_ops filter, which represents all
the systems attachments. It's faster to use just the passed hash filter, which
contains only the modified sites and is always a subset of the ops->func_hash.
Fixes: e93672f770d7 ("ftrace: Add update_ftrace_direct_mod function")
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/trace/ftrace.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
v2 changes:
- updated comment and changelog [ci]
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8df69e702706..413310912609 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6606,9 +6606,9 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b
if (!orig_hash)
goto unlock;
- /* Enable the tmp_ops to have the same functions as the direct ops */
+ /* Enable the tmp_ops to have the same functions as the hash object. */
ftrace_ops_init(&tmp_ops);
- tmp_ops.func_hash = ops->func_hash;
+ tmp_ops.func_hash->filter_hash = hash;
err = register_ftrace_function_nolock(&tmp_ops);
if (err)
--
2.53.0
^ permalink raw reply related
* [PATCH 2/3] tracing: add more symbols to whitelist
From: Arnd Bergmann @ 2026-03-12 12:35 UTC (permalink / raw)
To: Vincent Donnefort, Marc Zyngier
Cc: Steven Rostedt, Oliver Upton, Catalin Marinas, Will Deacon,
Arnd Bergmann, Masami Hiramatsu, Mathieu Desnoyers, linux-kernel,
linux-trace-kernel
In-Reply-To: <20260312123601.625063-1-arnd@kernel.org>
From: Arnd Bergmann <arnd@arndb.de>
Randconfig builds show a number of cryptic build errors from
hitting undefined symbols in simple_ring_buffer.o:
make[7]: *** [/home/arnd/arm-soc/kernel/trace/Makefile:147: kernel/trace/simple_ring_buffer.o.checked] Error 1
These happen with CONFIG_TRACE_BRANCH_PROFILING, CONFIG_KASAN_HW_TAGS,
CONFIG_STACKPROTECTOR, CONFIG_DEBUG_IRQFLAGS and indirectly from WARN_ON().
Add exceptions for each one that I have hit so far on arm64, x86_64 and arm
randconfig builds.
Other architectures likely hit additional ones, so it would be nice
to produce a little more verbose output that include the name of the
missing symbols directly.
Fixes: a717943d8ecc ("tracing: Check for undefined symbols in simple_ring_buffer")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
kernel/trace/Makefile | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 3182e1bc1cf7..e3f8d6e619d2 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -138,6 +138,8 @@ obj-$(CONFIG_TRACE_REMOTE_TEST) += remote_test.o
#
UNDEFINED_ALLOWLIST := memset alt_cb_patch_nops __x86 __ubsan __asan __kasan __gcov __aeabi_unwind
UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer
+UNDEFINED_ALLOWLIST += ftrace_likely_update __hwasan_load __hwasan_store __hwasan_tag_memory
+UNDEFINED_ALLOWLIST += warn_bogus_irq_restore warn_slowpath_fmt __stack_chk_guard
UNDEFINED_ALLOWLIST := $(addprefix -e , $(UNDEFINED_ALLOWLIST))
quiet_cmd_check_undefined = NM $<
--
2.39.5
^ permalink raw reply related
* Re: [PATCH v2 7/8] RDMA/umem: Tell DMA mapping that UMEM requires coherency
From: Jason Gunthorpe @ 2026-03-12 12:34 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Marek Szyprowski, Robin Murphy, Michael S. Tsirkin, Petr Tesarik,
Jonathan Corbet, Shuah Khan, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Joerg Roedel, Will Deacon, Andrew Morton,
iommu, linux-kernel, linux-doc, virtualization, linux-rdma,
linux-trace-kernel, linux-mm
In-Reply-To: <20260311-dma-debug-overlap-v2-7-e00bc2ca346d@nvidia.com>
On Wed, Mar 11, 2026 at 09:08:50PM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> The RDMA subsystem exposes DMA regions through the verbs interface, which
> assumes a coherent system. Use the DMA_ATTR_REQUIRE_COHERENCE attribute to
> ensure coherency and avoid taking the SWIOTLB path.
Lets elaborate a bit more so people understand why verbs is like
this:
The RDMA verbs programming model is like HMM and assumes concurrent DMA and
CPU access to userspace memory in a process. The HW device and
programming model has so-called "one-sided" operations which are
initiated over the network by a remote CPU without notification or
involvement of the local CPU. These include things like ATOMIC
compare/swap, READ, and WRITE. Using these operations a remote CPU can
traverse data structures, form locks, and so on without awareness of
the host CPU. Having SWIOTLB substitute the memory or the DMA be cache
incoherent completely breaks these use cases.
RDMA in-kernel is OK with incoherence because none of the kernel use
cases make use of one-sided operations that would cause problems.
Jason
^ permalink raw reply
* Re: [PATCH v2 8/8] mm/hmm: Indicate that HMM requires DMA coherency
From: Jason Gunthorpe @ 2026-03-12 12:26 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Marek Szyprowski, Robin Murphy, Michael S. Tsirkin, Petr Tesarik,
Jonathan Corbet, Shuah Khan, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Joerg Roedel, Will Deacon, Andrew Morton,
iommu, linux-kernel, linux-doc, virtualization, linux-rdma,
linux-trace-kernel, linux-mm
In-Reply-To: <20260311-dma-debug-overlap-v2-8-e00bc2ca346d@nvidia.com>
On Wed, Mar 11, 2026 at 09:08:51PM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> HMM mirroring can work on coherent systems without SWIOTLB path only.
> Until introduction of DMA_ATTR_REQUIRE_COHERENT, there was no reliable
> way to indicate that and various approximation was done:
HMM is fundamentally about allowing a sophisticated device to
independently DMA to a process's memory concurrently with the CPU
accessing the same memory. It is similar to SVA but does not rely on
IOMMU support. Since the entire use model is concurrent access to the
same memory it becomes fatally broken as a uAPI if SWIOTLB is
replacing the memory, or the CPU caches are incoherent with DMA.
Till now there was no reliable way to indicate that and various
approximation was done:
> int hmm_dma_map_alloc(struct device *dev, struct hmm_dma_map *map,
> size_t nr_entries, size_t dma_entry_size)
> {
> <...>
> /*
> * The HMM API violates our normal DMA buffer ownership rules and can't
> * transfer buffer ownership. The dma_addressing_limited() check is a
> * best approximation to ensure no swiotlb buffering happens.
> */
> dma_need_sync = !dev->dma_skip_sync;
> if (dma_need_sync || dma_addressing_limited(dev))
> return -EOPNOTSUPP;
Can it get dropped now then?
> So let's mark mapped buffers with DMA_ATTR_REQUIRE_COHERENT attribute
> to prevent DMA debugging warnings for cache overlapped entries.
Well, that isn't the main motivation, this prevents silent data
corruption if someone tries to use hmm in a system with swiotlb or
incoherent DMA,
Looks OK otherwise
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply
* Re: [PATCH bpf-next] ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod
From: bot+bpf-ci @ 2026-03-12 12:24 UTC (permalink / raw)
To: jolsa, rostedt, ast
Cc: bpf, linux-kernel, linux-trace-kernel, daniel, andrii,
menglong8.dong, song, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, clm, ihor.solodrai
In-Reply-To: <20260312114746.122174-1-jolsa@kernel.org>
[-- Attachment #1: Type: text/plain, Size: 1158 bytes --]
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 8df69e702706..71dcbfeac86c 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -6608,7 +6608,7 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b
>
> /* Enable the tmp_ops to have the same functions as the direct ops */
> ftrace_ops_init(&tmp_ops);
> - tmp_ops.func_hash = ops->func_hash;
> + tmp_ops.func_hash->filter_hash = hash;
The comment above says "Enable the tmp_ops to have the same functions
as the direct ops", but after this change tmp_ops only gets the
modified subset via the hash argument, not all of the direct ops
functions. Should the comment be updated to reflect this?
Also, the commit message has a minor grammar issue:
> which contains only the modified sites is always a subset of the
> ops->func_hash.
Reads like it is missing an "and" between "sites" and "is".
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23000924618
^ permalink raw reply
* Re: [PATCH v2 7/8] RDMA/umem: Tell DMA mapping that UMEM requires coherency
From: Jason Gunthorpe @ 2026-03-12 12:22 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Marek Szyprowski, Robin Murphy, Michael S. Tsirkin, Petr Tesarik,
Jonathan Corbet, Shuah Khan, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Joerg Roedel, Will Deacon, Andrew Morton,
iommu, linux-kernel, linux-doc, virtualization, linux-rdma,
linux-trace-kernel, linux-mm
In-Reply-To: <20260311-dma-debug-overlap-v2-7-e00bc2ca346d@nvidia.com>
On Wed, Mar 11, 2026 at 09:08:50PM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> The RDMA subsystem exposes DMA regions through the verbs interface, which
> assumes a coherent system. Use the DMA_ATTR_REQUIRE_COHERENCE attribute to
> ensure coherency and avoid taking the SWIOTLB path.
>
> In addition, a given region may be exported multiple times, which will trigger
> warnings about cacheline overlaps. These warnings are suppressed when using
> the new attribute.
> Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
> ---
> drivers/infiniband/core/umem.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
Reviewed-by: Jason Gunthorpe <jgg@nvidia.com>
Jason
^ permalink raw reply
* Re: [PATCH v2 5/8] dma-direct: prevent SWIOTLB path when DMA_ATTR_REQUIRE_COHERENT is set
From: Jason Gunthorpe @ 2026-03-12 12:20 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Marek Szyprowski, Robin Murphy, Michael S. Tsirkin, Petr Tesarik,
Jonathan Corbet, Shuah Khan, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Joerg Roedel, Will Deacon, Andrew Morton,
iommu, linux-kernel, linux-doc, virtualization, linux-rdma,
linux-trace-kernel, linux-mm
In-Reply-To: <20260311-dma-debug-overlap-v2-5-e00bc2ca346d@nvidia.com>
On Wed, Mar 11, 2026 at 09:08:48PM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> DMA_ATTR_REQUIRE_COHERENT indicates that SWIOTLB must not be used.
> Ensure the SWIOTLB path is declined whenever the DMA direct path is
> selected.
>
> Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
> ---
> kernel/dma/direct.h | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/kernel/dma/direct.h b/kernel/dma/direct.h
> index e89f175e9c2d0..6184ff303f080 100644
> --- a/kernel/dma/direct.h
> +++ b/kernel/dma/direct.h
> @@ -84,7 +84,7 @@ static inline dma_addr_t dma_direct_map_phys(struct device *dev,
> dma_addr_t dma_addr;
>
> if (is_swiotlb_force_bounce(dev)) {
> - if (attrs & DMA_ATTR_MMIO)
> + if (attrs & (DMA_ATTR_MMIO | DMA_ATTR_REQUIRE_COHERENT))
> return DMA_MAPPING_ERROR;
>
> return swiotlb_map(dev, phys, size, dir, attrs);
Oh here it is, still maybe it is better to put it in swiotlb_map() ?
Jason
^ permalink raw reply
* Re: [PATCH v2 4/8] dma-mapping: Introduce DMA require coherency attribute
From: Jason Gunthorpe @ 2026-03-12 12:19 UTC (permalink / raw)
To: Leon Romanovsky
Cc: Marek Szyprowski, Robin Murphy, Michael S. Tsirkin, Petr Tesarik,
Jonathan Corbet, Shuah Khan, Jason Wang, Xuan Zhuo,
Eugenio Pérez, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Joerg Roedel, Will Deacon, Andrew Morton,
iommu, linux-kernel, linux-doc, virtualization, linux-rdma,
linux-trace-kernel, linux-mm
In-Reply-To: <20260311-dma-debug-overlap-v2-4-e00bc2ca346d@nvidia.com>
On Wed, Mar 11, 2026 at 09:08:47PM +0200, Leon Romanovsky wrote:
> From: Leon Romanovsky <leonro@nvidia.com>
>
> The mapping buffers which carry this attribute require DMA coherent system.
> This means that they can't take SWIOTLB path, can perform CPU cache overlap
> and doesn't perform cache flushing.
>
> Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
> ---
> Documentation/core-api/dma-attributes.rst | 12 ++++++++++++
> include/linux/dma-mapping.h | 7 +++++++
> include/trace/events/dma.h | 3 ++-
> kernel/dma/debug.c | 3 ++-
> kernel/dma/mapping.c | 6 ++++++
> 5 files changed, 29 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/core-api/dma-attributes.rst b/Documentation/core-api/dma-attributes.rst
> index 48cfe86cc06d7..69d094f144c70 100644
> --- a/Documentation/core-api/dma-attributes.rst
> +++ b/Documentation/core-api/dma-attributes.rst
> @@ -163,3 +163,15 @@ data corruption.
>
> All mappings that share a cache line must set this attribute to suppress DMA
> debug warnings about overlapping mappings.
> +
> +DMA_ATTR_REQUIRE_COHERENT
> +-------------------------
> +
> +The mapping buffers which carry this attribute require DMA coherent system. This means
> +that they can't take SWIOTLB path, can perform CPU cache overlap and doesn't perform
> +cache flushing.
DMA mapping requests with the DMA_ATTR_REQUIRE_COHERENT fail on any
system where SWIOTLB or cache management is required. This should only
be used to support uAPI designs that require continuous HW DMA
coherence with userspace processes, for example RDMA and DRM. At a
minimum the memory being mapped must be userspace memory from
pin_user_pages() or similar.
Drivers should consider using dma_mmap_pages() instead of this
interface when building their uAPIs, when possible.
It must never be used in an in-kernel driver that only works with
kernal memory.
> @@ -164,6 +164,9 @@ dma_addr_t dma_map_phys(struct device *dev, phys_addr_t phys, size_t size,
> if (WARN_ON_ONCE(!dev->dma_mask))
> return DMA_MAPPING_ERROR;
>
> + if (!dev_is_dma_coherent(dev) && (attrs & DMA_ATTR_REQUIRE_COHERENT))
> + return DMA_MAPPING_ERROR;
This doesn't capture enough conditions.. is_swiotlb_force_bounce(),
dma_kmalloc_needs_bounce(), dma_capable(), etc all need to be blocked
too
So check it inside swiotlb_map() too, and maybe shift the above
into the existing branches:
if (!dev_is_dma_coherent(dev) &&
!(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO)))
arch_sync_dma_for_device(phys, size, dir);
Jason
^ permalink raw reply
* Re: [PATCH v4 12/18] rtla: Enforce exact match for time unit suffixes
From: Tomas Glozar @ 2026-03-12 12:17 UTC (permalink / raw)
To: Wander Lairson Costa
Cc: Steven Rostedt, Crystal Wood, Ivan Pravdin, Costa Shulyupin,
John Kacur, Tiezhu Yang, Daniel Bristot de Oliveira,
Daniel Wagner, open list:Real-time Linux Analysis (RTLA) tools,
open list:Real-time Linux Analysis (RTLA) tools,
open list:BPF [MISC]:Keyword:(?:b|_)bpf(?:b|_)
In-Reply-To: <20260309195040.1019085-13-wander@redhat.com>
po 9. 3. 2026 v 20:58 odesílatel Wander Lairson Costa
<wander@redhat.com> napsal:
>
> The parse_ns_duration() function currently uses prefix matching for
> detecting time units. This approach is problematic as it silently
> accepts malformed strings such as "100nsx" or "100us_invalid" by
> ignoring the trailing characters, leading to potential configuration
> errors.
>
> Introduce a match_time_unit() helper that checks the suffix matches
> exactly and is followed by either end-of-string or a ':' delimiter.
> The ':' is needed because parse_ns_duration() is also called from
> get_long_ns_after_colon() when parsing SCHED_DEADLINE priority
> specifications in the format "d:runtime:period" (e.g., "d:10ms:100ms").
>
> A plain strcmp() would reject valid deadline strings because the suffix
> "ms" is followed by ":100ms", not end-of-string. Similarly,
> strncmp_static() would fail because ARRAY_SIZE() includes the NUL
> terminator, making it equivalent to strcmp() for this comparison.
>
This fixes both the command and the corresponding unit test, thanks!
> The match_time_unit() helper solves both problems: it rejects malformed
> input like "100msx" while correctly handling the colon-delimited
> deadline format.
>
It now fails to reject this kind of input:
$ rtla timerlat -P d:10ms:100ms:somethingsomething
// this is also parsed as valid
But that can be fixed in a future patchset, perhaps together with also migrating
parse_seconds_duration() from prefix matching to match_time_unit() as well.
That would prevent the same imprecise parsing issue for -d:
$ rtla timerlat -d 1somethingsomething
// this is also parsed as valid
Tomas
^ permalink raw reply
* [PATCH bpf-next] ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod
From: Jiri Olsa @ 2026-03-12 11:47 UTC (permalink / raw)
To: Steven Rostedt, Alexei Starovoitov
Cc: bpf, linux-kernel, linux-trace-kernel, Daniel Borkmann,
Andrii Nakryiko, Menglong Dong, Song Liu
The modify logic registers temporary ftrace_ops object (tmp_ops) to trigger
the slow path for all direct callers to be able to safely modify attached
addresses.
At the moment we use ops->func_hash for tmp_ops filter, which represents all
the systems attachments. It's faster to use just the passed hash filter, which
contains only the modified sites is always a subset of the ops->func_hash.
Fixes: e93672f770d7 ("ftrace: Add update_ftrace_direct_mod function")
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
kernel/trace/ftrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8df69e702706..71dcbfeac86c 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6608,7 +6608,7 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b
/* Enable the tmp_ops to have the same functions as the direct ops */
ftrace_ops_init(&tmp_ops);
- tmp_ops.func_hash = ops->func_hash;
+ tmp_ops.func_hash->filter_hash = hash;
err = register_ftrace_function_nolock(&tmp_ops);
if (err)
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 1/2] locking/percpu-rwsem: Extract __percpu_up_read()
From: Usama Arif @ 2026-03-12 11:39 UTC (permalink / raw)
To: Dmitry Ilvokhin
Cc: Usama Arif, Dennis Zhou, Tejun Heo, Christoph Lameter,
Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
linux-mm, linux-kernel, linux-trace-kernel, kernel-team
In-Reply-To: <a065fd88990c0091a168b1d6715cd0cae8e9066c.1773164180.git.d@ilvokhin.com>
On Tue, 10 Mar 2026 17:49:38 +0000 Dmitry Ilvokhin <d@ilvokhin.com> wrote:
> Move the percpu_up_read() slowpath out of the inline function into a new
> __percpu_up_read() to avoid binary size increase from adding a
> tracepoint to an inlined function.
>
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> ---
> include/linux/percpu-rwsem.h | 15 +++------------
> kernel/locking/percpu-rwsem.c | 18 ++++++++++++++++++
> 2 files changed, 21 insertions(+), 12 deletions(-)
>
> diff --git a/include/linux/percpu-rwsem.h b/include/linux/percpu-rwsem.h
> index c8cb010d655e..39d5bf8e6562 100644
> --- a/include/linux/percpu-rwsem.h
> +++ b/include/linux/percpu-rwsem.h
> @@ -107,6 +107,8 @@ static inline bool percpu_down_read_trylock(struct percpu_rw_semaphore *sem)
> return ret;
> }
>
Acked-by: Usama Arif <usama.arif@linux.dev>
^ permalink raw reply
* Re: [PATCH v2 2/2] locking: Add contended_release tracepoint
From: Usama Arif @ 2026-03-12 11:38 UTC (permalink / raw)
To: Dmitry Ilvokhin
Cc: Usama Arif, Dennis Zhou, Tejun Heo, Christoph Lameter,
Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
Peter Zijlstra, Ingo Molnar, Will Deacon, Boqun Feng, Waiman Long,
linux-mm, linux-kernel, linux-trace-kernel, kernel-team
In-Reply-To: <cb89caf58885858433711f0ed6238484f5f1a67f.1773164180.git.d@ilvokhin.com>
On Tue, 10 Mar 2026 17:49:39 +0000 Dmitry Ilvokhin <d@ilvokhin.com> wrote:
> Add the contended_release trace event. This tracepoint fires on the
> holder side when a contended lock is released, complementing the
> existing contention_begin/contention_end tracepoints which fire on the
> waiter side.
>
> This enables correlating lock hold time under contention with waiter
> events by lock address.
>
> Add trace_contended_release() calls to the slowpath unlock paths of
> sleepable locks: mutex, rtmutex, semaphore, rwsem, percpu-rwsem, and
> RT-specific rwbase locks. Each call site fires only when there are
> blocked waiters being woken, except percpu_up_write() which always wakes
> via __wake_up().
>
> Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
> ---
> include/trace/events/lock.h | 17 +++++++++++++++++
> kernel/locking/mutex.c | 1 +
> kernel/locking/percpu-rwsem.c | 3 +++
> kernel/locking/rtmutex.c | 1 +
> kernel/locking/rwbase_rt.c | 8 +++++++-
> kernel/locking/rwsem.c | 9 +++++++--
> kernel/locking/semaphore.c | 4 +++-
> 7 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/include/trace/events/lock.h b/include/trace/events/lock.h
> index 8e89baa3775f..4f28e41977ec 100644
> --- a/include/trace/events/lock.h
> +++ b/include/trace/events/lock.h
> @@ -138,6 +138,23 @@ TRACE_EVENT(contention_end,
> TP_printk("%p (ret=%d)", __entry->lock_addr, __entry->ret)
> );
>
> +TRACE_EVENT(contended_release,
> +
> + TP_PROTO(void *lock),
> +
> + TP_ARGS(lock),
> +
> + TP_STRUCT__entry(
> + __field(void *, lock_addr)
> + ),
> +
> + TP_fast_assign(
> + __entry->lock_addr = lock;
> + ),
> +
> + TP_printk("%p", __entry->lock_addr)
> +);
> +
> #endif /* _TRACE_LOCK_H */
>
> /* This part must be outside protection */
> diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
> index 427187ff02db..ff9d07f3e900 100644
> --- a/kernel/locking/mutex.c
> +++ b/kernel/locking/mutex.c
> @@ -992,6 +992,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
> if (waiter) {
> next = waiter->task;
>
> + trace_contended_release(lock);
> debug_mutex_wake_waiter(lock, waiter);
> __clear_task_blocked_on(next, lock);
> wake_q_add(&wake_q, next);
> diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
> index f3ee7a0d6047..1eee51766aaf 100644
> --- a/kernel/locking/percpu-rwsem.c
> +++ b/kernel/locking/percpu-rwsem.c
> @@ -263,6 +263,8 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
> {
> rwsem_release(&sem->dep_map, _RET_IP_);
>
> + trace_contended_release(sem);
> +
Hello!
I saw that you mentioned in the commmit message that you do this for only
blocked waiters except for percpu_up_write(). We can use
waitqueue_active(&sem->waiters) to check for this over here so that
its consistent with every other call?
> /*
> * Signal the writer is done, no fast path yet.
> *
> @@ -297,6 +299,7 @@ void __percpu_up_read(struct percpu_rw_semaphore *sem)
> * writer.
> */
> smp_mb(); /* B matches C */
> + trace_contended_release(sem);
Should we do this after this_cpu_dec(*sem->read_count)?
> /*
> * In other words, if they see our decrement (presumably to
> * aggregate zero, as that is the only time it matters) they
> diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
> index ccaba6148b61..3db8a840b4e8 100644
> --- a/kernel/locking/rtmutex.c
> +++ b/kernel/locking/rtmutex.c
> @@ -1466,6 +1466,7 @@ static void __sched rt_mutex_slowunlock(struct rt_mutex_base *lock)
> raw_spin_lock_irqsave(&lock->wait_lock, flags);
> }
>
> + trace_contended_release(lock);
> /*
> * The wakeup next waiter path does not suffer from the above
> * race. See the comments there.
> diff --git a/kernel/locking/rwbase_rt.c b/kernel/locking/rwbase_rt.c
> index 82e078c0665a..081778934b13 100644
> --- a/kernel/locking/rwbase_rt.c
> +++ b/kernel/locking/rwbase_rt.c
> @@ -162,8 +162,10 @@ static void __sched __rwbase_read_unlock(struct rwbase_rt *rwb,
> * worst case which can happen is a spurious wakeup.
> */
> owner = rt_mutex_owner(rtm);
> - if (owner)
> + if (owner) {
> + trace_contended_release(rwb);
> rt_mutex_wake_q_add_task(&wqh, owner, state);
> + }
>
> /* Pairs with the preempt_enable in rt_mutex_wake_up_q() */
> preempt_disable();
> @@ -205,6 +207,8 @@ static inline void rwbase_write_unlock(struct rwbase_rt *rwb)
> unsigned long flags;
>
> raw_spin_lock_irqsave(&rtm->wait_lock, flags);
> + if (trace_contended_release_enabled() && rt_mutex_has_waiters(rtm))
> + trace_contended_release(rwb);
> __rwbase_write_unlock(rwb, WRITER_BIAS, flags);
> }
>
> @@ -214,6 +218,8 @@ static inline void rwbase_write_downgrade(struct rwbase_rt *rwb)
> unsigned long flags;
>
> raw_spin_lock_irqsave(&rtm->wait_lock, flags);
> + if (trace_contended_release_enabled() && rt_mutex_has_waiters(rtm))
> + trace_contended_release(rwb);
> /* Release it and account current as reader */
> __rwbase_write_unlock(rwb, WRITER_BIAS - 1, flags);
> }
> diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c
> index ba4cb74de064..cf7d8e75ad7b 100644
> --- a/kernel/locking/rwsem.c
> +++ b/kernel/locking/rwsem.c
> @@ -1390,6 +1390,7 @@ static inline void __up_read(struct rw_semaphore *sem)
> if (unlikely((tmp & (RWSEM_LOCK_MASK|RWSEM_FLAG_WAITERS)) ==
> RWSEM_FLAG_WAITERS)) {
> clear_nonspinnable(sem);
> + trace_contended_release(sem);
> rwsem_wake(sem);
> }
> preempt_enable();
> @@ -1413,8 +1414,10 @@ static inline void __up_write(struct rw_semaphore *sem)
> preempt_disable();
> rwsem_clear_owner(sem);
> tmp = atomic_long_fetch_add_release(-RWSEM_WRITER_LOCKED, &sem->count);
> - if (unlikely(tmp & RWSEM_FLAG_WAITERS))
> + if (unlikely(tmp & RWSEM_FLAG_WAITERS)) {
> + trace_contended_release(sem);
> rwsem_wake(sem);
> + }
> preempt_enable();
> }
>
> @@ -1437,8 +1440,10 @@ static inline void __downgrade_write(struct rw_semaphore *sem)
> tmp = atomic_long_fetch_add_release(
> -RWSEM_WRITER_LOCKED+RWSEM_READER_BIAS, &sem->count);
> rwsem_set_reader_owned(sem);
> - if (tmp & RWSEM_FLAG_WAITERS)
> + if (tmp & RWSEM_FLAG_WAITERS) {
> + trace_contended_release(sem);
> rwsem_downgrade_wake(sem);
> + }
> preempt_enable();
> }
>
> diff --git a/kernel/locking/semaphore.c b/kernel/locking/semaphore.c
> index 74d41433ba13..d46415095dd6 100644
> --- a/kernel/locking/semaphore.c
> +++ b/kernel/locking/semaphore.c
> @@ -231,8 +231,10 @@ void __sched up(struct semaphore *sem)
> else
> __up(sem, &wake_q);
> raw_spin_unlock_irqrestore(&sem->lock, flags);
> - if (!wake_q_empty(&wake_q))
> + if (!wake_q_empty(&wake_q)) {
> + trace_contended_release(sem);
> wake_up_q(&wake_q);
> + }
> }
> EXPORT_SYMBOL(up);
>
> --
> 2.52.0
>
>
^ permalink raw reply
* [PATCH] tracing: Update undefined symbols allow list for simple_ring_buffer
From: Vincent Donnefort @ 2026-03-12 11:35 UTC (permalink / raw)
To: maz
Cc: rostedt, linux-trace-kernel, kvmarm, kernel-team,
Vincent Donnefort, Nathan Chancellor
Undefined symbols are not allowed for simple_ring_buffer.c. But some
compiler emitted symbols are missing in the allowlist. Update it.
Reported-by: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
index 3182e1bc1cf7..3cc490aadc99 100644
--- a/kernel/trace/Makefile
+++ b/kernel/trace/Makefile
@@ -137,7 +137,8 @@ obj-$(CONFIG_TRACE_REMOTE_TEST) += remote_test.o
# to all kernel symbols. Fail the build if forbidden symbols are found.
#
UNDEFINED_ALLOWLIST := memset alt_cb_patch_nops __x86 __ubsan __asan __kasan __gcov __aeabi_unwind
-UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer
+UNDEFINED_ALLOWLIST += __stack_chk_fail stackleak_track_stack __ref_stack __sanitizer llvm_gcda llvm_gcov
+UNDEFINED_ALLOWLIST += .TOC\. __clear_pages_unrolled __memmove copy_page warn_slowpath_fmt
UNDEFINED_ALLOWLIST := $(addprefix -e , $(UNDEFINED_ALLOWLIST))
quiet_cmd_check_undefined = NM $<
base-commit: 455baa581922086f1ad44c76d4a3b03c265ee950
--
2.53.0.851.ga537e3e6e9-goog
^ permalink raw reply related
* Re: [PATCH v7 05/15] Documentation/rv: Add documentation about hybrid automata
From: Juri Lelli @ 2026-03-12 10:39 UTC (permalink / raw)
To: Gabriele Monaco
Cc: linux-kernel, Steven Rostedt, Nam Cao, Juri Lelli,
Jonathan Corbet, linux-trace-kernel, linux-doc, Tomas Glozar,
Clark Williams, John Kacur
In-Reply-To: <20260310105627.332044-6-gmonaco@redhat.com>
Hello,
On 10/03/26 11:56, Gabriele Monaco wrote:
...
> diff --git a/Documentation/trace/rv/hybrid_automata.rst b/Documentation/trace/rv/hybrid_automata.rst
> new file mode 100644
> index 000000000000..60f6bccfba38
> --- /dev/null
> +++ b/Documentation/trace/rv/hybrid_automata.rst
> @@ -0,0 +1,341 @@
> +Hybrid Automata
> +===============
> +
> +Hybrid automata are an extension of deterministic automata, there are several
> +definitions of hybrid automata in the literature. The adaptation implemented
> +here is formally denoted by G and defined as a 7-tuple:
> +
> + *G* = { *X*, *E*, *V*, *f*, x\ :subscript:`0`, X\ :subscript:`m`, *i* }
> +
> +- *X* is the set of states;
> +- *E* is the finite set of events;
> +- *V* is the finite set of environment variables;
> +- x\ :subscript:`0` is the initial state;
> +- X\ :subscript:`m` (subset of *X*) is the set of marked (or final) states.
> +- *f* : *X* x *E* x *C(V)* -> *X* is the transition function.
> + It defines the state transition in the occurrence of an event from *E* in the
> + state *X*. Unlike deterministic automata, the transition function also
> + includes guards from the set of all possible constraints (defined as *C(V)*).
> + Guards can be true or false with the valuation of *V* when the event occurs,
> + and the transition is possible only when constraints are true. Similarly to
> + deterministic automata, the occurrence of the event in *E* in a state in *X*
> + has a deterministic next state from *X*, if the guard is true.
> +- *i* : *X* -> *C'(V)* is the invariant assignment function, this is a
> + constraint assigned to each state in *X*, every state in *X* must be left
> + before the invariant turns to false. We can omit the representation of
> + invariants whose value is true regardless of the valuation of *V*.
Very minor nit, feel free to ignore, but ...
The formal 7-tuple definition includes 'i' (invariant function), but
unlike other elements, 'i' isn't stored in the automaton struct - it's
implemented as generated code in ha_verify_constraint(), IIUC. Worth a
brief note clarifying this design choice so readers don't expect to find
an invariants[] member in the struct? Here or below in the example C
code section.
In any case,
Reviewed-by: Juri Lelli <juri.lelli@redhat.com>
Thanks,
Juri
^ permalink raw reply
* [PATCH net-next v4 13/13] net/mlx5: Add a shared devlink instance for PFs on same chip
From: Jiri Pirko @ 2026-03-12 10:04 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter, corbet,
skhan, saeedm, leon, tariqt, mbloch, przemyslaw.kitszel, mschmidt,
andrew+netdev, rostedt, mhiramat, mathieu.desnoyers, chuck.lever,
matttbe, cjubran, daniel.zahka, linux-doc, linux-rdma,
linux-trace-kernel
In-Reply-To: <20260312100407.551173-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Use the previously introduced shared devlink infrastructure to create
a shared devlink instance for mlx5 PFs that reside on the same physical
chip. The shared instance is identified by the chip's serial number
extracted from PCI VPD (V3 keyword, with fallback to serial number
for older devices).
Each PF that probes calls mlx5_shd_init() which extracts the chip serial
number and uses devlink_shd_get() to get or create the shared instance.
When a PF is removed, mlx5_shd_uninit() calls devlink_shd_put()
to release the reference. The shared instance is automatically destroyed
when the last PF is removed.
Make the PF devlink instances nested in this shared devlink instance,
allowing userspace to identify which PFs belong to the same physical
chip.
Example:
pci/0000:08:00.0: index 0
nested_devlink:
auxiliary/mlx5_core.eth.0
devlink_index/1: index 1
nested_devlink:
pci/0000:08:00.0
pci/0000:08:00.1
auxiliary/mlx5_core.eth.0: index 2
pci/0000:08:00.1: index 3
nested_devlink:
auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1: index 4
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- removed "const" from "sn"
- passing driver pointer to devlink_shd_get()
---
.../net/ethernet/mellanox/mlx5/core/Makefile | 5 +-
.../net/ethernet/mellanox/mlx5/core/main.c | 17 ++++++
.../ethernet/mellanox/mlx5/core/sh_devlink.c | 61 +++++++++++++++++++
.../ethernet/mellanox/mlx5/core/sh_devlink.h | 12 ++++
include/linux/mlx5/driver.h | 1 +
5 files changed, 94 insertions(+), 2 deletions(-)
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.c
create mode 100644 drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.h
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/Makefile b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
index 8ffa286a18f5..d39fe9c4a87c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/Makefile
+++ b/drivers/net/ethernet/mellanox/mlx5/core/Makefile
@@ -16,8 +16,9 @@ mlx5_core-y := main.o cmd.o debugfs.o fw.o eq.o uar.o pagealloc.o \
transobj.o vport.o sriov.o fs_cmd.o fs_core.o pci_irq.o \
fs_counters.o fs_ft_pool.o rl.o lag/debugfs.o lag/lag.o dev.o events.o wq.o lib/gid.o \
lib/devcom.o lib/pci_vsc.o lib/dm.o lib/fs_ttc.o diag/fs_tracepoint.o \
- diag/fw_tracer.o diag/crdump.o devlink.o diag/rsc_dump.o diag/reporter_vnic.o \
- fw_reset.o qos.o lib/tout.o lib/aso.o wc.o fs_pool.o lib/nv_param.o
+ diag/fw_tracer.o diag/crdump.o devlink.o sh_devlink.o diag/rsc_dump.o \
+ diag/reporter_vnic.o fw_reset.o qos.o lib/tout.o lib/aso.o wc.o fs_pool.o \
+ lib/nv_param.o
#
# Netdev basic
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
index fdc3ba20912e..1c35c3fc3bb3 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
@@ -74,6 +74,7 @@
#include "mlx5_irq.h"
#include "hwmon.h"
#include "lag/lag.h"
+#include "sh_devlink.h"
MODULE_AUTHOR("Eli Cohen <eli@mellanox.com>");
MODULE_DESCRIPTION("Mellanox 5th generation network adapters (ConnectX series) core driver");
@@ -1520,10 +1521,16 @@ int mlx5_init_one(struct mlx5_core_dev *dev)
int err;
devl_lock(devlink);
+ if (dev->shd) {
+ err = devl_nested_devlink_set(dev->shd, devlink);
+ if (err)
+ goto unlock;
+ }
devl_register(devlink);
err = mlx5_init_one_devl_locked(dev);
if (err)
devl_unregister(devlink);
+unlock:
devl_unlock(devlink);
return err;
}
@@ -2005,6 +2012,13 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
goto pci_init_err;
}
+ err = mlx5_shd_init(dev);
+ if (err) {
+ mlx5_core_err(dev, "mlx5_shd_init failed with error code %d\n",
+ err);
+ goto shd_init_err;
+ }
+
err = mlx5_init_one(dev);
if (err) {
mlx5_core_err(dev, "mlx5_init_one failed with error code %d\n",
@@ -2018,6 +2032,8 @@ static int probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
err_init_one:
+ mlx5_shd_uninit(dev);
+shd_init_err:
mlx5_pci_close(dev);
pci_init_err:
mlx5_mdev_uninit(dev);
@@ -2039,6 +2055,7 @@ static void remove_one(struct pci_dev *pdev)
mlx5_drain_health_wq(dev);
mlx5_sriov_disable(pdev, false);
mlx5_uninit_one(dev);
+ mlx5_shd_uninit(dev);
mlx5_pci_close(dev);
mlx5_mdev_uninit(dev);
mlx5_adev_idx_free(dev->priv.adev_idx);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.c b/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.c
new file mode 100644
index 000000000000..bc33f95302df
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
+/* Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#include <linux/mlx5/driver.h>
+#include <net/devlink.h>
+
+#include "sh_devlink.h"
+
+static const struct devlink_ops mlx5_shd_ops = {
+};
+
+int mlx5_shd_init(struct mlx5_core_dev *dev)
+{
+ u8 *vpd_data __free(kfree) = NULL;
+ struct pci_dev *pdev = dev->pdev;
+ unsigned int vpd_size, kw_len;
+ struct devlink *devlink;
+ char *sn, *end;
+ int start;
+ int err;
+
+ if (!mlx5_core_is_pf(dev))
+ return 0;
+
+ vpd_data = pci_vpd_alloc(pdev, &vpd_size);
+ if (IS_ERR(vpd_data)) {
+ err = PTR_ERR(vpd_data);
+ return err == -ENODEV ? 0 : err;
+ }
+ start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size, "V3", &kw_len);
+ if (start < 0) {
+ /* Fall-back to SN for older devices. */
+ start = pci_vpd_find_ro_info_keyword(vpd_data, vpd_size,
+ PCI_VPD_RO_KEYWORD_SERIALNO, &kw_len);
+ if (start < 0)
+ return -ENOENT;
+ }
+ sn = kstrndup(vpd_data + start, kw_len, GFP_KERNEL);
+ if (!sn)
+ return -ENOMEM;
+ /* Firmware may return spaces at the end of the string, strip it. */
+ end = strchrnul(sn, ' ');
+ *end = '\0';
+
+ /* Get or create shared devlink instance */
+ devlink = devlink_shd_get(sn, &mlx5_shd_ops, 0, pdev->dev.driver);
+ kfree(sn);
+ if (!devlink)
+ return -ENOMEM;
+
+ dev->shd = devlink;
+ return 0;
+}
+
+void mlx5_shd_uninit(struct mlx5_core_dev *dev)
+{
+ if (!dev->shd)
+ return;
+
+ devlink_shd_put(dev->shd);
+}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.h b/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.h
new file mode 100644
index 000000000000..8ab8d6940227
--- /dev/null
+++ b/drivers/net/ethernet/mellanox/mlx5/core/sh_devlink.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
+/* Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#ifndef __MLX5_SH_DEVLINK_H__
+#define __MLX5_SH_DEVLINK_H__
+
+#include <linux/mlx5/driver.h>
+
+int mlx5_shd_init(struct mlx5_core_dev *dev);
+void mlx5_shd_uninit(struct mlx5_core_dev *dev);
+
+#endif /* __MLX5_SH_DEVLINK_H__ */
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 04dcd09f7517..1268fcf35ec7 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -798,6 +798,7 @@ struct mlx5_core_dev {
enum mlx5_wc_state wc_state;
/* sync write combining state */
struct mutex wc_state_lock;
+ struct devlink *shd;
};
struct mlx5_db {
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v4 12/13] documentation: networking: add shared devlink documentation
From: Jiri Pirko @ 2026-03-12 10:04 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter, corbet,
skhan, saeedm, leon, tariqt, mbloch, przemyslaw.kitszel, mschmidt,
andrew+netdev, rostedt, mhiramat, mathieu.desnoyers, chuck.lever,
matttbe, cjubran, daniel.zahka, linux-doc, linux-rdma,
linux-trace-kernel
In-Reply-To: <20260312100407.551173-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Document shared devlink instances for multiple PFs on the same chip.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- describing 2 models of use os shared device, with and without per-PF
instances
v1->v2:
- fixed number of "="'s
---
.../networking/devlink/devlink-shared.rst | 97 +++++++++++++++++++
Documentation/networking/devlink/index.rst | 1 +
2 files changed, 98 insertions(+)
create mode 100644 Documentation/networking/devlink/devlink-shared.rst
diff --git a/Documentation/networking/devlink/devlink-shared.rst b/Documentation/networking/devlink/devlink-shared.rst
new file mode 100644
index 000000000000..16bf6a7d25d9
--- /dev/null
+++ b/Documentation/networking/devlink/devlink-shared.rst
@@ -0,0 +1,97 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+========================
+Devlink Shared Instances
+========================
+
+Overview
+========
+
+Shared devlink instances allow multiple physical functions (PFs) on the same
+chip to share a devlink instance for chip-wide operations.
+
+Multiple PFs may reside on the same physical chip, running a single firmware.
+Some of the resources and configurations may be shared among these PFs. The
+shared devlink instance provides an object to pin configuration knobs on.
+
+There are two possible usage models:
+
+1. The shared devlink instance is used alongside individual PF devlink
+ instances, providing chip-wide configuration in addition to per-PF
+ configuration.
+2. The shared devlink instance is the only devlink instance, without
+ per-PF instances.
+
+It is up to the driver to decide which usage model to use.
+
+The shared devlink instance is not backed by any struct *device*.
+
+Implementation
+==============
+
+Architecture
+------------
+
+The implementation uses:
+
+* **Chip identification**: PFs are grouped by chip using a driver-specific identifier
+* **Shared instance management**: Global list of shared instances with reference counting
+
+API Functions
+-------------
+
+The following functions are provided for managing shared devlink instances:
+
+* ``devlink_shd_get()``: Get or create a shared devlink instance identified by a string ID
+* ``devlink_shd_put()``: Release a reference on a shared devlink instance
+* ``devlink_shd_get_priv()``: Get private data from shared devlink instance
+
+Initialization Flow
+-------------------
+
+1. **PF calls shared devlink init** during driver probe
+2. **Chip identification** using driver-specific method to determine device identity
+3. **Get or create shared instance** using ``devlink_shd_get()``:
+
+ * The function looks up existing instance by identifier
+ * If none exists, creates new instance:
+ - Allocates and registers devlink instance
+ - Adds to global shared instances list
+ - Increments reference count
+
+4. **Set nested devlink instance** for the PF devlink instance using
+ ``devl_nested_devlink_set()`` before registering the PF devlink instance
+
+Cleanup Flow
+------------
+
+1. **Cleanup** when PF is removed
+2. **Call** ``devlink_shd_put()`` to release reference (decrements reference count)
+3. **Shared instance is automatically destroyed** when the last PF removes (reference count reaches zero)
+
+Chip Identification
+-------------------
+
+PFs belonging to the same chip are identified using a driver-specific method.
+The driver is free to choose any identifier that is suitable for determining
+whether two PFs are part of the same device. Examples include:
+
+* **PCI VPD serial numbers**: Extract from PCI VPD
+* **Device tree properties**: Read chip identifier from device tree
+* **Other hardware-specific identifiers**: Any unique identifier that groups PFs by chip
+
+Locking
+-------
+
+A global mutex (``shd_mutex``) protects the shared instances list during registration/deregistration.
+
+Similarly to other nested devlink instance relationships, devlink lock of
+the shared instance should be always taken after the devlink lock of PF.
+
+Reference Counting
+------------------
+
+Each shared devlink instance maintains a reference count (``refcount_t refcount``).
+The reference count is incremented when ``devlink_shd_get()`` is called and decremented
+when ``devlink_shd_put()`` is called. When the reference count reaches zero, the shared
+instance is automatically destroyed.
diff --git a/Documentation/networking/devlink/index.rst b/Documentation/networking/devlink/index.rst
index 35b12a2bfeba..f7ba7dcf477d 100644
--- a/Documentation/networking/devlink/index.rst
+++ b/Documentation/networking/devlink/index.rst
@@ -68,6 +68,7 @@ general.
devlink-resource
devlink-selftests
devlink-trap
+ devlink-shared
Driver-specific documentation
-----------------------------
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v4 11/13] devlink: introduce shared devlink instance for PFs on same chip
From: Jiri Pirko @ 2026-03-12 10:04 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter, corbet,
skhan, saeedm, leon, tariqt, mbloch, przemyslaw.kitszel, mschmidt,
andrew+netdev, rostedt, mhiramat, mathieu.desnoyers, chuck.lever,
matttbe, cjubran, daniel.zahka, linux-doc, linux-rdma,
linux-trace-kernel
In-Reply-To: <20260312100407.551173-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Multiple PFs may reside on the same physical chip, running a single
firmware. Some of the resources and configurations may be shared among
these PFs. Currently, there is no good object to pin the configuration
knobs on.
Introduce a shared devlink instance, instantiated upon probe of
the first PF and removed during remove of the last PF. The shared
devlink instance is not backed by any device device, as there is
no PCI device related to it.
The implementation uses reference counting to manage the lifecycle:
each PF that probes calls devlink_shd_get() to get or create
the shared instance, and calls devlink_shd_put() when it removes.
The shared instance is automatically destroyed when the last PF removes.
Example:
pci/0000:08:00.0: index 0
nested_devlink:
auxiliary/mlx5_core.eth.0
devlink_index/1: index 1
nested_devlink:
pci/0000:08:00.0
pci/0000:08:00.1
auxiliary/mlx5_core.eth.0: index 2
pci/0000:08:00.1: index 3
nested_devlink:
auxiliary/mlx5_core.eth.1
auxiliary/mlx5_core.eth.1: index 4
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- added __counter_by() for priv
- added *driver arg to devlink_shd_get()
- added ops, priv_size and driver pointer consistency check
v1->v2:
- s/err_kstrdup_id/err_devlink_free/
- fixed kernel-doc comment of devlink_shd_get()
- removed NULL arg check in devlink_shd_get/put()
---
include/net/devlink.h | 7 ++
net/devlink/Makefile | 2 +-
net/devlink/sh_dev.c | 161 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 169 insertions(+), 1 deletion(-)
create mode 100644 net/devlink/sh_dev.c
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 45dec7067a8e..3038af6ec017 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1647,6 +1647,13 @@ void devlink_register(struct devlink *devlink);
void devlink_unregister(struct devlink *devlink);
void devlink_free(struct devlink *devlink);
+struct devlink *devlink_shd_get(const char *id,
+ const struct devlink_ops *ops,
+ size_t priv_size,
+ const struct device_driver *driver);
+void devlink_shd_put(struct devlink *devlink);
+void *devlink_shd_get_priv(struct devlink *devlink);
+
/**
* struct devlink_port_ops - Port operations
* @port_split: Callback used to split the port into multiple ones.
diff --git a/net/devlink/Makefile b/net/devlink/Makefile
index 000da622116a..8f2adb5e5836 100644
--- a/net/devlink/Makefile
+++ b/net/devlink/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-y := core.o netlink.o netlink_gen.o dev.o port.o sb.o dpipe.o \
- resource.o param.o region.o health.o trap.o rate.o linecard.o
+ resource.o param.o region.o health.o trap.o rate.o linecard.o sh_dev.o
diff --git a/net/devlink/sh_dev.c b/net/devlink/sh_dev.c
new file mode 100644
index 000000000000..85acce97e788
--- /dev/null
+++ b/net/devlink/sh_dev.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. */
+
+#include <net/devlink.h>
+
+#include "devl_internal.h"
+
+static LIST_HEAD(shd_list);
+static DEFINE_MUTEX(shd_mutex); /* Protects shd_list and shd->list */
+
+/* This structure represents a shared devlink instance,
+ * there is one created per identifier (e.g., serial number).
+ */
+struct devlink_shd {
+ struct list_head list; /* Node in shd list */
+ const char *id; /* Identifier string (e.g., serial number) */
+ refcount_t refcount; /* Reference count */
+ size_t priv_size; /* Size of driver private data */
+ char priv[] __aligned(NETDEV_ALIGN) __counted_by(priv_size);
+};
+
+static struct devlink_shd *devlink_shd_lookup(const char *id)
+{
+ struct devlink_shd *shd;
+
+ list_for_each_entry(shd, &shd_list, list) {
+ if (!strcmp(shd->id, id))
+ return shd;
+ }
+
+ return NULL;
+}
+
+static struct devlink_shd *devlink_shd_create(const char *id,
+ const struct devlink_ops *ops,
+ size_t priv_size,
+ const struct device_driver *driver)
+{
+ struct devlink_shd *shd;
+ struct devlink *devlink;
+
+ devlink = __devlink_alloc(ops, sizeof(struct devlink_shd) + priv_size,
+ &init_net, NULL, driver);
+ if (!devlink)
+ return NULL;
+ shd = devlink_priv(devlink);
+
+ shd->id = kstrdup(id, GFP_KERNEL);
+ if (!shd->id)
+ goto err_devlink_free;
+ shd->priv_size = priv_size;
+ refcount_set(&shd->refcount, 1);
+
+ devl_lock(devlink);
+ devl_register(devlink);
+ devl_unlock(devlink);
+
+ list_add_tail(&shd->list, &shd_list);
+
+ return shd;
+
+err_devlink_free:
+ devlink_free(devlink);
+ return NULL;
+}
+
+static void devlink_shd_destroy(struct devlink_shd *shd)
+{
+ struct devlink *devlink = priv_to_devlink(shd);
+
+ list_del(&shd->list);
+ devl_lock(devlink);
+ devl_unregister(devlink);
+ devl_unlock(devlink);
+ kfree(shd->id);
+ devlink_free(devlink);
+}
+
+/**
+ * devlink_shd_get - Get or create a shared devlink instance
+ * @id: Identifier string (e.g., serial number) for the shared instance
+ * @ops: Devlink operations structure
+ * @priv_size: Size of private data structure
+ * @driver: Driver associated with the shared devlink instance
+ *
+ * Get an existing shared devlink instance identified by @id, or create
+ * a new one if it doesn't exist. Return the devlink instance with a
+ * reference held. The caller must call devlink_shd_put() when done.
+ *
+ * All callers sharing the same @id must pass identical @ops, @priv_size
+ * and @driver. A mismatch triggers a warning and returns NULL.
+ *
+ * Return: Pointer to the shared devlink instance on success,
+ * NULL on failure
+ */
+struct devlink *devlink_shd_get(const char *id,
+ const struct devlink_ops *ops,
+ size_t priv_size,
+ const struct device_driver *driver)
+{
+ struct devlink *devlink;
+ struct devlink_shd *shd;
+
+ mutex_lock(&shd_mutex);
+
+ shd = devlink_shd_lookup(id);
+ if (!shd) {
+ shd = devlink_shd_create(id, ops, priv_size, driver);
+ goto unlock;
+ }
+
+ devlink = priv_to_devlink(shd);
+ if (WARN_ON_ONCE(devlink->ops != ops ||
+ shd->priv_size != priv_size ||
+ devlink->dev_driver != driver)) {
+ shd = NULL;
+ goto unlock;
+ }
+ refcount_inc(&shd->refcount);
+
+unlock:
+ mutex_unlock(&shd_mutex);
+ return shd ? priv_to_devlink(shd) : NULL;
+}
+EXPORT_SYMBOL_GPL(devlink_shd_get);
+
+/**
+ * devlink_shd_put - Release a reference on a shared devlink instance
+ * @devlink: Shared devlink instance
+ *
+ * Release a reference on a shared devlink instance obtained via
+ * devlink_shd_get().
+ */
+void devlink_shd_put(struct devlink *devlink)
+{
+ struct devlink_shd *shd;
+
+ mutex_lock(&shd_mutex);
+ shd = devlink_priv(devlink);
+ if (refcount_dec_and_test(&shd->refcount))
+ devlink_shd_destroy(shd);
+ mutex_unlock(&shd_mutex);
+}
+EXPORT_SYMBOL_GPL(devlink_shd_put);
+
+/**
+ * devlink_shd_get_priv - Get private data from shared devlink instance
+ * @devlink: Devlink instance
+ *
+ * Returns a pointer to the driver's private data structure within
+ * the shared devlink instance.
+ *
+ * Return: Pointer to private data
+ */
+void *devlink_shd_get_priv(struct devlink *devlink)
+{
+ struct devlink_shd *shd = devlink_priv(devlink);
+
+ return shd->priv;
+}
+EXPORT_SYMBOL_GPL(devlink_shd_get_priv);
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v4 10/13] devlink: allow devlink instance allocation without a backing device
From: Jiri Pirko @ 2026-03-12 10:04 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter, corbet,
skhan, saeedm, leon, tariqt, mbloch, przemyslaw.kitszel, mschmidt,
andrew+netdev, rostedt, mhiramat, mathieu.desnoyers, chuck.lever,
matttbe, cjubran, daniel.zahka, linux-doc, linux-rdma,
linux-trace-kernel
In-Reply-To: <20260312100407.551173-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Allow devlink_alloc_ns() to be called with dev=NULL to support
device-less devlink instances. When dev is NULL, the instance is
identified over netlink using "devlink_index" as bus_name and
the decimal index value as dev_name.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- rebased on top of __devlink_alloc() introduction
- removed dev check before dev_warn (devl_warn is used now)
- rebased on top of devlink->bus_name and devlink->dev_name removal
- rebased on top of devlink->dev_driver addition
v1->v2:
- moved DEVLINK_INDEX_BUS_NAME definition to patch #5
- added comment to dev arg that it can be NULL
- fixed the index sprintf for dev-less
---
net/devlink/core.c | 23 ++++++++++++++++++-----
net/devlink/dev.c | 8 ++++----
net/devlink/devl_internal.h | 5 +++--
3 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index 34eb06d88544..eeb6a71f5f56 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -250,13 +250,13 @@ EXPORT_SYMBOL_GPL(devlink_to_dev);
const char *devlink_bus_name(const struct devlink *devlink)
{
- return devlink->dev->bus->name;
+ return devlink->dev ? devlink->dev->bus->name : DEVLINK_INDEX_BUS_NAME;
}
EXPORT_SYMBOL_GPL(devlink_bus_name);
const char *devlink_dev_name(const struct devlink *devlink)
{
- return dev_name(devlink->dev);
+ return devlink->dev ? dev_name(devlink->dev) : devlink->dev_name_index;
}
EXPORT_SYMBOL_GPL(devlink_dev_name);
@@ -329,7 +329,10 @@ static void devlink_release(struct work_struct *work)
mutex_destroy(&devlink->lock);
lockdep_unregister_key(&devlink->lock_key);
- put_device(devlink->dev);
+ if (devlink->dev)
+ put_device(devlink->dev);
+ else
+ kfree(devlink->dev_name_index);
kvfree(devlink);
}
@@ -432,7 +435,7 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
static u32 last_id;
int ret;
- WARN_ON(!ops || !dev || !dev_driver);
+ WARN_ON(!ops || !dev_driver);
if (!devlink_reload_actions_valid(ops))
return NULL;
@@ -445,7 +448,14 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
if (ret < 0)
goto err_xa_alloc;
- devlink->dev = get_device(dev);
+ if (dev) {
+ devlink->dev = get_device(dev);
+ } else {
+ devlink->dev_name_index = kasprintf(GFP_KERNEL, "%u", devlink->index);
+ if (!devlink->dev_name_index)
+ goto err_kasprintf;
+ }
+
devlink->ops = ops;
devlink->dev_driver = dev_driver;
xa_init_flags(&devlink->ports, XA_FLAGS_ALLOC);
@@ -471,6 +481,8 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
return devlink;
+err_kasprintf:
+ xa_erase(&devlinks, devlink->index);
err_xa_alloc:
kvfree(devlink);
return NULL;
@@ -492,6 +504,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
size_t priv_size, struct net *net,
struct device *dev)
{
+ WARN_ON(!dev);
return __devlink_alloc(ops, priv_size, net, dev, dev->driver);
}
EXPORT_SYMBOL_GPL(devlink_alloc_ns);
diff --git a/net/devlink/dev.c b/net/devlink/dev.c
index e3a36de4f4ae..57b2b8f03543 100644
--- a/net/devlink/dev.c
+++ b/net/devlink/dev.c
@@ -453,7 +453,8 @@ int devlink_reload(struct devlink *devlink, struct net *dest_net,
* (e.g., PCI reset) and to close possible races between these
* operations and probe/remove.
*/
- device_lock_assert(devlink->dev);
+ if (devlink->dev)
+ device_lock_assert(devlink->dev);
memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
sizeof(remote_reload_stats));
@@ -854,7 +855,7 @@ int devlink_info_version_running_put_ext(struct devlink_info_req *req,
}
EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
-static int devlink_nl_driver_info_get(struct device_driver *drv,
+static int devlink_nl_driver_info_get(const struct device_driver *drv,
struct devlink_info_req *req)
{
if (!drv)
@@ -872,7 +873,6 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
enum devlink_command cmd, u32 portid,
u32 seq, int flags, struct netlink_ext_ack *extack)
{
- struct device *dev = devlink_to_dev(devlink);
struct devlink_info_req req = {};
void *hdr;
int err;
@@ -892,7 +892,7 @@ devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
goto err_cancel_msg;
}
- err = devlink_nl_driver_info_get(dev->driver, &req);
+ err = devlink_nl_driver_info_get(devlink->dev_driver, &req);
if (err)
goto err_cancel_msg;
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index cb2ffef1ac2d..7dfb7cdd2d23 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -49,6 +49,7 @@ struct devlink {
struct xarray snapshot_ids;
struct devlink_dev_stats stats;
struct device *dev;
+ const char *dev_name_index;
const struct device_driver *dev_driver;
possible_net_t _net;
/* Serializes access to devlink instance specific objects such as
@@ -119,7 +120,7 @@ static inline bool devl_is_registered(struct devlink *devlink)
static inline void devl_dev_lock(struct devlink *devlink, bool dev_lock)
{
- if (dev_lock)
+ if (dev_lock && devlink->dev)
device_lock(devlink->dev);
devl_lock(devlink);
}
@@ -127,7 +128,7 @@ static inline void devl_dev_lock(struct devlink *devlink, bool dev_lock)
static inline void devl_dev_unlock(struct devlink *devlink, bool dev_lock)
{
devl_unlock(devlink);
- if (dev_lock)
+ if (dev_lock && devlink->dev)
device_unlock(devlink->dev);
}
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v4 09/13] devlink: add devl_warn() helper and use it in port warnings
From: Jiri Pirko @ 2026-03-12 10:04 UTC (permalink / raw)
To: netdev
Cc: davem, edumazet, kuba, pabeni, horms, donald.hunter, corbet,
skhan, saeedm, leon, tariqt, mbloch, przemyslaw.kitszel, mschmidt,
andrew+netdev, rostedt, mhiramat, mathieu.desnoyers, chuck.lever,
matttbe, cjubran, daniel.zahka, linux-doc, linux-rdma,
linux-trace-kernel
In-Reply-To: <20260312100407.551173-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Introduce devl_warn() macro that uses dev_warn() when a backing
device is available and falls back to pr_warn() otherwise. Convert
all dev_warn() calls in port.c to use it, preparing for devlink
instances without a backing device.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
net/devlink/devl_internal.h | 9 +++++++++
net/devlink/port.c | 14 +++++++-------
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 3cc7e696e0fd..cb2ffef1ac2d 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -71,6 +71,15 @@ struct devlink *__devlink_alloc(const struct devlink_ops *ops, size_t priv_size,
struct net *net, struct device *dev,
const struct device_driver *dev_driver);
+#define devl_warn(devlink, format, args...) \
+ do { \
+ if ((devlink)->dev) \
+ dev_warn((devlink)->dev, format, ##args); \
+ else \
+ pr_warn("devlink (%s): " format, \
+ devlink_dev_name(devlink), ##args); \
+ } while (0)
+
/* devlink instances are open to the access from the user space after
* devlink_register() call. Such logical barrier allows us to have certain
* expectations related to locking.
diff --git a/net/devlink/port.c b/net/devlink/port.c
index fa3e1597711b..7fcd1d3ed44c 100644
--- a/net/devlink/port.c
+++ b/net/devlink/port.c
@@ -976,7 +976,7 @@ static void devlink_port_type_warn(struct work_struct *work)
struct devlink_port *port = container_of(to_delayed_work(work),
struct devlink_port,
type_warn_dw);
- dev_warn(port->devlink->dev, "Type was not set for devlink port.");
+ devl_warn(port->devlink, "Type was not set for devlink port.");
}
static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
@@ -1242,9 +1242,9 @@ static void __devlink_port_type_set(struct devlink_port *devlink_port,
*/
void devlink_port_type_eth_set(struct devlink_port *devlink_port)
{
- dev_warn(devlink_port->devlink->dev,
- "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
- devlink_port->index);
+ devl_warn(devlink_port->devlink,
+ "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
+ devlink_port->index);
__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
}
EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
@@ -1273,9 +1273,9 @@ EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
void devlink_port_type_clear(struct devlink_port *devlink_port)
{
if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
- dev_warn(devlink_port->devlink->dev,
- "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
- devlink_port->index);
+ devl_warn(devlink_port->devlink,
+ "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
+ devlink_port->index);
__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
}
EXPORT_SYMBOL_GPL(devlink_port_type_clear);
--
2.51.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox