* [PATCHv2 bpf-next 02/23] bpf: Use mutex lock pool for bpf trampolines
From: Jiri Olsa @ 2026-03-04 22:21 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, linux-trace-kernel, Martin KaFai Lau, Eduard Zingerman,
Song Liu, Yonghong Song, Menglong Dong, Steven Rostedt
In-Reply-To: <20260304222141.497203-1-jolsa@kernel.org>
Adding mutex lock pool that replaces bpf trampolines mutex.
For tracing_multi link coming in following changes we need to lock all
the involved trampolines during the attachment. This could mean thousands
of mutex locks, which is not convenient.
As suggested by Andrii we can replace bpf trampolines mutex with mutex
pool, where each trampoline is hash-ed to one of the locks from the pool.
It's better to lock all the pool mutexes (32 at the moment) than
thousands of them.
There is 48 (MAX_LOCK_DEPTH) lock limit allowed to be simultaneously
held by task, so we need to keep 32 mutexes (5 bits) in the pool, so
when we lock them all in following changes the lockdep won't scream.
Removing the mutex_is_locked in bpf_trampoline_put, because we removed
the mutex from bpf_trampoline.
Suggested-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/bpf.h | 2 --
kernel/bpf/trampoline.c | 75 ++++++++++++++++++++++++++++-------------
2 files changed, 52 insertions(+), 25 deletions(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 05b34a6355b0..1d900f49aff5 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1335,8 +1335,6 @@ struct bpf_trampoline {
/* hlist for trampoline_ip_table */
struct hlist_node hlist_ip;
struct ftrace_ops *fops;
- /* serializes access to fields of this trampoline */
- struct mutex mutex;
refcount_t refcnt;
u32 flags;
u64 key;
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c
index 84db9e658e52..28a5a96bccec 100644
--- a/kernel/bpf/trampoline.c
+++ b/kernel/bpf/trampoline.c
@@ -30,6 +30,34 @@ static struct hlist_head trampoline_ip_table[TRAMPOLINE_TABLE_SIZE];
/* serializes access to trampoline tables */
static DEFINE_MUTEX(trampoline_mutex);
+/*
+ * We keep 32 trampoline locks (5 bits) in the pool, because there
+ * is 48 (MAX_LOCK_DEPTH) locks limit allowed to be simultaneously
+ * held by task.
+ */
+#define TRAMPOLINE_LOCKS_BITS 5
+#define TRAMPOLINE_LOCKS_TABLE_SIZE (1 << TRAMPOLINE_LOCKS_BITS)
+
+static struct {
+ struct mutex mutex;
+ struct lock_class_key key;
+} trampoline_locks[TRAMPOLINE_LOCKS_TABLE_SIZE];
+
+static struct mutex *select_trampoline_lock(struct bpf_trampoline *tr)
+{
+ return &trampoline_locks[hash_64((u64)(uintptr_t) tr, TRAMPOLINE_LOCKS_BITS)].mutex;
+}
+
+static void trampoline_lock(struct bpf_trampoline *tr)
+{
+ mutex_lock(select_trampoline_lock(tr));
+}
+
+static void trampoline_unlock(struct bpf_trampoline *tr)
+{
+ mutex_unlock(select_trampoline_lock(tr));
+}
+
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mutex);
@@ -69,9 +97,9 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip,
if (cmd == FTRACE_OPS_CMD_ENABLE_SHARE_IPMODIFY_SELF) {
/* This is called inside register_ftrace_direct_multi(), so
- * tr->mutex is already locked.
+ * trampoline's mutex is already locked.
*/
- lockdep_assert_held_once(&tr->mutex);
+ lockdep_assert_held_once(select_trampoline_lock(tr));
/* Instead of updating the trampoline here, we propagate
* -EAGAIN to register_ftrace_direct(). Then we can
@@ -91,7 +119,7 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip,
}
/* The normal locking order is
- * tr->mutex => direct_mutex (ftrace.c) => ftrace_lock (ftrace.c)
+ * select_trampoline_lock(tr) => direct_mutex (ftrace.c) => ftrace_lock (ftrace.c)
*
* The following two commands are called from
*
@@ -99,12 +127,12 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip,
* cleanup_direct_functions_after_ipmodify
*
* In both cases, direct_mutex is already locked. Use
- * mutex_trylock(&tr->mutex) to avoid deadlock in race condition
+ * mutex_trylock(select_trampoline_lock(tr)) to avoid deadlock in race condition
* (something else is making changes to this same trampoline).
*/
- if (!mutex_trylock(&tr->mutex)) {
- /* sleep 1 ms to make sure whatever holding tr->mutex makes
- * some progress.
+ if (!mutex_trylock(select_trampoline_lock(tr))) {
+ /* sleep 1 ms to make sure whatever holding select_trampoline_lock(tr)
+ * makes some progress.
*/
msleep(1);
return -EAGAIN;
@@ -129,7 +157,7 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip,
break;
}
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
return ret;
}
#endif
@@ -359,7 +387,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key, unsigned long ip)
head = &trampoline_ip_table[hash_64(tr->ip, TRAMPOLINE_HASH_BITS)];
hlist_add_head(&tr->hlist_ip, head);
refcount_set(&tr->refcnt, 1);
- mutex_init(&tr->mutex);
for (i = 0; i < BPF_TRAMP_MAX; i++)
INIT_HLIST_HEAD(&tr->progs_hlist[i]);
out:
@@ -844,9 +871,9 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link,
{
int err;
- mutex_lock(&tr->mutex);
+ trampoline_lock(tr);
err = __bpf_trampoline_link_prog(link, tr, tgt_prog);
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
return err;
}
@@ -887,9 +914,9 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link,
{
int err;
- mutex_lock(&tr->mutex);
+ trampoline_lock(tr);
err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog);
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
return err;
}
@@ -999,14 +1026,15 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
if (!tr)
return -ENOMEM;
- mutex_lock(&tr->mutex);
+ trampoline_lock(tr);
shim_link = cgroup_shim_find(tr, bpf_func);
if (shim_link) {
/* Reusing existing shim attached by the other program. */
bpf_link_inc(&shim_link->link.link);
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
+
bpf_trampoline_put(tr); /* bpf_trampoline_get above */
return 0;
}
@@ -1026,16 +1054,16 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog,
shim_link->trampoline = tr;
/* note, we're still holding tr refcnt from above */
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
return 0;
err:
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
if (shim_link)
bpf_link_put(&shim_link->link.link);
- /* have to release tr while _not_ holding its mutex */
+ /* have to release tr while _not_ holding pool mutex for trampoline */
bpf_trampoline_put(tr); /* bpf_trampoline_get above */
return err;
@@ -1056,9 +1084,9 @@ void bpf_trampoline_unlink_cgroup_shim(struct bpf_prog *prog)
if (WARN_ON_ONCE(!tr))
return;
- mutex_lock(&tr->mutex);
+ trampoline_lock(tr);
shim_link = cgroup_shim_find(tr, bpf_func);
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
if (shim_link)
bpf_link_put(&shim_link->link.link);
@@ -1076,14 +1104,14 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key,
if (!tr)
return NULL;
- mutex_lock(&tr->mutex);
+ trampoline_lock(tr);
if (tr->func.addr)
goto out;
memcpy(&tr->func.model, &tgt_info->fmodel, sizeof(tgt_info->fmodel));
tr->func.addr = (void *)tgt_info->tgt_addr;
out:
- mutex_unlock(&tr->mutex);
+ trampoline_unlock(tr);
return tr;
}
@@ -1096,7 +1124,6 @@ void bpf_trampoline_put(struct bpf_trampoline *tr)
mutex_lock(&trampoline_mutex);
if (!refcount_dec_and_test(&tr->refcnt))
goto out;
- WARN_ON_ONCE(mutex_is_locked(&tr->mutex));
for (i = 0; i < BPF_TRAMP_MAX; i++)
if (WARN_ON_ONCE(!hlist_empty(&tr->progs_hlist[i])))
@@ -1382,6 +1409,8 @@ static int __init init_trampolines(void)
INIT_HLIST_HEAD(&trampoline_key_table[i]);
for (i = 0; i < TRAMPOLINE_TABLE_SIZE; i++)
INIT_HLIST_HEAD(&trampoline_ip_table[i]);
+ for (i = 0; i < TRAMPOLINE_LOCKS_TABLE_SIZE; i++)
+ __mutex_init(&trampoline_locks[i].mutex, "trampoline_lock", &trampoline_locks[i].key);
return 0;
}
late_initcall(init_trampolines);
--
2.53.0
^ permalink raw reply related
* [PATCHv2 bpf-next 01/23] ftrace: Add ftrace_hash_count function
From: Jiri Olsa @ 2026-03-04 22:21 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, linux-trace-kernel, Martin KaFai Lau, Eduard Zingerman,
Song Liu, Yonghong Song, Menglong Dong, Steven Rostedt
In-Reply-To: <20260304222141.497203-1-jolsa@kernel.org>
Adding external ftrace_hash_count function so we could get hash
count outside of ftrace object.
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
include/linux/ftrace.h | 1 +
kernel/trace/ftrace.c | 7 ++++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index c242fe49af4c..401f8dfd05d3 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -415,6 +415,7 @@ struct ftrace_hash *alloc_ftrace_hash(int size_bits);
void free_ftrace_hash(struct ftrace_hash *hash);
struct ftrace_func_entry *add_ftrace_hash_entry_direct(struct ftrace_hash *hash,
unsigned long ip, unsigned long direct);
+unsigned long ftrace_hash_count(struct ftrace_hash *hash);
/* The hash used to know what functions callbacks trace */
struct ftrace_ops_hash {
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8baf61c9be6d..ac06bf17caaf 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6288,11 +6288,16 @@ int modify_ftrace_direct(struct ftrace_ops *ops, unsigned long addr)
}
EXPORT_SYMBOL_GPL(modify_ftrace_direct);
-static unsigned long hash_count(struct ftrace_hash *hash)
+static inline unsigned long hash_count(struct ftrace_hash *hash)
{
return hash ? hash->count : 0;
}
+unsigned long ftrace_hash_count(struct ftrace_hash *hash)
+{
+ return hash_count(hash);
+}
+
/**
* hash_add - adds two struct ftrace_hash and returns the result
* @a: struct ftrace_hash object
--
2.53.0
^ permalink raw reply related
* [PATCHv2 bpf-next 00/23] bpf: tracing_multi link
From: Jiri Olsa @ 2026-03-04 22:21 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko
Cc: bpf, linux-trace-kernel, Martin KaFai Lau, Eduard Zingerman,
Song Liu, Yonghong Song, Menglong Dong, Steven Rostedt
hi,
adding tracing_multi link support that allows fast attachment
of tracing program to many functions.
RFC version: https://lore.kernel.org/bpf/20260203093819.2105105-1-jolsa@kernel.org/
v1: https://lore.kernel.org/bpf/20260220100649.628307-1-jolsa@kernel.org/
v2 changes:
- allocate data.unreg in bpf_trampoline_multi_attach for rollback path [ci]
and fixed link count setup in rollback path [ci]
- several small assorted fixes [ci]
- added loongarch and powerpc changes for struct bpf_tramp_node change
- added support to attach functions from modules
- added tests for sleepable programs
- added rollback tests
v1 changes:
- added ftrace_hash_count as wrapper for hash_count [Steven]
- added trampoline mutex pool [Andrii]
- reworked 'struct bpf_tramp_node' separatoin [Andrii]
- the 'struct bpf_tramp_node' now holds pointer to bpf_link,
which is similar to what we do for uprobe_multi;
I understand it's not a fundamental change compared to previous
version which used bpf_prog pointer instead, but I don't see better
way of doing this.. I'm happy to discuss this further if there's
better idea
- reworked 'struct bpf_fsession_link' based on bpf_tramp_node
- made btf__find_by_glob_kind function internal helper [Andrii]
- many small assorted fixes [Andrii,CI]
- added session support [Leon Hwang]
- added cookies support
- added more tests
Note I plan to send linkinfo support separately, the patchset is big enough.
thanks,
jirka
---
Jiri Olsa (23):
ftrace: Add ftrace_hash_count function
bpf: Use mutex lock pool for bpf trampolines
bpf: Add struct bpf_trampoline_ops object
bpf: Add struct bpf_tramp_node object
bpf: Factor fsession link to use struct bpf_tramp_node
bpf: Add multi tracing attach types
bpf: Move sleepable verification code to btf_id_allow_sleepable
bpf: Add bpf_trampoline_multi_attach/detach functions
bpf: Add support for tracing multi link
bpf: Add support for tracing_multi link cookies
bpf: Add support for tracing_multi link session
bpf: Add support for tracing_multi link fdinfo
libbpf: Add bpf_object_cleanup_btf function
libbpf: Add bpf_link_create support for tracing_multi link
libbpf: Add support to create tracing multi link
selftests/bpf: Add tracing multi skel/pattern/ids attach tests
selftests/bpf: Add tracing multi skel/pattern/ids module attach tests
selftests/bpf: Add tracing multi intersect tests
selftests/bpf: Add tracing multi cookies test
selftests/bpf: Add tracing multi session test
selftests/bpf: Add tracing multi attach fails test
selftests/bpf: Add tracing multi attach benchmark test
selftests/bpf: Add tracing multi rollback tests
arch/arm64/net/bpf_jit_comp.c | 58 +++---
arch/loongarch/net/bpf_jit.c | 44 ++---
arch/powerpc/net/bpf_jit_comp.c | 46 ++---
arch/riscv/net/bpf_jit_comp64.c | 52 ++---
arch/s390/net/bpf_jit_comp.c | 44 ++---
arch/x86/net/bpf_jit_comp.c | 54 +++---
include/linux/bpf.h | 91 ++++++---
include/linux/bpf_types.h | 1 +
include/linux/bpf_verifier.h | 3 +
include/linux/btf_ids.h | 1 +
include/linux/ftrace.h | 1 +
include/linux/trace_events.h | 6 +
include/uapi/linux/bpf.h | 9 +
kernel/bpf/bpf_struct_ops.c | 27 +--
kernel/bpf/btf.c | 4 +
kernel/bpf/syscall.c | 88 ++++++---
kernel/bpf/trampoline.c | 511 +++++++++++++++++++++++++++++++++++++++---------
kernel/bpf/verifier.c | 116 +++++++----
kernel/trace/bpf_trace.c | 147 +++++++++++++-
kernel/trace/ftrace.c | 7 +-
net/bpf/bpf_dummy_struct_ops.c | 14 +-
net/bpf/test_run.c | 3 +
tools/include/uapi/linux/bpf.h | 10 +
tools/lib/bpf/bpf.c | 9 +
tools/lib/bpf/bpf.h | 5 +
tools/lib/bpf/libbpf.c | 329 ++++++++++++++++++++++++++++++-
tools/lib/bpf/libbpf.h | 15 ++
tools/lib/bpf/libbpf.map | 1 +
tools/testing/selftests/bpf/Makefile | 9 +-
tools/testing/selftests/bpf/prog_tests/tracing_multi.c | 896 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/testing/selftests/bpf/progs/tracing_multi_attach.c | 40 ++++
tools/testing/selftests/bpf/progs/tracing_multi_attach_module.c | 26 +++
tools/testing/selftests/bpf/progs/tracing_multi_bench.c | 13 ++
tools/testing/selftests/bpf/progs/tracing_multi_check.c | 215 ++++++++++++++++++++
tools/testing/selftests/bpf/progs/tracing_multi_fail.c | 19 ++
tools/testing/selftests/bpf/progs/tracing_multi_intersect_attach.c | 42 ++++
tools/testing/selftests/bpf/progs/tracing_multi_rollback.c | 25 +++
tools/testing/selftests/bpf/progs/tracing_multi_session_attach.c | 27 +++
38 files changed, 2642 insertions(+), 366 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/tracing_multi.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_attach.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_attach_module.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_bench.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_check.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_fail.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_intersect_attach.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_rollback.c
create mode 100644 tools/testing/selftests/bpf/progs/tracing_multi_session_attach.c
^ permalink raw reply
* Re: [PATCH RFC 2/3] locking/percpu-rwsem: Extract __percpu_up_read_slowpath()
From: Peter Zijlstra @ 2026-03-04 22:02 UTC (permalink / raw)
To: Dmitry Ilvokhin
Cc: Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Ingo Molnar, Will Deacon,
Boqun Feng, Waiman Long, linux-mm, linux-kernel,
linux-trace-kernel, kernel-team
In-Reply-To: <6b1f1521ca186d5c402a65619d8f30fe83b93bf6.1772642407.git.d@ilvokhin.com>
On Wed, Mar 04, 2026 at 04:56:16PM +0000, Dmitry Ilvokhin wrote:
> Move the percpu_up_read() slowpath out of the inline function into a new
> __percpu_up_read_slowpath() 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..89506895365c 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;
> }
>
> +void __percpu_up_read_slowpath(struct percpu_rw_semaphore *sem);
> +
extern for consistency with all the other declarations in this header.
s/_slowpath//, the corresponding down function also doesn't have
_slowpath on.
> static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
> {
> rwsem_release(&sem->dep_map, _RET_IP_);
^ permalink raw reply
* Re: [RFC PATCH 1/2] locking: add mutex_lock_nospin()
From: David Laight @ 2026-03-04 21:44 UTC (permalink / raw)
To: Steven Rostedt
Cc: Peter Zijlstra, Yafang Shao, mingo, will, boqun, longman,
mhiramat, mark.rutland, mathieu.desnoyers, linux-kernel,
linux-trace-kernel, bpf
In-Reply-To: <20260304155742.7b4de2d1@gandalf.local.home>
On Wed, 4 Mar 2026 15:57:42 -0500
Steven Rostedt <rostedt@goodmis.org> wrote:
> On Wed, 4 Mar 2026 09:54:15 +0000
> David Laight <david.laight.linux@gmail.com> wrote:
>
> > That might still be an issue if a high priority process is spinning.
> > But a %sys spike doesn't imply a latency spike.
> >
> > Is this using the osq_lock.c code?
> > That will have problems on overprovisioned VMs, it tries to find out
> > whether the hypervisor has switched out - but ISTR that is flawed.
> >
> > In reality a spin lock shouldn't be held for long enough to cause
> > any kind latency issue.
> > So something in the code that reads the list of filter functions
> > needs to be done differently so that the lock isn't held for as long.
>
> It's not a spinlock, it's an adaptive mutex which spins while the owner of
> the mutex is also still running on the CPU. If the spinner CPU triggers a
> NEED_RESCHED or the owner goes to sleep, the spinner stops spinning and
> goes to sleep too.
I think half my brain knew that - otherwise I wouldn't have mentioned
the osq_lock.c code.
That all reminded me I've a patch that optimises that code a bit.
But I do remember thinking it ought to have a 'I been spinning long
enough, time to sleep' path.
David
>
> Honestly, this still looks like a non-issue or a corner case that I don't
> think requires these changes.
>
> This looks like one of those "Patient: Doctor it hurts me when I do this.
> Doctor: Then don't do that." cases.
>
> Why is a production system having multiple users cat
> avaliable_filter_functions to begin with?
>
> -- Steve
^ permalink raw reply
* Re: [PATCH v3 08/12] zonefs: widen trace event i_ino fields to u64
From: Damien Le Moal @ 2026-03-04 21:41 UTC (permalink / raw)
To: Jeff Layton, Alexander Viro, Christian Brauner, Jan Kara,
Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers, Dan Williams,
Eric Biggers, Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
Tyler Hicks, Amir Goldstein, Christoph Hellwig,
John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
David Woodhouse, Richard Weinberger, Dave Kleikamp,
Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
Zhihao Cheng, Naohiro Aota, Johannes Thumshirn, John Johansen,
Paul Moore, James Morris, Serge E. Hallyn, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
Christian König, David Airlie, Simona Vetter, Sumit Semwal,
Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
Martin Schiller, Eric Paris, Joerg Reuter, Marcel Holtmann,
Johan Hedberg, Luiz Augusto von Dentz, Oliver Hartkopp,
Marc Kleine-Budde, David Ahern, Neal Cardwell, Steffen Klassert,
Herbert Xu, Remi Denis-Courmont, Marcelo Ricardo Leitner,
Xin Long, Magnus Karlsson, Maciej Fijalkowski, Stanislav Fomichev,
Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
John Fastabend
Cc: linux-fsdevel, linux-kernel, linux-trace-kernel, nvdimm, fsverity,
linux-mm, netfs, linux-ext4, linux-f2fs-devel, linux-nfs,
linux-cifs, samba-technical, linux-nilfs, v9fs, linux-afs, autofs,
ceph-devel, codalist, ecryptfs, linux-mtd, jfs-discussion, ntfs3,
ocfs2-devel, devel, linux-unionfs, apparmor,
linux-security-module, linux-integrity, selinux, amd-gfx,
dri-devel, linux-media, linaro-mm-sig, netdev, linux-perf-users,
linux-fscrypt, linux-xfs, linux-hams, linux-x25, audit,
linux-bluetooth, linux-can, linux-sctp, bpf
In-Reply-To: <20260304-iino-u64-v3-8-2257ad83d372@kernel.org>
On 3/5/26 00:32, Jeff Layton wrote:
> Update zonefs trace event definitions to use u64 instead of
> ino_t/unsigned long for inode number fields.
>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
Acked-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [PATCH v3 12/12] treewide: change inode->i_ino from unsigned long to u64
From: Damien Le Moal @ 2026-03-04 21:41 UTC (permalink / raw)
To: Jeff Layton, Alexander Viro, Christian Brauner, Jan Kara,
Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers, Dan Williams,
Eric Biggers, Theodore Y. Ts'o, Muchun Song, Oscar Salvador,
David Hildenbrand, David Howells, Paulo Alcantara, Andreas Dilger,
Jan Kara, Jaegeuk Kim, Chao Yu, Trond Myklebust, Anna Schumaker,
Chuck Lever, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
Steve French, Ronnie Sahlberg, Shyam Prasad N, Bharath SM,
Alexander Aring, Ryusuke Konishi, Viacheslav Dubeyko,
Eric Van Hensbergen, Latchesar Ionkov, Dominique Martinet,
Christian Schoenebeck, David Sterba, Marc Dionne, Ian Kent,
Luis de Bethencourt, Salah Triki, Tigran A. Aivazian,
Ilya Dryomov, Alex Markuze, Jan Harkes, coda, Nicolas Pitre,
Tyler Hicks, Amir Goldstein, Christoph Hellwig,
John Paul Adrian Glaubitz, Yangtao Li, Mikulas Patocka,
David Woodhouse, Richard Weinberger, Dave Kleikamp,
Konstantin Komarov, Mark Fasheh, Joel Becker, Joseph Qi,
Mike Marshall, Martin Brandenburg, Miklos Szeredi, Anders Larsen,
Zhihao Cheng, Naohiro Aota, Johannes Thumshirn, John Johansen,
Paul Moore, James Morris, Serge E. Hallyn, Mimi Zohar,
Roberto Sassu, Dmitry Kasatkin, Eric Snowberg, Fan Wu,
Stephen Smalley, Ondrej Mosnacek, Casey Schaufler, Alex Deucher,
Christian König, David Airlie, Simona Vetter, Sumit Semwal,
Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
David S. Miller, Jakub Kicinski, Simon Horman, Oleg Nesterov,
Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
Namhyung Kim, Mark Rutland, Alexander Shishkin, Jiri Olsa,
Ian Rogers, Adrian Hunter, James Clark, Darrick J. Wong,
Martin Schiller, Eric Paris, Joerg Reuter, Marcel Holtmann,
Johan Hedberg, Luiz Augusto von Dentz, Oliver Hartkopp,
Marc Kleine-Budde, David Ahern, Neal Cardwell, Steffen Klassert,
Herbert Xu, Remi Denis-Courmont, Marcelo Ricardo Leitner,
Xin Long, Magnus Karlsson, Maciej Fijalkowski, Stanislav Fomichev,
Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
John Fastabend
Cc: linux-fsdevel, linux-kernel, linux-trace-kernel, nvdimm, fsverity,
linux-mm, netfs, linux-ext4, linux-f2fs-devel, linux-nfs,
linux-cifs, samba-technical, linux-nilfs, v9fs, linux-afs, autofs,
ceph-devel, codalist, ecryptfs, linux-mtd, jfs-discussion, ntfs3,
ocfs2-devel, devel, linux-unionfs, apparmor,
linux-security-module, linux-integrity, selinux, amd-gfx,
dri-devel, linux-media, linaro-mm-sig, netdev, linux-perf-users,
linux-fscrypt, linux-xfs, linux-hams, linux-x25, audit,
linux-bluetooth, linux-can, linux-sctp, bpf
In-Reply-To: <20260304-iino-u64-v3-12-2257ad83d372@kernel.org>
On 3/5/26 00:32, Jeff Layton wrote:
> On 32-bit architectures, unsigned long is only 32 bits wide, which
> causes 64-bit inode numbers to be silently truncated. Several
> filesystems (NFS, XFS, BTRFS, etc.) can generate inode numbers that
> exceed 32 bits, and this truncation can lead to inode number collisions
> and other subtle bugs on 32-bit systems.
>
> Change the type of inode->i_ino from unsigned long to u64 to ensure that
> inode numbers are always represented as 64-bit values regardless of
> architecture. Update all format specifiers treewide from %lu/%lx to
> %llu/%llx to match the new type, along with corresponding local variable
> types.
>
> This is the bulk treewide conversion. Earlier patches in this series
> handled trace events separately to allow trace field reordering for
> better struct packing on 32-bit.
>
> Signed-off-by: Jeff Layton <jlayton@kernel.org>
For the zonefs bits:
Acked-by: Damien Le Moal <dlemoal@kernel.org>
--
Damien Le Moal
Western Digital Research
^ permalink raw reply
* Re: [RFC PATCH 1/2] locking: add mutex_lock_nospin()
From: Steven Rostedt @ 2026-03-04 20:57 UTC (permalink / raw)
To: David Laight
Cc: Peter Zijlstra, Yafang Shao, mingo, will, boqun, longman,
mhiramat, mark.rutland, mathieu.desnoyers, linux-kernel,
linux-trace-kernel, bpf
In-Reply-To: <20260304095415.4d5f2528@pumpkin>
On Wed, 4 Mar 2026 09:54:15 +0000
David Laight <david.laight.linux@gmail.com> wrote:
> That might still be an issue if a high priority process is spinning.
> But a %sys spike doesn't imply a latency spike.
>
> Is this using the osq_lock.c code?
> That will have problems on overprovisioned VMs, it tries to find out
> whether the hypervisor has switched out - but ISTR that is flawed.
>
> In reality a spin lock shouldn't be held for long enough to cause
> any kind latency issue.
> So something in the code that reads the list of filter functions
> needs to be done differently so that the lock isn't held for as long.
It's not a spinlock, it's an adaptive mutex which spins while the owner of
the mutex is also still running on the CPU. If the spinner CPU triggers a
NEED_RESCHED or the owner goes to sleep, the spinner stops spinning and
goes to sleep too.
Honestly, this still looks like a non-issue or a corner case that I don't
think requires these changes.
This looks like one of those "Patient: Doctor it hurts me when I do this.
Doctor: Then don't do that." cases.
Why is a production system having multiple users cat
avaliable_filter_functions to begin with?
-- Steve
^ permalink raw reply
* Re: [PATCH] tracing: Fix WARN_ON in tracing_buffers_mmap_close
From: Lorenzo Stoakes (Oracle) @ 2026-03-04 17:30 UTC (permalink / raw)
To: Steven Rostedt
Cc: Lorenzo Stoakes, Vincent Donnefort, Qing Wang, Masami Hiramatsu,
Mathieu Desnoyers, linux-kernel, linux-trace-kernel,
syzbot+3b5dd2030fe08afdf65d, linux-mm, Andrew Morton,
Vlastimil Babka, David Hildenbrand
In-Reply-To: <20260303102528.744d57ae@gandalf.local.home>
On Tue, Mar 03, 2026 at 10:25:28AM -0500, Steven Rostedt wrote:
> On Tue, 3 Mar 2026 10:19:52 +0000
> Lorenzo Stoakes <lorenzo.stoakes@oracle.com> wrote:
>
> > > > Setting VM_IO just to trigger a failure case in madvise() feels like a hack? I
> > > > guess it'd do the trick though, but you're not going to be able to reclaim that
> > > > memory, and you might get some unexpected behaviour in code paths that assume
> > > > VM_IO means it's memory-mapped I/O... (for instance GUP will stop working, if
> > > > you need that).
> > >
> > > Well, we don't reclaim that memory anyway.
> >
> > OK so maybe not such an issue then! As long as GUP not working with it wouldn't
> > break anything?
>
> Yeah, we don't ever use get_user_page() for this memory. It's pretty much
> all handled on the kernel side. User space just has it mapped as read only.
> The kernel doesn't care what user space does with it.
OK.
>
>
> > > Yeah, right now the accounting gets screwed up as the mappings get out of
> > > sync when it is forked.
> >
> > Ack, is that in a way that could screw up things from a kernel point of view at
> > all? Presumably there was some report that triggered this work, like an assert
> > fail or something, or a warning?
>
> Yes, it triggered a warning. The start of this thread added a patch to allow
> madvise to remove DONTCOPY from this memory without screwing things up
> (by adding an open() handler for the vm_operations_struct).
I mean that'd be preferable.
>
>
> >
> > If a user is explicitly going to an ftrace buffer and madvise()'ing it in random
> > ways they've only themselves to blame for being so stupid :)
> >
> > As long as it's not exploitable in some way I don't think that's too much of an
> > issue?
> >
> > It'd be nice to keep the semantics of 'don't copy on fork' if we could, even if
> > some crazy users might override it with madvise().
>
> OK, so should we add the VM_IO flag?
Would be preferable not to lie about the mapping if possible :P that'd be a hack.
>
> >
> > Kind of separate from the question, but I mean if it's kernel-allocated memory
> > which you're managing separately it should surely be VM_PFNMAP?
>
> OK, I'm a bit confused. What do you mean "managing separately"? You mean
> managing the user space side of things? if so then yes.
>
> Hmm, I haven't heard of VM_PFNMAP, can you explain more its use case.
means either no struct page (e.g. could be I/O mapped device memory) or 'don't
touch struct page it's not for userspace' e.g. kernel allocation.
>
> >
> > It depends if you want to have a refcounted folio underneath though. If you do
> > then yeah don't do that :)
>
> I have no idea what a refcounted folio would do here :-p
Well you are currently treating this as a userland folio.
>
> >
> > In general I'd suggest supporting the fork case if you can, or just let things
> > be wrong if a user does something crazy and undoes the VM_DONTCOPY flag.
>
> OK, so don't add these flags and just allow the forking to happen as this
> patch does (if they screw it up, it's their problem).
>
> This patch is here:
>
> https://lore.kernel.org/all/20260227025842.1085206-1-wangqing7171@gmail.com/
>
> I mean, we allow two separate tasks to mmap the same buffer, and they will
> have the same issues as a fork would have. Thus, I guess the answer is to
> apply this patch?
Well note that vm_ops->open is also called on splitting a VMA (ok I guess you
disable this I think you said) and also mremap()'ing (before it removes the old
VMA, if MREMAP_DONTUNMAP is not set).
Probably all that's fine right? If so then good, and yeah something not-VM_IO
would be best I think!
>
> -- Steve
Cheers, Lorenzo
^ permalink raw reply
* [PATCH RFC 3/3] locking: Wire up contended_release tracepoint
From: Dmitry Ilvokhin @ 2026-03-04 16:56 UTC (permalink / raw)
To: Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Will Deacon, Boqun Feng, Waiman Long
Cc: linux-mm, linux-kernel, linux-trace-kernel, kernel-team,
Dmitry Ilvokhin
In-Reply-To: <cover.1772642407.git.d@ilvokhin.com>
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>
---
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 +++-
6 files changed, 22 insertions(+), 4 deletions(-)
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
index c867f6c15530..54ca045987a2 100644
--- a/kernel/locking/mutex.c
+++ b/kernel/locking/mutex.c
@@ -970,6 +970,7 @@ static noinline void __sched __mutex_unlock_slowpath(struct mutex *lock, unsigne
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 4190635458da..0f2e8e63d252 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);
+
/*
* Signal the writer is done, no fast path yet.
*
@@ -297,6 +299,7 @@ void __percpu_up_read_slowpath(struct percpu_rw_semaphore *sem)
* writer.
*/
smp_mb(); /* B matches C */
+ trace_contended_release(sem);
/*
* 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 c80902eacd79..e0873f0ed982 100644
--- a/kernel/locking/rtmutex.c
+++ b/kernel/locking/rtmutex.c
@@ -1457,6 +1457,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 9f4322c07486..42f3658c0059 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();
@@ -204,6 +206,8 @@ static inline void rwbase_write_unlock(struct rwbase_rt *rwb)
unsigned long flags;
raw_spin_lock_irqsave(&rtm->wait_lock, flags);
+ if (rt_mutex_has_waiters(rtm))
+ trace_contended_release(rwb);
__rwbase_write_unlock(rwb, WRITER_BIAS, flags);
}
@@ -213,6 +217,8 @@ static inline void rwbase_write_downgrade(struct rwbase_rt *rwb)
unsigned long flags;
raw_spin_lock_irqsave(&rtm->wait_lock, flags);
+ if (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 24df4d98f7d2..4e61dc0bb045 100644
--- a/kernel/locking/rwsem.c
+++ b/kernel/locking/rwsem.c
@@ -1360,6 +1360,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();
@@ -1383,8 +1384,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();
}
@@ -1407,8 +1410,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 3ef032e22f7e..3cef5ba88f7e 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.47.3
^ permalink raw reply related
* [PATCH RFC 2/3] locking/percpu-rwsem: Extract __percpu_up_read_slowpath()
From: Dmitry Ilvokhin @ 2026-03-04 16:56 UTC (permalink / raw)
To: Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Will Deacon, Boqun Feng, Waiman Long
Cc: linux-mm, linux-kernel, linux-trace-kernel, kernel-team,
Dmitry Ilvokhin
In-Reply-To: <cover.1772642407.git.d@ilvokhin.com>
Move the percpu_up_read() slowpath out of the inline function into a new
__percpu_up_read_slowpath() 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..89506895365c 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;
}
+void __percpu_up_read_slowpath(struct percpu_rw_semaphore *sem);
+
static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
{
rwsem_release(&sem->dep_map, _RET_IP_);
@@ -118,18 +120,7 @@ static inline void percpu_up_read(struct percpu_rw_semaphore *sem)
if (likely(rcu_sync_is_idle(&sem->rss))) {
this_cpu_dec(*sem->read_count);
} else {
- /*
- * slowpath; reader will only ever wake a single blocked
- * writer.
- */
- smp_mb(); /* B matches C */
- /*
- * In other words, if they see our decrement (presumably to
- * aggregate zero, as that is the only time it matters) they
- * will also see our critical section.
- */
- this_cpu_dec(*sem->read_count);
- rcuwait_wake_up(&sem->writer);
+ __percpu_up_read_slowpath(sem);
}
preempt_enable();
}
diff --git a/kernel/locking/percpu-rwsem.c b/kernel/locking/percpu-rwsem.c
index ef234469baac..4190635458da 100644
--- a/kernel/locking/percpu-rwsem.c
+++ b/kernel/locking/percpu-rwsem.c
@@ -288,3 +288,21 @@ void percpu_up_write(struct percpu_rw_semaphore *sem)
rcu_sync_exit(&sem->rss);
}
EXPORT_SYMBOL_GPL(percpu_up_write);
+
+void __percpu_up_read_slowpath(struct percpu_rw_semaphore *sem)
+{
+ lockdep_assert_preemption_disabled();
+ /*
+ * slowpath; reader will only ever wake a single blocked
+ * writer.
+ */
+ smp_mb(); /* B matches C */
+ /*
+ * In other words, if they see our decrement (presumably to
+ * aggregate zero, as that is the only time it matters) they
+ * will also see our critical section.
+ */
+ this_cpu_dec(*sem->read_count);
+ rcuwait_wake_up(&sem->writer);
+}
+EXPORT_SYMBOL_GPL(__percpu_up_read_slowpath);
--
2.47.3
^ permalink raw reply related
* [PATCH RFC 0/3] locking: contended_release tracepoint instrumentation
From: Dmitry Ilvokhin @ 2026-03-04 16:56 UTC (permalink / raw)
To: Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Will Deacon, Boqun Feng, Waiman Long
Cc: linux-mm, linux-kernel, linux-trace-kernel, kernel-team,
Dmitry Ilvokhin
The existing contention_begin/contention_end tracepoints fire on the
waiter side. The lock holder's identity and stack can be captured at
contention_begin time (e.g. perf lock contention --lock-owner), but
this reflects the holder's state when a waiter arrives, not when the
lock is actually released.
This series adds a contended_release tracepoint that fires on the
holder side when a lock with waiters is released. This provides:
- Hold time estimation: when the holder's own acquisition was
contended, its contention_end (acquisition) and contended_release
can be correlated to measure how long the lock was held under
contention.
- The holder's stack at release time, which may differ from what perf lock
contention --lock-owner captures if the holder does significant work between
the waiter's arrival and the unlock.
The tracepoint is placed exclusively in slowpath unlock paths, so
there is no performance impact on the uncontended fast path and
expected minimal impact on binary size.
Dmitry Ilvokhin (3):
locking: Add contended_release tracepoint
locking/percpu-rwsem: Extract __percpu_up_read_slowpath()
locking: Wire up contended_release tracepoint
include/linux/percpu-rwsem.h | 15 +++------------
include/trace/events/lock.h | 17 +++++++++++++++++
kernel/locking/mutex.c | 1 +
kernel/locking/percpu-rwsem.c | 21 +++++++++++++++++++++
kernel/locking/rtmutex.c | 1 +
kernel/locking/rwbase_rt.c | 8 +++++++-
kernel/locking/rwsem.c | 9 +++++++--
kernel/locking/semaphore.c | 4 +++-
8 files changed, 60 insertions(+), 16 deletions(-)
--
2.47.3
^ permalink raw reply
* [PATCH RFC 1/3] locking: Add contended_release tracepoint
From: Dmitry Ilvokhin @ 2026-03-04 16:56 UTC (permalink / raw)
To: Dennis Zhou, Tejun Heo, Christoph Lameter, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Peter Zijlstra, Ingo Molnar,
Will Deacon, Boqun Feng, Waiman Long
Cc: linux-mm, linux-kernel, linux-trace-kernel, kernel-team,
Dmitry Ilvokhin
In-Reply-To: <cover.1772642407.git.d@ilvokhin.com>
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. Subsequent patches wire this tracepoint into
the individual lock implementations.
Signed-off-by: Dmitry Ilvokhin <d@ilvokhin.com>
---
include/trace/events/lock.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
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 */
--
2.47.3
^ permalink raw reply related
* [PATCH net-next v3 13/13] net/mlx5: Add a shared devlink instance for PFs on same chip
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-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 v3 12/13] documentation: networking: add shared devlink documentation
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-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 v3 11/13] devlink: introduce shared devlink instance for PFs on same chip
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-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 v3 10/13] devlink: allow devlink instance allocation without a backing device
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-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 v3 06/13] devlink: support index-based notification filtering
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Extend the notification filter descriptor with devlink_index so
that userspace can filter notifications by devlink instance index
in addition to bus_name/dev_name.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
net/devlink/devl_internal.h | 4 ++++
net/devlink/netlink.c | 11 ++++++++++-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 395832ed4477..f0ebfb936770 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -205,6 +205,8 @@ struct devlink_obj_desc {
const char *dev_name;
unsigned int port_index;
bool port_index_valid;
+ unsigned int devlink_index;
+ bool devlink_index_valid;
long data[];
};
@@ -214,6 +216,8 @@ static inline void devlink_nl_obj_desc_init(struct devlink_obj_desc *desc,
memset(desc, 0, sizeof(*desc));
desc->bus_name = devlink_bus_name(devlink);
desc->dev_name = devlink_dev_name(devlink);
+ desc->devlink_index = devlink->index;
+ desc->devlink_index_valid = true;
}
static inline void devlink_nl_obj_desc_port_set(struct devlink_obj_desc *desc,
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 5db931a0091c..1b00aa1dbcf5 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -73,13 +73,19 @@ int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
flt->dev_name = pos;
}
+ if (attrs[DEVLINK_ATTR_INDEX]) {
+ flt->devlink_index = nla_get_uint(attrs[DEVLINK_ATTR_INDEX]);
+ flt->devlink_index_valid = true;
+ }
+
if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
flt->port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
flt->port_index_valid = true;
}
/* Don't attach empty filter. */
- if (!flt->bus_name && !flt->dev_name && !flt->port_index_valid) {
+ if (!flt->bus_name && !flt->dev_name &&
+ !flt->devlink_index_valid && !flt->port_index_valid) {
kfree(flt);
flt = NULL;
}
@@ -100,6 +106,9 @@ int devlink_nl_notify_filter_set_doit(struct sk_buff *skb,
static bool devlink_obj_desc_match(const struct devlink_obj_desc *desc,
const struct devlink_obj_desc *flt)
{
+ if (desc->devlink_index_valid && flt->devlink_index_valid &&
+ desc->devlink_index != flt->devlink_index)
+ return false;
if (desc->bus_name && flt->bus_name &&
strcmp(desc->bus_name, flt->bus_name))
return false;
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 09/13] devlink: add devl_warn() helper and use it in port warnings
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-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
* [PATCH net-next v3 08/13] devlink: add devlink_dev_driver_name() helper and use it in trace events
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
In preparation to dev-less devlinks, add devlink_dev_driver_name()
that returns the driver name stored in devlink struct, and use it in
all trace events.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- using stored devlink->dev_driver
v1->v2:
- added missing symbol export
---
include/net/devlink.h | 1 +
include/trace/events/devlink.h | 12 ++++++------
net/devlink/core.c | 6 ++++++
3 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 0afb0958b910..45dec7067a8e 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1613,6 +1613,7 @@ struct devlink *priv_to_devlink(void *priv);
struct device *devlink_to_dev(const struct devlink *devlink);
const char *devlink_bus_name(const struct devlink *devlink);
const char *devlink_dev_name(const struct devlink *devlink);
+const char *devlink_dev_driver_name(const struct devlink *devlink);
/* Devlink instance explicit locking */
void devl_lock(struct devlink *devlink);
diff --git a/include/trace/events/devlink.h b/include/trace/events/devlink.h
index 32304ce9ad15..4f8edf77dfbe 100644
--- a/include/trace/events/devlink.h
+++ b/include/trace/events/devlink.h
@@ -23,7 +23,7 @@ TRACE_EVENT(devlink_hwmsg,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__field(bool, incoming)
__field(unsigned long, type)
__dynamic_array(u8, buf, len)
@@ -57,7 +57,7 @@ TRACE_EVENT(devlink_hwerr,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__field(int, err)
__string(msg, msg)
),
@@ -87,7 +87,7 @@ TRACE_EVENT(devlink_health_report,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__string(reporter_name, reporter_name)
__string(msg, msg)
),
@@ -118,7 +118,7 @@ TRACE_EVENT(devlink_health_recover_aborted,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__string(reporter_name, reporter_name)
__field(bool, health_state)
__field(u64, time_since_last_recover)
@@ -152,7 +152,7 @@ TRACE_EVENT(devlink_health_reporter_state_update,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__string(reporter_name, reporter_name)
__field(u8, new_state)
),
@@ -183,7 +183,7 @@ TRACE_EVENT(devlink_trap_report,
TP_STRUCT__entry(
__string(bus_name, devlink_bus_name(devlink))
__string(dev_name, devlink_dev_name(devlink))
- __string(driver_name, devlink_to_dev(devlink)->driver->name)
+ __string(driver_name, devlink_dev_driver_name(devlink))
__string(trap_name, metadata->trap_name)
__string(trap_group_name, metadata->trap_group_name)
__array(char, input_dev_name, IFNAMSIZ)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index fcb73d3e56aa..34eb06d88544 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -260,6 +260,12 @@ const char *devlink_dev_name(const struct devlink *devlink)
}
EXPORT_SYMBOL_GPL(devlink_dev_name);
+const char *devlink_dev_driver_name(const struct devlink *devlink)
+{
+ return devlink->dev_driver->name;
+}
+EXPORT_SYMBOL_GPL(devlink_dev_driver_name);
+
struct net *devlink_net(const struct devlink *devlink)
{
return read_pnet(&devlink->_net);
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 07/13] devlink: introduce __devlink_alloc() with dev driver pointer
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Introduce __devlink_alloc() as an internal devlink allocator that
accepts a struct device_driver pointer and stores it in the devlink
instance. This allows internal devlink code (e.g. shared instances)
to associate a driver with a devlink instance without need to pass dev
pointer.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- new patch
---
net/devlink/core.c | 40 ++++++++++++++++++++++---------------
net/devlink/devl_internal.h | 5 +++++
2 files changed, 29 insertions(+), 16 deletions(-)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index 237558abcd63..fcb73d3e56aa 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -418,27 +418,15 @@ void devlink_unregister(struct devlink *devlink)
}
EXPORT_SYMBOL_GPL(devlink_unregister);
-/**
- * devlink_alloc_ns - Allocate new devlink instance resources
- * in specific namespace
- *
- * @ops: ops
- * @priv_size: size of user private data
- * @net: net namespace
- * @dev: parent device
- *
- * Allocate new devlink instance resources, including devlink index
- * and name.
- */
-struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
- size_t priv_size, struct net *net,
- struct device *dev)
+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)
{
struct devlink *devlink;
static u32 last_id;
int ret;
- WARN_ON(!ops || !dev);
+ WARN_ON(!ops || !dev || !dev_driver);
if (!devlink_reload_actions_valid(ops))
return NULL;
@@ -453,6 +441,7 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
devlink->dev = get_device(dev);
devlink->ops = ops;
+ devlink->dev_driver = dev_driver;
xa_init_flags(&devlink->ports, XA_FLAGS_ALLOC);
xa_init_flags(&devlink->params, XA_FLAGS_ALLOC);
xa_init_flags(&devlink->snapshot_ids, XA_FLAGS_ALLOC);
@@ -480,6 +469,25 @@ struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
kvfree(devlink);
return NULL;
}
+
+/**
+ * devlink_alloc_ns - Allocate new devlink instance resources
+ * in specific namespace
+ *
+ * @ops: ops
+ * @priv_size: size of user private data
+ * @net: net namespace
+ * @dev: parent device
+ *
+ * Allocate new devlink instance resources, including devlink index
+ * and name.
+ */
+struct devlink *devlink_alloc_ns(const struct devlink_ops *ops,
+ size_t priv_size, struct net *net,
+ struct device *dev)
+{
+ return __devlink_alloc(ops, priv_size, net, dev, dev->driver);
+}
EXPORT_SYMBOL_GPL(devlink_alloc_ns);
/**
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index f0ebfb936770..3cc7e696e0fd 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 struct device_driver *dev_driver;
possible_net_t _net;
/* Serializes access to devlink instance specific objects such as
* port, sb, dpipe, resource, params, region, traps and more.
@@ -66,6 +67,10 @@ struct devlink {
extern struct xarray devlinks;
extern struct genl_family devlink_nl_family;
+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);
+
/* 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.
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 05/13] devlink: support index-based lookup via bus_name/dev_name handle
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Devlink instances without a backing device use bus_name
"devlink_index" and dev_name set to the decimal index string.
When user space sends this handle, detect the pattern and perform
a direct xarray lookup by index instead of iterating all instances.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- unify return value -ENODEV even in case non-numeric dev_name
v1->v2:
- moved DEVLINK_INDEX_BUS_NAME definition here from patch #7
---
include/uapi/linux/devlink.h | 2 ++
net/devlink/netlink.c | 9 +++++++++
2 files changed, 11 insertions(+)
diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 1ba3436db4ae..7de2d8cc862f 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -19,6 +19,8 @@
#define DEVLINK_GENL_VERSION 0x1
#define DEVLINK_GENL_MCGRP_CONFIG_NAME "config"
+#define DEVLINK_INDEX_BUS_NAME "devlink_index"
+
enum devlink_command {
/* don't change the order or add anything between, this is ABI! */
DEVLINK_CMD_UNSPEC,
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index e73e39116365..5db931a0091c 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -208,6 +208,15 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
+ if (!strcmp(busname, DEVLINK_INDEX_BUS_NAME)) {
+ if (kstrtoul(devname, 10, &index))
+ return ERR_PTR(-ENODEV);
+ devlink = devlinks_xa_lookup_get(net, index);
+ if (!devlink)
+ return ERR_PTR(-ENODEV);
+ goto found;
+ }
+
devlinks_xa_for_each_registered_get(net, index, devlink) {
if (strcmp(devlink_bus_name(devlink), busname) == 0 &&
strcmp(devlink_dev_name(devlink), devname) == 0)
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 04/13] devlink: allow to use devlink index as a command handle
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Currently devlink instances are addressed bus_name/dev_name tuple.
Allow the newly introduced DEVLINK_ATTR_INDEX to be used as
an alternative handle for all devlink commands.
When DEVLINK_ATTR_INDEX is present in the request, use it for a direct
xarray lookup instead of iterating over all instances comparing
bus_name/dev_name strings.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- check out of bounds index
- reject mixture of handle approaches
---
Documentation/netlink/specs/devlink.yaml | 51 ++++
net/devlink/core.c | 16 +-
net/devlink/devl_internal.h | 1 +
net/devlink/netlink.c | 19 +-
net/devlink/netlink_gen.c | 350 ++++++++++++++---------
5 files changed, 294 insertions(+), 143 deletions(-)
diff --git a/Documentation/netlink/specs/devlink.yaml b/Documentation/netlink/specs/devlink.yaml
index 1bed67a0eefb..a73a86ec595d 100644
--- a/Documentation/netlink/specs/devlink.yaml
+++ b/Documentation/netlink/specs/devlink.yaml
@@ -1310,6 +1310,7 @@ operations:
attributes: &dev-id-attrs
- bus-name
- dev-name
+ - index
reply: &get-reply
value: 3
attributes:
@@ -1334,6 +1335,7 @@ operations:
attributes: &port-id-attrs
- bus-name
- dev-name
+ - index
- port-index
reply:
value: 7
@@ -1358,6 +1360,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- port-type
- port-function
@@ -1375,6 +1378,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- port-flavour
- port-pci-pf-number
@@ -1409,6 +1413,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- port-split-count
@@ -1437,6 +1442,7 @@ operations:
attributes: &sb-id-attrs
- bus-name
- dev-name
+ - index
- sb-index
reply: &sb-get-reply
value: 13
@@ -1459,6 +1465,7 @@ operations:
attributes: &sb-pool-id-attrs
- bus-name
- dev-name
+ - index
- sb-index
- sb-pool-index
reply: &sb-pool-get-reply
@@ -1482,6 +1489,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- sb-index
- sb-pool-index
- sb-pool-threshold-type
@@ -1500,6 +1508,7 @@ operations:
attributes: &sb-port-pool-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- sb-index
- sb-pool-index
@@ -1524,6 +1533,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- sb-index
- sb-pool-index
@@ -1542,6 +1552,7 @@ operations:
attributes: &sb-tc-pool-bind-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- sb-index
- sb-pool-type
@@ -1567,6 +1578,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- sb-index
- sb-pool-index
@@ -1588,6 +1600,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- sb-index
-
@@ -1603,6 +1616,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- sb-index
-
@@ -1621,6 +1635,7 @@ operations:
attributes: &eswitch-attrs
- bus-name
- dev-name
+ - index
- eswitch-mode
- eswitch-inline-mode
- eswitch-encap-mode
@@ -1649,12 +1664,14 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- dpipe-table-name
reply:
value: 31
attributes:
- bus-name
- dev-name
+ - index
- dpipe-tables
-
@@ -1669,11 +1686,13 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- dpipe-table-name
reply:
attributes:
- bus-name
- dev-name
+ - index
- dpipe-entries
-
@@ -1688,10 +1707,12 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
reply:
attributes:
- bus-name
- dev-name
+ - index
- dpipe-headers
-
@@ -1707,6 +1728,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- dpipe-table-name
- dpipe-table-counters-enabled
@@ -1723,6 +1745,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- resource-id
- resource-size
@@ -1738,11 +1761,13 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
reply:
value: 36
attributes:
- bus-name
- dev-name
+ - index
- resource-list
-
@@ -1758,6 +1783,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- reload-action
- reload-limits
- netns-pid
@@ -1767,6 +1793,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- reload-actions-performed
-
@@ -1781,6 +1808,7 @@ operations:
attributes: ¶m-id-attrs
- bus-name
- dev-name
+ - index
- param-name
reply: ¶m-get-reply
attributes: *param-id-attrs
@@ -1802,6 +1830,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- param-name
- param-type
# param-value-data is missing here as the type is variable
@@ -1821,6 +1850,7 @@ operations:
attributes: ®ion-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- region-name
reply: ®ion-get-reply
@@ -1845,6 +1875,7 @@ operations:
attributes: ®ion-snapshot-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- region-name
- region-snapshot-id
@@ -1875,6 +1906,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- region-name
- region-snapshot-id
@@ -1886,6 +1918,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- region-name
@@ -1935,6 +1968,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- info-driver-name
- info-serial-number
- info-version-fixed
@@ -1956,6 +1990,7 @@ operations:
attributes: &health-reporter-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- health-reporter-name
reply: &health-reporter-get-reply
@@ -1978,6 +2013,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
- health-reporter-name
- health-reporter-graceful-period
@@ -2048,6 +2084,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- flash-update-file-name
- flash-update-component
- flash-update-overwrite-mask
@@ -2065,6 +2102,7 @@ operations:
attributes: &trap-id-attrs
- bus-name
- dev-name
+ - index
- trap-name
reply: &trap-get-reply
value: 63
@@ -2087,6 +2125,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- trap-name
- trap-action
@@ -2103,6 +2142,7 @@ operations:
attributes: &trap-group-id-attrs
- bus-name
- dev-name
+ - index
- trap-group-name
reply: &trap-group-get-reply
value: 67
@@ -2125,6 +2165,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- trap-group-name
- trap-action
- trap-policer-id
@@ -2142,6 +2183,7 @@ operations:
attributes: &trap-policer-id-attrs
- bus-name
- dev-name
+ - index
- trap-policer-id
reply: &trap-policer-get-reply
value: 71
@@ -2164,6 +2206,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- trap-policer-id
- trap-policer-rate
- trap-policer-burst
@@ -2194,6 +2237,7 @@ operations:
attributes: &rate-id-attrs
- bus-name
- dev-name
+ - index
- port-index
- rate-node-name
reply: &rate-get-reply
@@ -2217,6 +2261,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- rate-node-name
- rate-tx-share
- rate-tx-max
@@ -2238,6 +2283,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- rate-node-name
- rate-tx-share
- rate-tx-max
@@ -2259,6 +2305,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- rate-node-name
-
@@ -2274,6 +2321,7 @@ operations:
attributes: &linecard-id-attrs
- bus-name
- dev-name
+ - index
- linecard-index
reply: &linecard-get-reply
value: 80
@@ -2296,6 +2344,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- linecard-index
- linecard-type
@@ -2329,6 +2378,7 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- selftests
-
@@ -2340,4 +2390,5 @@ operations:
attributes:
- bus-name
- dev-name
+ - index
- port-index
diff --git a/net/devlink/core.c b/net/devlink/core.c
index 63709c132a7c..237558abcd63 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -333,13 +333,15 @@ void devlink_put(struct devlink *devlink)
queue_rcu_work(system_percpu_wq, &devlink->rwork);
}
-struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp)
+static struct devlink *__devlinks_xa_find_get(struct net *net,
+ unsigned long *indexp,
+ unsigned long end)
{
struct devlink *devlink = NULL;
rcu_read_lock();
retry:
- devlink = xa_find(&devlinks, indexp, ULONG_MAX, DEVLINK_REGISTERED);
+ devlink = xa_find(&devlinks, indexp, end, DEVLINK_REGISTERED);
if (!devlink)
goto unlock;
@@ -358,6 +360,16 @@ struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp)
goto retry;
}
+struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp)
+{
+ return __devlinks_xa_find_get(net, indexp, ULONG_MAX);
+}
+
+struct devlink *devlinks_xa_lookup_get(struct net *net, unsigned long index)
+{
+ return __devlinks_xa_find_get(net, &index, index);
+}
+
/**
* devl_register - Register devlink instance
* @devlink: devlink
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 1b770de0313e..395832ed4477 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -90,6 +90,7 @@ extern struct genl_family devlink_nl_family;
for (index = 0; (devlink = devlinks_xa_find_get(net, &index)); index++)
struct devlink *devlinks_xa_find_get(struct net *net, unsigned long *indexp);
+struct devlink *devlinks_xa_lookup_get(struct net *net, unsigned long index);
static inline bool __devl_is_registered(struct devlink *devlink)
{
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 7b205f677b7a..e73e39116365 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -186,6 +186,22 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
char *busname;
char *devname;
+ if (attrs[DEVLINK_ATTR_INDEX]) {
+ u64 tmp;
+
+ if (attrs[DEVLINK_ATTR_BUS_NAME] ||
+ attrs[DEVLINK_ATTR_DEV_NAME])
+ return ERR_PTR(-EINVAL);
+ tmp = nla_get_uint(attrs[DEVLINK_ATTR_INDEX]);
+ if (tmp > U32_MAX)
+ return ERR_PTR(-EINVAL);
+ index = tmp;
+ devlink = devlinks_xa_lookup_get(net, index);
+ if (!devlink)
+ return ERR_PTR(-ENODEV);
+ goto found;
+ }
+
if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
return ERR_PTR(-EINVAL);
@@ -356,7 +372,8 @@ int devlink_nl_dumpit(struct sk_buff *msg, struct netlink_callback *cb,
int flags = NLM_F_MULTI;
if (attrs &&
- (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME]))
+ (attrs[DEVLINK_ATTR_BUS_NAME] || attrs[DEVLINK_ATTR_DEV_NAME] ||
+ attrs[DEVLINK_ATTR_INDEX]))
return devlink_nl_inst_single_dumpit(msg, cb, flags, dump_one,
attrs);
else
diff --git a/net/devlink/netlink_gen.c b/net/devlink/netlink_gen.c
index f4c61c2b4f22..9812897c5524 100644
--- a/net/devlink/netlink_gen.c
+++ b/net/devlink/netlink_gen.c
@@ -56,37 +56,42 @@ const struct nla_policy devlink_dl_selftest_id_nl_policy[DEVLINK_ATTR_SELFTEST_I
};
/* DEVLINK_CMD_GET - do */
-static const struct nla_policy devlink_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_PORT_GET - do */
-static const struct nla_policy devlink_port_get_do_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_port_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_PORT_GET - dump */
-static const struct nla_policy devlink_port_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_port_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_PORT_SET - do */
-static const struct nla_policy devlink_port_set_nl_policy[DEVLINK_ATTR_PORT_FUNCTION + 1] = {
+static const struct nla_policy devlink_port_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_PORT_TYPE] = NLA_POLICY_MAX(NLA_U16, 3),
[DEVLINK_ATTR_PORT_FUNCTION] = NLA_POLICY_NESTED(devlink_dl_port_function_nl_policy),
};
/* DEVLINK_CMD_PORT_NEW - do */
-static const struct nla_policy devlink_port_new_nl_policy[DEVLINK_ATTR_PORT_PCI_SF_NUMBER + 1] = {
+static const struct nla_policy devlink_port_new_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_PORT_FLAVOUR] = NLA_POLICY_MAX(NLA_U16, 7),
[DEVLINK_ATTR_PORT_PCI_PF_NUMBER] = { .type = NLA_U16, },
@@ -95,58 +100,66 @@ static const struct nla_policy devlink_port_new_nl_policy[DEVLINK_ATTR_PORT_PCI_
};
/* DEVLINK_CMD_PORT_DEL - do */
-static const struct nla_policy devlink_port_del_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_port_del_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_PORT_SPLIT - do */
-static const struct nla_policy devlink_port_split_nl_policy[DEVLINK_ATTR_PORT_SPLIT_COUNT + 1] = {
+static const struct nla_policy devlink_port_split_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_PORT_UNSPLIT - do */
-static const struct nla_policy devlink_port_unsplit_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_port_unsplit_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_SB_GET - do */
-static const struct nla_policy devlink_sb_get_do_nl_policy[DEVLINK_ATTR_SB_INDEX + 1] = {
+static const struct nla_policy devlink_sb_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_SB_GET - dump */
-static const struct nla_policy devlink_sb_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_sb_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_SB_POOL_GET - do */
-static const struct nla_policy devlink_sb_pool_get_do_nl_policy[DEVLINK_ATTR_SB_POOL_INDEX + 1] = {
+static const struct nla_policy devlink_sb_pool_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16, },
};
/* DEVLINK_CMD_SB_POOL_GET - dump */
-static const struct nla_policy devlink_sb_pool_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_sb_pool_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_SB_POOL_SET - do */
-static const struct nla_policy devlink_sb_pool_set_nl_policy[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE + 1] = {
+static const struct nla_policy devlink_sb_pool_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16, },
[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = NLA_POLICY_MAX(NLA_U8, 1),
@@ -154,24 +167,27 @@ static const struct nla_policy devlink_sb_pool_set_nl_policy[DEVLINK_ATTR_SB_POO
};
/* DEVLINK_CMD_SB_PORT_POOL_GET - do */
-static const struct nla_policy devlink_sb_port_pool_get_do_nl_policy[DEVLINK_ATTR_SB_POOL_INDEX + 1] = {
+static const struct nla_policy devlink_sb_port_pool_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16, },
};
/* DEVLINK_CMD_SB_PORT_POOL_GET - dump */
-static const struct nla_policy devlink_sb_port_pool_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_sb_port_pool_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_SB_PORT_POOL_SET - do */
-static const struct nla_policy devlink_sb_port_pool_set_nl_policy[DEVLINK_ATTR_SB_THRESHOLD + 1] = {
+static const struct nla_policy devlink_sb_port_pool_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16, },
@@ -179,9 +195,10 @@ static const struct nla_policy devlink_sb_port_pool_set_nl_policy[DEVLINK_ATTR_S
};
/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - do */
-static const struct nla_policy devlink_sb_tc_pool_bind_get_do_nl_policy[DEVLINK_ATTR_SB_TC_INDEX + 1] = {
+static const struct nla_policy devlink_sb_tc_pool_bind_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_TYPE] = NLA_POLICY_MAX(NLA_U8, 1),
@@ -189,15 +206,17 @@ static const struct nla_policy devlink_sb_tc_pool_bind_get_do_nl_policy[DEVLINK_
};
/* DEVLINK_CMD_SB_TC_POOL_BIND_GET - dump */
-static const struct nla_policy devlink_sb_tc_pool_bind_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_sb_tc_pool_bind_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_SB_TC_POOL_BIND_SET - do */
-static const struct nla_policy devlink_sb_tc_pool_bind_set_nl_policy[DEVLINK_ATTR_SB_TC_INDEX + 1] = {
+static const struct nla_policy devlink_sb_tc_pool_bind_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16, },
@@ -207,80 +226,91 @@ static const struct nla_policy devlink_sb_tc_pool_bind_set_nl_policy[DEVLINK_ATT
};
/* DEVLINK_CMD_SB_OCC_SNAPSHOT - do */
-static const struct nla_policy devlink_sb_occ_snapshot_nl_policy[DEVLINK_ATTR_SB_INDEX + 1] = {
+static const struct nla_policy devlink_sb_occ_snapshot_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_SB_OCC_MAX_CLEAR - do */
-static const struct nla_policy devlink_sb_occ_max_clear_nl_policy[DEVLINK_ATTR_SB_INDEX + 1] = {
+static const struct nla_policy devlink_sb_occ_max_clear_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_ESWITCH_GET - do */
-static const struct nla_policy devlink_eswitch_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_eswitch_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_ESWITCH_SET - do */
-static const struct nla_policy devlink_eswitch_set_nl_policy[DEVLINK_ATTR_ESWITCH_ENCAP_MODE + 1] = {
+static const struct nla_policy devlink_eswitch_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_ESWITCH_MODE] = NLA_POLICY_MAX(NLA_U16, 2),
[DEVLINK_ATTR_ESWITCH_INLINE_MODE] = NLA_POLICY_MAX(NLA_U8, 3),
[DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = NLA_POLICY_MAX(NLA_U8, 1),
};
/* DEVLINK_CMD_DPIPE_TABLE_GET - do */
-static const struct nla_policy devlink_dpipe_table_get_nl_policy[DEVLINK_ATTR_DPIPE_TABLE_NAME + 1] = {
+static const struct nla_policy devlink_dpipe_table_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_DPIPE_ENTRIES_GET - do */
-static const struct nla_policy devlink_dpipe_entries_get_nl_policy[DEVLINK_ATTR_DPIPE_TABLE_NAME + 1] = {
+static const struct nla_policy devlink_dpipe_entries_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_DPIPE_HEADERS_GET - do */
-static const struct nla_policy devlink_dpipe_headers_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_dpipe_headers_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET - do */
-static const struct nla_policy devlink_dpipe_table_counters_set_nl_policy[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED + 1] = {
+static const struct nla_policy devlink_dpipe_table_counters_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8, },
};
/* DEVLINK_CMD_RESOURCE_SET - do */
-static const struct nla_policy devlink_resource_set_nl_policy[DEVLINK_ATTR_RESOURCE_SIZE + 1] = {
+static const struct nla_policy devlink_resource_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64, },
[DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64, },
};
/* DEVLINK_CMD_RESOURCE_DUMP - do */
-static const struct nla_policy devlink_resource_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_resource_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_RELOAD - do */
-static const struct nla_policy devlink_reload_nl_policy[DEVLINK_ATTR_RELOAD_LIMITS + 1] = {
+static const struct nla_policy devlink_reload_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_RELOAD_ACTION] = NLA_POLICY_RANGE(NLA_U8, 1, 2),
[DEVLINK_ATTR_RELOAD_LIMITS] = NLA_POLICY_BITFIELD32(6),
[DEVLINK_ATTR_NETNS_PID] = { .type = NLA_U32, },
@@ -289,22 +319,25 @@ static const struct nla_policy devlink_reload_nl_policy[DEVLINK_ATTR_RELOAD_LIMI
};
/* DEVLINK_CMD_PARAM_GET - do */
-static const struct nla_policy devlink_param_get_do_nl_policy[DEVLINK_ATTR_PARAM_NAME + 1] = {
+static const struct nla_policy devlink_param_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_PARAM_GET - dump */
-static const struct nla_policy devlink_param_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_param_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_PARAM_SET - do */
-static const struct nla_policy devlink_param_set_nl_policy[DEVLINK_ATTR_PARAM_RESET_DEFAULT + 1] = {
+static const struct nla_policy devlink_param_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_PARAM_TYPE] = NLA_POLICY_VALIDATE_FN(NLA_U8, &devlink_attr_param_type_validate),
[DEVLINK_ATTR_PARAM_VALUE_CMODE] = NLA_POLICY_MAX(NLA_U8, 2),
@@ -312,41 +345,46 @@ static const struct nla_policy devlink_param_set_nl_policy[DEVLINK_ATTR_PARAM_RE
};
/* DEVLINK_CMD_REGION_GET - do */
-static const struct nla_policy devlink_region_get_do_nl_policy[DEVLINK_ATTR_REGION_NAME + 1] = {
+static const struct nla_policy devlink_region_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_REGION_GET - dump */
-static const struct nla_policy devlink_region_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_region_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_REGION_NEW - do */
-static const struct nla_policy devlink_region_new_nl_policy[DEVLINK_ATTR_REGION_SNAPSHOT_ID + 1] = {
+static const struct nla_policy devlink_region_new_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_REGION_DEL - do */
-static const struct nla_policy devlink_region_del_nl_policy[DEVLINK_ATTR_REGION_SNAPSHOT_ID + 1] = {
+static const struct nla_policy devlink_region_del_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_REGION_READ - dump */
-static const struct nla_policy devlink_region_read_nl_policy[DEVLINK_ATTR_REGION_DIRECT + 1] = {
+static const struct nla_policy devlink_region_read_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32, },
@@ -356,44 +394,50 @@ static const struct nla_policy devlink_region_read_nl_policy[DEVLINK_ATTR_REGION
};
/* DEVLINK_CMD_PORT_PARAM_GET - do */
-static const struct nla_policy devlink_port_param_get_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_port_param_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_PORT_PARAM_SET - do */
-static const struct nla_policy devlink_port_param_set_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_port_param_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_INFO_GET - do */
-static const struct nla_policy devlink_info_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_info_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_GET - do */
-static const struct nla_policy devlink_health_reporter_get_do_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_GET - dump */
-static const struct nla_policy devlink_health_reporter_get_dump_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_health_reporter_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_SET - do */
-static const struct nla_policy devlink_health_reporter_set_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_BURST_PERIOD + 1] = {
+static const struct nla_policy devlink_health_reporter_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64, },
@@ -403,137 +447,155 @@ static const struct nla_policy devlink_health_reporter_set_nl_policy[DEVLINK_ATT
};
/* DEVLINK_CMD_HEALTH_REPORTER_RECOVER - do */
-static const struct nla_policy devlink_health_reporter_recover_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_recover_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE - do */
-static const struct nla_policy devlink_health_reporter_diagnose_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_diagnose_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET - dump */
-static const struct nla_policy devlink_health_reporter_dump_get_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_dump_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR - do */
-static const struct nla_policy devlink_health_reporter_dump_clear_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_dump_clear_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_FLASH_UPDATE - do */
-static const struct nla_policy devlink_flash_update_nl_policy[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK + 1] = {
+static const struct nla_policy devlink_flash_update_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK] = NLA_POLICY_BITFIELD32(3),
};
/* DEVLINK_CMD_TRAP_GET - do */
-static const struct nla_policy devlink_trap_get_do_nl_policy[DEVLINK_ATTR_TRAP_NAME + 1] = {
+static const struct nla_policy devlink_trap_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_TRAP_GET - dump */
-static const struct nla_policy devlink_trap_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_trap_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_TRAP_SET - do */
-static const struct nla_policy devlink_trap_set_nl_policy[DEVLINK_ATTR_TRAP_ACTION + 1] = {
+static const struct nla_policy devlink_trap_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_TRAP_ACTION] = NLA_POLICY_MAX(NLA_U8, 2),
};
/* DEVLINK_CMD_TRAP_GROUP_GET - do */
-static const struct nla_policy devlink_trap_group_get_do_nl_policy[DEVLINK_ATTR_TRAP_GROUP_NAME + 1] = {
+static const struct nla_policy devlink_trap_group_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_TRAP_GROUP_GET - dump */
-static const struct nla_policy devlink_trap_group_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_trap_group_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_TRAP_GROUP_SET - do */
-static const struct nla_policy devlink_trap_group_set_nl_policy[DEVLINK_ATTR_TRAP_POLICER_ID + 1] = {
+static const struct nla_policy devlink_trap_group_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_GROUP_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_TRAP_ACTION] = NLA_POLICY_MAX(NLA_U8, 2),
[DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_TRAP_POLICER_GET - do */
-static const struct nla_policy devlink_trap_policer_get_do_nl_policy[DEVLINK_ATTR_TRAP_POLICER_ID + 1] = {
+static const struct nla_policy devlink_trap_policer_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_TRAP_POLICER_GET - dump */
-static const struct nla_policy devlink_trap_policer_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_trap_policer_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_TRAP_POLICER_SET - do */
-static const struct nla_policy devlink_trap_policer_set_nl_policy[DEVLINK_ATTR_TRAP_POLICER_BURST + 1] = {
+static const struct nla_policy devlink_trap_policer_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_TRAP_POLICER_ID] = { .type = NLA_U32, },
[DEVLINK_ATTR_TRAP_POLICER_RATE] = { .type = NLA_U64, },
[DEVLINK_ATTR_TRAP_POLICER_BURST] = { .type = NLA_U64, },
};
/* DEVLINK_CMD_HEALTH_REPORTER_TEST - do */
-static const struct nla_policy devlink_health_reporter_test_nl_policy[DEVLINK_ATTR_HEALTH_REPORTER_NAME + 1] = {
+static const struct nla_policy devlink_health_reporter_test_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_RATE_GET - do */
-static const struct nla_policy devlink_rate_get_do_nl_policy[DEVLINK_ATTR_RATE_NODE_NAME + 1] = {
+static const struct nla_policy devlink_rate_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_RATE_GET - dump */
-static const struct nla_policy devlink_rate_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_rate_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_RATE_SET - do */
-static const struct nla_policy devlink_rate_set_nl_policy[DEVLINK_ATTR_RATE_TC_BWS + 1] = {
+static const struct nla_policy devlink_rate_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64, },
[DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64, },
@@ -544,9 +606,10 @@ static const struct nla_policy devlink_rate_set_nl_policy[DEVLINK_ATTR_RATE_TC_B
};
/* DEVLINK_CMD_RATE_NEW - do */
-static const struct nla_policy devlink_rate_new_nl_policy[DEVLINK_ATTR_RATE_TC_BWS + 1] = {
+static const struct nla_policy devlink_rate_new_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_RATE_TX_SHARE] = { .type = NLA_U64, },
[DEVLINK_ATTR_RATE_TX_MAX] = { .type = NLA_U64, },
@@ -557,50 +620,57 @@ static const struct nla_policy devlink_rate_new_nl_policy[DEVLINK_ATTR_RATE_TC_B
};
/* DEVLINK_CMD_RATE_DEL - do */
-static const struct nla_policy devlink_rate_del_nl_policy[DEVLINK_ATTR_RATE_NODE_NAME + 1] = {
+static const struct nla_policy devlink_rate_del_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_RATE_NODE_NAME] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_LINECARD_GET - do */
-static const struct nla_policy devlink_linecard_get_do_nl_policy[DEVLINK_ATTR_LINECARD_INDEX + 1] = {
+static const struct nla_policy devlink_linecard_get_do_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32, },
};
/* DEVLINK_CMD_LINECARD_GET - dump */
-static const struct nla_policy devlink_linecard_get_dump_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_linecard_get_dump_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_LINECARD_SET - do */
-static const struct nla_policy devlink_linecard_set_nl_policy[DEVLINK_ATTR_LINECARD_TYPE + 1] = {
+static const struct nla_policy devlink_linecard_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32, },
[DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING, },
};
/* DEVLINK_CMD_SELFTESTS_GET - do */
-static const struct nla_policy devlink_selftests_get_nl_policy[DEVLINK_ATTR_DEV_NAME + 1] = {
+static const struct nla_policy devlink_selftests_get_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
};
/* DEVLINK_CMD_SELFTESTS_RUN - do */
-static const struct nla_policy devlink_selftests_run_nl_policy[DEVLINK_ATTR_SELFTESTS + 1] = {
+static const struct nla_policy devlink_selftests_run_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_SELFTESTS] = NLA_POLICY_NESTED(devlink_dl_selftest_id_nl_policy),
};
/* DEVLINK_CMD_NOTIFY_FILTER_SET - do */
-static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_PORT_INDEX + 1] = {
+static const struct nla_policy devlink_notify_filter_set_nl_policy[DEVLINK_ATTR_INDEX + 1] = {
[DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING, },
[DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING, },
+ [DEVLINK_ATTR_INDEX] = { .type = NLA_UINT, },
[DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32, },
};
@@ -613,7 +683,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -629,14 +699,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_PORT_GET,
.dumpit = devlink_nl_port_get_dumpit,
.policy = devlink_port_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -646,7 +716,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_set_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_FUNCTION,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -656,7 +726,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_new_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_new_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -666,7 +736,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_del_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_del_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -676,7 +746,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_split_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_split_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_SPLIT_COUNT,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -686,7 +756,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_unsplit_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_unsplit_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -696,14 +766,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_SB_GET,
.dumpit = devlink_nl_sb_get_dumpit,
.policy = devlink_sb_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -713,14 +783,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_pool_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_pool_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_POOL_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_SB_POOL_GET,
.dumpit = devlink_nl_sb_pool_get_dumpit,
.policy = devlink_sb_pool_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -730,7 +800,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_pool_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_pool_set_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -740,14 +810,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_port_pool_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_port_pool_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_POOL_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
.dumpit = devlink_nl_sb_port_pool_get_dumpit,
.policy = devlink_sb_port_pool_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -757,7 +827,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_port_pool_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_port_pool_set_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_THRESHOLD,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -767,14 +837,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_tc_pool_bind_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_tc_pool_bind_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_TC_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
.dumpit = devlink_nl_sb_tc_pool_bind_get_dumpit,
.policy = devlink_sb_tc_pool_bind_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -784,7 +854,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_tc_pool_bind_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_tc_pool_bind_set_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_TC_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -794,7 +864,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_occ_snapshot_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_occ_snapshot_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -804,7 +874,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_sb_occ_max_clear_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_sb_occ_max_clear_nl_policy,
- .maxattr = DEVLINK_ATTR_SB_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -814,7 +884,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_eswitch_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_eswitch_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -824,7 +894,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_eswitch_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_eswitch_set_nl_policy,
- .maxattr = DEVLINK_ATTR_ESWITCH_ENCAP_MODE,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -834,7 +904,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_dpipe_table_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_dpipe_table_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DPIPE_TABLE_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -844,7 +914,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_dpipe_entries_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_dpipe_entries_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DPIPE_TABLE_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -854,7 +924,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_dpipe_headers_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_dpipe_headers_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -864,7 +934,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_dpipe_table_counters_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_dpipe_table_counters_set_nl_policy,
- .maxattr = DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -874,7 +944,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_resource_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_resource_set_nl_policy,
- .maxattr = DEVLINK_ATTR_RESOURCE_SIZE,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -884,7 +954,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_resource_dump_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_resource_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -894,7 +964,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_reload_doit,
.post_doit = devlink_nl_post_doit_dev_lock,
.policy = devlink_reload_nl_policy,
- .maxattr = DEVLINK_ATTR_RELOAD_LIMITS,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -904,14 +974,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_param_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_param_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_PARAM_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_PARAM_GET,
.dumpit = devlink_nl_param_get_dumpit,
.policy = devlink_param_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -921,7 +991,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_param_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_param_set_nl_policy,
- .maxattr = DEVLINK_ATTR_PARAM_RESET_DEFAULT,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -931,14 +1001,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_region_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_region_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_REGION_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_REGION_GET,
.dumpit = devlink_nl_region_get_dumpit,
.policy = devlink_region_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -948,7 +1018,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_region_new_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_region_new_nl_policy,
- .maxattr = DEVLINK_ATTR_REGION_SNAPSHOT_ID,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -958,7 +1028,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_region_del_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_region_del_nl_policy,
- .maxattr = DEVLINK_ATTR_REGION_SNAPSHOT_ID,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -966,7 +1036,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.validate = GENL_DONT_VALIDATE_DUMP_STRICT,
.dumpit = devlink_nl_region_read_dumpit,
.policy = devlink_region_read_nl_policy,
- .maxattr = DEVLINK_ATTR_REGION_DIRECT,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
},
{
@@ -976,7 +1046,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_param_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_param_get_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -992,7 +1062,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_port_param_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_port_param_set_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1002,7 +1072,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_info_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_info_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -1018,14 +1088,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
.dumpit = devlink_nl_health_reporter_get_dumpit,
.policy = devlink_health_reporter_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1035,7 +1105,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_set_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_BURST_PERIOD,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1045,7 +1115,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_recover_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_recover_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1055,7 +1125,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_diagnose_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_diagnose_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1063,7 +1133,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.validate = GENL_DONT_VALIDATE_DUMP_STRICT,
.dumpit = devlink_nl_health_reporter_dump_get_dumpit,
.policy = devlink_health_reporter_dump_get_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
},
{
@@ -1073,7 +1143,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_dump_clear_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_dump_clear_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1083,7 +1153,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_flash_update_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_flash_update_nl_policy,
- .maxattr = DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1093,14 +1163,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_TRAP_GET,
.dumpit = devlink_nl_trap_get_dumpit,
.policy = devlink_trap_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1110,7 +1180,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_set_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_ACTION,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1120,14 +1190,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_group_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_group_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_GROUP_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_TRAP_GROUP_GET,
.dumpit = devlink_nl_trap_group_get_dumpit,
.policy = devlink_trap_group_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1137,7 +1207,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_group_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_group_set_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_POLICER_ID,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1147,14 +1217,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_policer_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_policer_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_POLICER_ID,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_TRAP_POLICER_GET,
.dumpit = devlink_nl_trap_policer_get_dumpit,
.policy = devlink_trap_policer_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1164,7 +1234,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_trap_policer_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_trap_policer_set_nl_policy,
- .maxattr = DEVLINK_ATTR_TRAP_POLICER_BURST,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1174,7 +1244,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_health_reporter_test_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_health_reporter_test_nl_policy,
- .maxattr = DEVLINK_ATTR_HEALTH_REPORTER_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1184,14 +1254,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_rate_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_rate_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_RATE_NODE_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_RATE_GET,
.dumpit = devlink_nl_rate_get_dumpit,
.policy = devlink_rate_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1201,7 +1271,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_rate_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_rate_set_nl_policy,
- .maxattr = DEVLINK_ATTR_RATE_TC_BWS,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1211,7 +1281,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_rate_new_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_rate_new_nl_policy,
- .maxattr = DEVLINK_ATTR_RATE_TC_BWS,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1221,7 +1291,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_rate_del_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_rate_del_nl_policy,
- .maxattr = DEVLINK_ATTR_RATE_NODE_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1231,14 +1301,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_linecard_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_linecard_get_do_nl_policy,
- .maxattr = DEVLINK_ATTR_LINECARD_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_LINECARD_GET,
.dumpit = devlink_nl_linecard_get_dumpit,
.policy = devlink_linecard_get_dump_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DUMP,
},
{
@@ -1248,7 +1318,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_linecard_set_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_linecard_set_nl_policy,
- .maxattr = DEVLINK_ATTR_LINECARD_TYPE,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
@@ -1258,7 +1328,7 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_selftests_get_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_selftests_get_nl_policy,
- .maxattr = DEVLINK_ATTR_DEV_NAME,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
{
@@ -1274,14 +1344,14 @@ const struct genl_split_ops devlink_nl_ops[74] = {
.doit = devlink_nl_selftests_run_doit,
.post_doit = devlink_nl_post_doit,
.policy = devlink_selftests_run_nl_policy,
- .maxattr = DEVLINK_ATTR_SELFTESTS,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
},
{
.cmd = DEVLINK_CMD_NOTIFY_FILTER_SET,
.doit = devlink_nl_notify_filter_set_doit,
.policy = devlink_notify_filter_set_nl_policy,
- .maxattr = DEVLINK_ATTR_PORT_INDEX,
+ .maxattr = DEVLINK_ATTR_INDEX,
.flags = GENL_CMD_CAP_DO,
},
};
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 02/13] devlink: add helpers to get bus_name/dev_name
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Introduce devlink_bus_name() and devlink_dev_name() helpers and
convert all direct accesses to devlink->dev->bus->name and
dev_name(devlink->dev) to use them.
This prepares for dev-less devlink instances where these helpers
will be extended to handle the missing device.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
v2->v3:
- don't store bus_name/dev_name in devlink struct
---
include/net/devlink.h | 2 ++
include/trace/events/devlink.h | 24 ++++++++++++------------
net/devlink/core.c | 12 ++++++++++++
net/devlink/devl_internal.h | 8 ++++----
net/devlink/netlink.c | 4 ++--
net/devlink/port.c | 4 ++--
6 files changed, 34 insertions(+), 20 deletions(-)
diff --git a/include/net/devlink.h b/include/net/devlink.h
index cb839e0435a1..0afb0958b910 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -1611,6 +1611,8 @@ struct devlink_ops {
void *devlink_priv(struct devlink *devlink);
struct devlink *priv_to_devlink(void *priv);
struct device *devlink_to_dev(const struct devlink *devlink);
+const char *devlink_bus_name(const struct devlink *devlink);
+const char *devlink_dev_name(const struct devlink *devlink);
/* Devlink instance explicit locking */
void devl_lock(struct devlink *devlink);
diff --git a/include/trace/events/devlink.h b/include/trace/events/devlink.h
index f241e204fe6b..32304ce9ad15 100644
--- a/include/trace/events/devlink.h
+++ b/include/trace/events/devlink.h
@@ -21,8 +21,8 @@ TRACE_EVENT(devlink_hwmsg,
TP_ARGS(devlink, incoming, type, buf, len),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__field(bool, incoming)
__field(unsigned long, type)
@@ -55,8 +55,8 @@ TRACE_EVENT(devlink_hwerr,
TP_ARGS(devlink, err, msg),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__field(int, err)
__string(msg, msg)
@@ -85,8 +85,8 @@ TRACE_EVENT(devlink_health_report,
TP_ARGS(devlink, reporter_name, msg),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__string(reporter_name, reporter_name)
__string(msg, msg)
@@ -116,8 +116,8 @@ TRACE_EVENT(devlink_health_recover_aborted,
TP_ARGS(devlink, reporter_name, health_state, time_since_last_recover),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__string(reporter_name, reporter_name)
__field(bool, health_state)
@@ -150,8 +150,8 @@ TRACE_EVENT(devlink_health_reporter_state_update,
TP_ARGS(devlink, reporter_name, new_state),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__string(reporter_name, reporter_name)
__field(u8, new_state)
@@ -181,8 +181,8 @@ TRACE_EVENT(devlink_trap_report,
TP_ARGS(devlink, skb, metadata),
TP_STRUCT__entry(
- __string(bus_name, devlink_to_dev(devlink)->bus->name)
- __string(dev_name, dev_name(devlink_to_dev(devlink)))
+ __string(bus_name, devlink_bus_name(devlink))
+ __string(dev_name, devlink_dev_name(devlink))
__string(driver_name, devlink_to_dev(devlink)->driver->name)
__string(trap_name, metadata->trap_name)
__string(trap_group_name, metadata->trap_group_name)
diff --git a/net/devlink/core.c b/net/devlink/core.c
index d8e509a669bf..63709c132a7c 100644
--- a/net/devlink/core.c
+++ b/net/devlink/core.c
@@ -248,6 +248,18 @@ struct device *devlink_to_dev(const struct devlink *devlink)
}
EXPORT_SYMBOL_GPL(devlink_to_dev);
+const char *devlink_bus_name(const struct devlink *devlink)
+{
+ return devlink->dev->bus->name;
+}
+EXPORT_SYMBOL_GPL(devlink_bus_name);
+
+const char *devlink_dev_name(const struct devlink *devlink)
+{
+ return dev_name(devlink->dev);
+}
+EXPORT_SYMBOL_GPL(devlink_dev_name);
+
struct net *devlink_net(const struct devlink *devlink)
{
return read_pnet(&devlink->_net);
diff --git a/net/devlink/devl_internal.h b/net/devlink/devl_internal.h
index 31fa98af418e..1b770de0313e 100644
--- a/net/devlink/devl_internal.h
+++ b/net/devlink/devl_internal.h
@@ -174,9 +174,9 @@ devlink_dump_state(struct netlink_callback *cb)
static inline int
devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
{
- if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
+ if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink_bus_name(devlink)))
return -EMSGSIZE;
- if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
+ if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, devlink_dev_name(devlink)))
return -EMSGSIZE;
if (nla_put_uint(msg, DEVLINK_ATTR_INDEX, devlink->index))
return -EMSGSIZE;
@@ -211,8 +211,8 @@ static inline void devlink_nl_obj_desc_init(struct devlink_obj_desc *desc,
struct devlink *devlink)
{
memset(desc, 0, sizeof(*desc));
- desc->bus_name = devlink->dev->bus->name;
- desc->dev_name = dev_name(devlink->dev);
+ desc->bus_name = devlink_bus_name(devlink);
+ desc->dev_name = devlink_dev_name(devlink);
}
static inline void devlink_nl_obj_desc_port_set(struct devlink_obj_desc *desc,
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 593605c1b1ef..56817b85a3f9 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -193,8 +193,8 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
devlinks_xa_for_each_registered_get(net, index, devlink) {
- if (strcmp(devlink->dev->bus->name, busname) == 0 &&
- strcmp(dev_name(devlink->dev), devname) == 0) {
+ if (strcmp(devlink_bus_name(devlink), busname) == 0 &&
+ strcmp(devlink_dev_name(devlink), devname) == 0) {
devl_dev_lock(devlink, dev_lock);
if (devl_is_registered(devlink))
return devlink;
diff --git a/net/devlink/port.c b/net/devlink/port.c
index 1ff609571ea4..fa3e1597711b 100644
--- a/net/devlink/port.c
+++ b/net/devlink/port.c
@@ -220,8 +220,8 @@ size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
{
struct devlink *devlink = devlink_port->devlink;
- return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
- + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
+ return nla_total_size(strlen(devlink_bus_name(devlink)) + 1) /* DEVLINK_ATTR_BUS_NAME */
+ + nla_total_size(strlen(devlink_dev_name(devlink)) + 1) /* DEVLINK_ATTR_DEV_NAME */
+ nla_total_size(8) /* DEVLINK_ATTR_INDEX */
+ nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
}
--
2.51.1
^ permalink raw reply related
* [PATCH net-next v3 03/13] devlink: avoid extra iterations when found devlink is not registered
From: Jiri Pirko @ 2026-03-04 16:00 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: <20260304160022.6114-1-jiri@resnulli.us>
From: Jiri Pirko <jiri@nvidia.com>
Since the one found is not registered, very unlikely another one with
the same bus_name/dev_name is going to be found. Stop right away and
prepare common "found" path for the follow-up patch.
Signed-off-by: Jiri Pirko <jiri@nvidia.com>
---
net/devlink/netlink.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/net/devlink/netlink.c b/net/devlink/netlink.c
index 56817b85a3f9..7b205f677b7a 100644
--- a/net/devlink/netlink.c
+++ b/net/devlink/netlink.c
@@ -194,16 +194,20 @@ devlink_get_from_attrs_lock(struct net *net, struct nlattr **attrs,
devlinks_xa_for_each_registered_get(net, index, devlink) {
if (strcmp(devlink_bus_name(devlink), busname) == 0 &&
- strcmp(devlink_dev_name(devlink), devname) == 0) {
- devl_dev_lock(devlink, dev_lock);
- if (devl_is_registered(devlink))
- return devlink;
- devl_dev_unlock(devlink, dev_lock);
- }
+ strcmp(devlink_dev_name(devlink), devname) == 0)
+ goto found;
devlink_put(devlink);
}
return ERR_PTR(-ENODEV);
+
+found:
+ devl_dev_lock(devlink, dev_lock);
+ if (devl_is_registered(devlink))
+ return devlink;
+ devl_dev_unlock(devlink, dev_lock);
+ devlink_put(devlink);
+ return ERR_PTR(-ENODEV);
}
static int __devlink_nl_pre_doit(struct sk_buff *skb, struct genl_info *info,
--
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