* Re: [PATCH 1/6] lib: include crc32.h conditionally on CONFIG_CRC32
From: Arnd Bergmann @ 2026-05-04 19:05 UTC (permalink / raw)
To: Yury Norov
Cc: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
Yury Norov, Rasmus Villemoes, Andrew Lunn, David S . Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Andrew Morton,
Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
John Fastabend, Stanislav Fomichev, Ruan Jinjie, linux-kernel,
linux-riscv, Linux-Arch, Netdev, bpf, Nathan Chancellor
In-Reply-To: <afjmIK4mlCWeywuS@yury>
On Mon, May 4, 2026, at 20:32, Yury Norov wrote:
> On Mon, May 04, 2026 at 07:18:49PM +0200, Arnd Bergmann wrote:
>> On Mon, May 4, 2026, at 18:46, Yury Norov wrote:
>> > Never heard about such a thing like "optional interface". And git grep
>> > tends to second that...
>>
>> I meant any library interface that can be turned on or off
>
> So? If I disable CRC32, can I use the either_crc()? In case of that
> networking header, the answer is yes. In some other piece of code
> the answer is no. Is that correct?
Since it's a macro defiend in terms of both bitref32 and
crc32_le, you can only call it from dead code, such as an
inline function that is not itself used, or from inside of
a block that is protected with IS_ENABLED(CONFIG_CRC32) etc.
>> >>
>> >> Don't add #ifdef blocks around headers. If the header cannot
>> >> be included without side-effects, change the linux/crc32.h
>> >> file instead of its users.
>> >
>> > linux/acpi.h does that like many othes. What exactly is wrong with
>> > protecting headers inclusion?
>>
>> There is no "protecting" here, you just add complexity to the
>> build when headers are sometimes included indirectly and but
>> other times are not, depending on kernel configuration.
>
> Sorry, don't understand... I use the 'protecting' term with the meaning:
> the functionality that is explicitly disabled should be never used.
> Otherwise, what for we disable it?
Arguably, both configuration symbols are at the point of not actually
saving enough object code size to actually be worth the Kconfig
dependencies.
As long as we have CONFIG_CRC32 and CONFIG_BITREVERSE, the
point of having the Kconfig symbols is to let drivers request
the inclusion of the library helpers.
>> It's unlikely to cause problems for the crc32.h header, but
>> the acpi example definitely risks running into circular
>> inclusions when you end up with some other header that depending
>> on configuration ends up including linux/acpi.h while also
>> bring included indirectly from that one.
>>
>> >> It looks like the problem is the check for CONFIG_GENERIC_BITREVERSE
>> >> in include/asm-generic/bitops/__bitrev.h, which ends up
>> >> hinding the generic___bitrev32() helper without need.
>> >>
>> >> Simply removing the #ifdef there should avoid the build failure.
>> >
>> > OK, it seems like this is what I don't understand.
>> >
>> > We've got an optional feature, like CRC32, which is enabled by
>> > CONFIG_CRC32. The most conservative way is to declare everything
>> > CRC32-related in the corresponding header, and then protect the header
>> > with IS_ENABLED(CONFIG_CRC32).
>> >
>> > I understand that from practical perspective, we can declare some simple
>> > macros, like header size, unprotected. But what we've got now is a sort
>> > of mess: all CRC32-related functions are declared unprotected, and
>> > generic headers are good to use them. Compiler is happy while those
>> > functions are actually unused. Next, CRC32 depends on BITREVERSE, which
>> > is again unprotected, and it may optionally have an arch implementation.
>> >
>> > So if arch bitrev() is implemented, you can use part of bitreverse and
>> > crc32 APIs despite that they are explicitly disabled - just because they
>> > are implemented as macros in unprotected headers. And you cannot use some
>> > others - because they are implemented differently, as a real functions.
>>
>> I think you trying to solve a non-problem here.
>
> This was reported by Nathan for tinyconfig. At least x86 and s390 are
> affected.
>
> https://lore.kernel.org/all/20260429202922.GA3575295@ax162/
>
> Is tinyconfig important?
Nathan reported a build regression caused by a small mistake
in 596a9ea9015b ("bitops: Define generic __bitrev8/16/32 for reuse"),
which is of course needs to be fixed.
What I meant is that there is no reason to not use the obvious
fix and do
--- a/include/asm-generic/bitops/__bitrev.h
+++ b/include/asm-generic/bitops/__bitrev.h
@@ -2,7 +2,6 @@
#ifndef _ASM_GENERIC_BITOPS___BITREV_H_
#define _ASM_GENERIC_BITOPS___BITREV_H_
-#ifdef CONFIG_GENERIC_BITREVERSE
#include <asm/types.h>
extern u8 const byte_rev_table[256];
@@ -20,6 +19,5 @@ static __always_inline __attribute_const__ u32 generic___bitrev32(u32 x)
{
return (generic___bitrev16(x & 0xffff) << 16) | generic___bitrev16(x >> 16);
}
-#endif /* CONFIG_GENERIC_BITREVERSE */
#endif /* _ASM_GENERIC_BITOPS___BITREV_H_ */
> Right now half CRC32 is available if CONFIG_CRC32 is on, and half is
> not available. The bitreverse is the same. If HAVE_ARCH_BITREVERSE is
> enabled, one can use the API, bypassing the BITREVERSE. This doesn't
> sound right to me long-term.
>
> Whatever this ends up, let's figure out a consistent solution please?
I really don't think we need any sort of solution here, aside from
the trivial regression fix that returns it to the previous working
state.
Arnd
^ permalink raw reply
* Re: [PATCH iproute2-next] tc: qdisc: provide tcm_handle and tcm_parent to kernel dump requests
From: Jamal Hadi Salim @ 2026-05-04 19:10 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Ahern, Stephen Hemminger, David S . Miller, Jakub Kicinski,
Paolo Abeni, netdev, eric.dumazet
In-Reply-To: <20260503115138.2467123-1-edumazet@google.com>
On Sun, May 3, 2026 at 7:51 AM Eric Dumazet <edumazet@google.com> wrote:
>
> linux-7.2 can filter "tc qdisc show ..." on tcm_handle / tcm_parent and
> reduce dump costs.
>
> Old kernels ignore these values.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
> ---
> tc/tc_qdisc.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
> index b3c395b65c2f6b47abbcb6aa37b7dc1f080032e8..7c3e7cb36b4830bca9f2785a58b38d319ec4b563 100644
> --- a/tc/tc_qdisc.c
> +++ b/tc/tc_qdisc.c
> @@ -408,6 +408,9 @@ static int tc_qdisc_list(int argc, char **argv)
> argc--; argv++;
> }
>
> + /* Recent kernels (7.2+) can filter on tcm_parent/tcm_handle */
> + req.t.tcm_parent = filter_parent;
> + req.t.tcm_handle = filter_handle;
>
> if (d[0]) {
> req.t.tcm_ifindex = ll_name_to_index(d);
> --
> 2.54.0.545.g6539524ca2-goog
>
^ permalink raw reply
* Re: [PATCH net-next] net/sched: speedup tc_dump_qdisc() when tcm_handle is provided
From: Jamal Hadi Salim @ 2026-05-04 19:13 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jiri Pirko, netdev, eric.dumazet
In-Reply-To: <20260503114515.2460477-1-edumazet@google.com>
On Sun, May 3, 2026 at 7:45 AM Eric Dumazet <edumazet@google.com> wrote:
>
> "tc qdisc show ... handle xxx" filtering can be done by the kernel.
>
> A followup patch can do the same for tcm_parent.
>
> iproute2/tc needs a small companion patch.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
If you ever redo this for whatever reason, showing the dump of before
and after will be good documentation.
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
> ---
> net/sched/sch_api.c | 27 +++++++++++++++++----------
> 1 file changed, 17 insertions(+), 10 deletions(-)
>
> diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
> index dd0edc9bd4610ec865fc97a81f801a7da020667b..6f7847c5536f16e6754954f0a606581e17257361 100644
> --- a/net/sched/sch_api.c
> +++ b/net/sched/sch_api.c
> @@ -979,13 +979,17 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
> return -EMSGSIZE;
> }
>
> -static bool tc_qdisc_dump_ignore(struct Qdisc *q, bool dump_invisible)
> +static bool tc_qdisc_dump_ignore(struct Qdisc *q, bool dump_invisible,
> + const struct tcmsg *tcm)
> {
> if (q->flags & TCQ_F_BUILTIN)
> return true;
> if ((q->flags & TCQ_F_INVISIBLE) && !dump_invisible)
> return true;
> -
> + if (tcm) {
> + if (tcm->tcm_handle && tcm->tcm_handle != q->handle)
> + return true;
> + }
> return false;
> }
>
> @@ -1000,7 +1004,7 @@ static int qdisc_get_notify(struct net *net, struct sk_buff *oskb,
> if (!skb)
> return -ENOBUFS;
>
> - if (!tc_qdisc_dump_ignore(q, false)) {
> + if (!tc_qdisc_dump_ignore(q, false, NULL)) {
> if (tc_fill_qdisc(skb, q, clid, portid, n->nlmsg_seq, 0,
> RTM_NEWQDISC, extack) < 0)
> goto err_out;
> @@ -1030,12 +1034,12 @@ static int qdisc_notify(struct net *net, struct sk_buff *oskb,
> if (!skb)
> return -ENOBUFS;
>
> - if (old && !tc_qdisc_dump_ignore(old, false)) {
> + if (old && !tc_qdisc_dump_ignore(old, false, NULL)) {
> if (tc_fill_qdisc(skb, old, clid, portid, n->nlmsg_seq,
> 0, RTM_DELQDISC, extack) < 0)
> goto err_out;
> }
> - if (new && !tc_qdisc_dump_ignore(new, false)) {
> + if (new && !tc_qdisc_dump_ignore(new, false, NULL)) {
> if (tc_fill_qdisc(skb, new, clid, portid, n->nlmsg_seq,
> old ? NLM_F_REPLACE : 0, RTM_NEWQDISC, extack) < 0)
> goto err_out;
> @@ -1825,21 +1829,24 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
> int *q_idx_p, int s_q_idx, bool recur,
> bool dump_invisible)
> {
> + const struct nlmsghdr *nlh = cb->nlh;
> int ret = 0, q_idx = *q_idx_p;
> + const struct tcmsg *tcm;
> struct Qdisc *q;
> int b;
>
> if (!root)
> return 0;
>
> + tcm = nlmsg_data(nlh);
> q = root;
> if (q_idx < s_q_idx) {
> q_idx++;
> } else {
> - if (!tc_qdisc_dump_ignore(q, dump_invisible))
> + if (!tc_qdisc_dump_ignore(q, dump_invisible, tcm))
> ret = tc_fill_qdisc(skb, q, q->parent,
> NETLINK_CB(cb->skb).portid,
> - cb->nlh->nlmsg_seq, NLM_F_MULTI,
> + nlh->nlmsg_seq, NLM_F_MULTI,
> RTM_NEWQDISC, NULL);
> if (ret < 0)
> goto out;
> @@ -1860,10 +1867,10 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
> q_idx++;
> continue;
> }
> - if (!tc_qdisc_dump_ignore(q, dump_invisible))
> + if (!tc_qdisc_dump_ignore(q, dump_invisible, tcm))
> ret = tc_fill_qdisc(skb, q, q->parent,
> NETLINK_CB(cb->skb).portid,
> - cb->nlh->nlmsg_seq, NLM_F_MULTI,
> + nlh->nlmsg_seq, NLM_F_MULTI,
> RTM_NEWQDISC, NULL);
> if (ret < 0)
> goto out;
> @@ -2341,7 +2348,7 @@ static int tc_dump_tclass_qdisc(struct Qdisc *q, struct sk_buff *skb,
> {
> struct qdisc_dump_args arg;
>
> - if (tc_qdisc_dump_ignore(q, false) ||
> + if (tc_qdisc_dump_ignore(q, false, NULL) ||
> *t_p < s_t || !q->ops->cl_ops ||
> (tcm->tcm_parent &&
> TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
> --
> 2.54.0.545.g6539524ca2-goog
>
^ permalink raw reply
* Re: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010 and TS2500 MAC-PHY
From: Andrew Lunn @ 2026-05-04 19:15 UTC (permalink / raw)
To: Selvamani Rajagopal
Cc: Piergiorgio Beruto, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CY8PR02MB92499BF412C31A04BADE609183312@CY8PR02MB9249.namprd02.prod.outlook.com>
> > So you seem to be compliant with the standard. I've not seen anything
> > use MDIO_MMD_POWER_UNIT so not having that should not be an
> > issue. MDIO_MMD_AN is used by a number of PHYs, but i assume yours
> > does not.
> >
> > 802.3 C45 says that if a register does not exist, it should read
> > 0. What would happen if a read was made to
> > OA_TC6_PHY_C45_AUTO_NEG_MMS5, rather than returning EOPNOTSUPP?
> >
> > Table 6 says nothing about MMD 30, which you map to 12. 10-15 are
> > defined as vendor specific, so that is O.K.
> >
> > But can we simply this. Add something like
> >
> > void oa_tc6_set_vend1_mms(struct oa_tc6 *tc6, int mms)
> > {
> > tc6->vend1_mms = mms;
> > }
> >
> > and make oa_tc6_get_phy_c45_mms() look at its value?
>
> Sure. I can do that.
>
> Since we don't support PCS, and POWER_UNIT, may I suggest alternative solution?
I would prefer to rely on 802.3 defined C45 behaviour. A read to a
register which does not exists gives 0. That is what PHYs and phylib
expect.
You failed to answer my question about this. What happens with your
device if you access C45 registers which don't exist?
> This gives flexibility to vendors as mostly likely, all the vendors
> may not share the same set of MDIO_MMD_XXX support.
Well, all vendors should support what is defined in the standard. It
is only MDIO_MMD_VEND1 which is left undefined, and different vendors
could put that at different MMS in the 10-15 range, but i think the
rest is well defined.
Andrew
^ permalink raw reply
* RE: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010 and TS2500 MAC-PHY
From: Selvamani Rajagopal @ 2026-05-04 19:17 UTC (permalink / raw)
To: Andrew Lunn
Cc: Piergiorgio Beruto, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <5f07822d-6ea9-4beb-a222-58a94e4801d6@lunn.ch>
> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Monday, May 4, 2026 12:15 PM
> To: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
> Cc: Piergiorgio Beruto <Pier.Beruto@onsemi.com>; andrew+netdev@lunn.ch;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org; pabeni@redhat.com;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010
> and TS2500 MAC-PHY
>
>
> This Message Is From an External Sender
> This message came from outside your organization.
>
> > > So you seem to be compliant with the standard. I've not seen anything
> > > use MDIO_MMD_POWER_UNIT so not having that should not be an
> > > issue. MDIO_MMD_AN is used by a number of PHYs, but i assume yours
> > > does not.
> > >
> > > 802.3 C45 says that if a register does not exist, it should read
> > > 0. What would happen if a read was made to
> > > OA_TC6_PHY_C45_AUTO_NEG_MMS5, rather than returning EOPNOTSUPP?
> > >
> > > Table 6 says nothing about MMD 30, which you map to 12. 10-15 are
> > > defined as vendor specific, so that is O.K.
> > >
> > > But can we simply this. Add something like
> > >
> > > void oa_tc6_set_vend1_mms(struct oa_tc6 *tc6, int mms)
> > > {
> > > tc6->vend1_mms = mms;
> > > }
> > >
> > > and make oa_tc6_get_phy_c45_mms() look at its value?
> >
> > Sure. I can do that.
> >
> > Since we don't support PCS, and POWER_UNIT, may I suggest alternative solution?
>
> I would prefer to rely on 802.3 defined C45 behaviour. A read to a
> register which does not exists gives 0. That is what PHYs and phylib
> expect.
>
> You failed to answer my question about this. What happens with your
> device if you access C45 registers which don't exist?
Sorry. Waiting for an answer from hardware designer.
>
> > This gives flexibility to vendors as mostly likely, all the vendors
> > may not share the same set of MDIO_MMD_XXX support.
>
> Well, all vendors should support what is defined in the standard. It
> is only MDIO_MMD_VEND1 which is left undefined, and different vendors
> could put that at different MMS in the 10-15 range, but i think the
> rest is well defined.
>
> Andrew
^ permalink raw reply
* Re: [PATCH net-next] net/sched: speedup tc_dump_qdisc() when tcm_handle is provided
From: Eric Dumazet @ 2026-05-04 19:20 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jiri Pirko, netdev, eric.dumazet
In-Reply-To: <CAM0EoMkH-7jjV3Z=74yF4ZKbPsw5JCJo1RRjnt3fEVvzgNbRSg@mail.gmail.com>
On Mon, May 4, 2026 at 12:13 PM Jamal Hadi Salim <jhs@mojatatu.com> wrote:
>
> On Sun, May 3, 2026 at 7:45 AM Eric Dumazet <edumazet@google.com> wrote:
> >
> > "tc qdisc show ... handle xxx" filtering can be done by the kernel.
> >
> > A followup patch can do the same for tcm_parent.
> >
> > iproute2/tc needs a small companion patch.
> >
> > Signed-off-by: Eric Dumazet <edumazet@google.com>
>
> If you ever redo this for whatever reason, showing the dump of before
> and after will be good documentation.
There is no difference in tc output.
One can use strace and look at all the recvmsg() values, but they are
quite verbose :/
^ permalink raw reply
* Re: [PATCH v2 net] net/sched: sch_fq_codel: annotate data-races from fq_codel_dump_class_stats()
From: Jamal Hadi Salim @ 2026-05-04 19:20 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jiri Pirko, netdev, eric.dumazet
In-Reply-To: <20260504163842.1162001-1-edumazet@google.com>
On Mon, May 4, 2026 at 12:38 PM Eric Dumazet <edumazet@google.com> wrote:
>
> fq_codel_dump_class_stats() acquires qdisc spinlock only when requested
> to follow flow->head chain.
>
> As we did in sch_cake recently, add the missing READ_ONCE()/WRITE_ONCE()
> annotations.
>
> Fixes: edb09eb17ed8 ("net: sched: do not acquire qdisc spinlock in qdisc/class stats dump")
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
> ---
> v2: added WRITE_ONCE(flow->cvars.count, flow->cvars.count + i);
>
> net/sched/sch_fq_codel.c | 39 ++++++++++++++++++++-------------------
> 1 file changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
> index 0664b2f2d6f28041e5250a44fc92311116ae0cf1..24db54684e8a5997b075e0f4072f49779ae45abb 100644
> --- a/net/sched/sch_fq_codel.c
> +++ b/net/sched/sch_fq_codel.c
> @@ -117,7 +117,7 @@ static inline struct sk_buff *dequeue_head(struct fq_codel_flow *flow)
> {
> struct sk_buff *skb = flow->head;
>
> - flow->head = skb->next;
> + WRITE_ONCE(flow->head, skb->next);
> skb_mark_not_on_list(skb);
> return skb;
> }
> @@ -127,7 +127,7 @@ static inline void flow_queue_add(struct fq_codel_flow *flow,
> struct sk_buff *skb)
> {
> if (flow->head == NULL)
> - flow->head = skb;
> + WRITE_ONCE(flow->head, skb);
> else
> flow->tail->next = skb;
> flow->tail = skb;
> @@ -173,8 +173,8 @@ static unsigned int fq_codel_drop(struct Qdisc *sch, unsigned int max_packets,
> } while (++i < max_packets && len < threshold);
>
> /* Tell codel to increase its signal strength also */
> - flow->cvars.count += i;
> - q->backlogs[idx] -= len;
> + WRITE_ONCE(flow->cvars.count, flow->cvars.count + i);
> + WRITE_ONCE(q->backlogs[idx], q->backlogs[idx] - len);
> q->memory_usage -= mem;
> sch->qstats.drops += i;
> sch->qstats.backlog -= len;
> @@ -204,13 +204,13 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch,
> codel_set_enqueue_time(skb);
> flow = &q->flows[idx];
> flow_queue_add(flow, skb);
> - q->backlogs[idx] += qdisc_pkt_len(skb);
> + WRITE_ONCE(q->backlogs[idx], q->backlogs[idx] + qdisc_pkt_len(skb));
> qdisc_qstats_backlog_inc(sch, skb);
>
> if (list_empty(&flow->flowchain)) {
> list_add_tail(&flow->flowchain, &q->new_flows);
> q->new_flow_count++;
> - flow->deficit = q->quantum;
> + WRITE_ONCE(flow->deficit, q->quantum);
> }
> get_codel_cb(skb)->mem_usage = skb->truesize;
> q->memory_usage += get_codel_cb(skb)->mem_usage;
> @@ -263,7 +263,8 @@ static struct sk_buff *dequeue_func(struct codel_vars *vars, void *ctx)
> flow = container_of(vars, struct fq_codel_flow, cvars);
> if (flow->head) {
> skb = dequeue_head(flow);
> - q->backlogs[flow - q->flows] -= qdisc_pkt_len(skb);
> + WRITE_ONCE(q->backlogs[flow - q->flows],
> + q->backlogs[flow - q->flows] - qdisc_pkt_len(skb));
> q->memory_usage -= get_codel_cb(skb)->mem_usage;
> sch->q.qlen--;
> sch->qstats.backlog -= qdisc_pkt_len(skb);
> @@ -296,7 +297,7 @@ static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
> flow = list_first_entry(head, struct fq_codel_flow, flowchain);
>
> if (flow->deficit <= 0) {
> - flow->deficit += q->quantum;
> + WRITE_ONCE(flow->deficit, flow->deficit + q->quantum);
> list_move_tail(&flow->flowchain, &q->old_flows);
> goto begin;
> }
> @@ -314,7 +315,7 @@ static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
> goto begin;
> }
> qdisc_bstats_update(sch, skb);
> - flow->deficit -= qdisc_pkt_len(skb);
> + WRITE_ONCE(flow->deficit, flow->deficit - qdisc_pkt_len(skb));
>
> if (q->cstats.drop_count) {
> qdisc_tree_reduce_backlog(sch, q->cstats.drop_count,
> @@ -328,7 +329,7 @@ static struct sk_buff *fq_codel_dequeue(struct Qdisc *sch)
> static void fq_codel_flow_purge(struct fq_codel_flow *flow)
> {
> rtnl_kfree_skbs(flow->head, flow->tail);
> - flow->head = NULL;
> + WRITE_ONCE(flow->head, NULL);
> }
>
> static void fq_codel_reset(struct Qdisc *sch)
> @@ -656,21 +657,21 @@ static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl,
>
> memset(&xstats, 0, sizeof(xstats));
> xstats.type = TCA_FQ_CODEL_XSTATS_CLASS;
> - xstats.class_stats.deficit = flow->deficit;
> + xstats.class_stats.deficit = READ_ONCE(flow->deficit);
> xstats.class_stats.ldelay =
> - codel_time_to_us(flow->cvars.ldelay);
> - xstats.class_stats.count = flow->cvars.count;
> - xstats.class_stats.lastcount = flow->cvars.lastcount;
> - xstats.class_stats.dropping = flow->cvars.dropping;
> - if (flow->cvars.dropping) {
> - codel_tdiff_t delta = flow->cvars.drop_next -
> + codel_time_to_us(READ_ONCE(flow->cvars.ldelay));
> + xstats.class_stats.count = READ_ONCE(flow->cvars.count);
> + xstats.class_stats.lastcount = READ_ONCE(flow->cvars.lastcount);
> + xstats.class_stats.dropping = READ_ONCE(flow->cvars.dropping);
> + if (xstats.class_stats.dropping) {
> + codel_tdiff_t delta = READ_ONCE(flow->cvars.drop_next) -
> codel_get_time();
>
> xstats.class_stats.drop_next = (delta >= 0) ?
> codel_time_to_us(delta) :
> -codel_time_to_us(-delta);
> }
> - if (flow->head) {
> + if (READ_ONCE(flow->head)) {
> sch_tree_lock(sch);
> skb = flow->head;
> while (skb) {
> @@ -679,7 +680,7 @@ static int fq_codel_dump_class_stats(struct Qdisc *sch, unsigned long cl,
> }
> sch_tree_unlock(sch);
> }
> - qs.backlog = q->backlogs[idx];
> + qs.backlog = READ_ONCE(q->backlogs[idx]);
> qs.drops = 0;
> }
> if (gnet_stats_copy_queue(d, NULL, &qs, qs.qlen) < 0)
> --
> 2.54.0.545.g6539524ca2-goog
>
^ permalink raw reply
* RE: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010 and TS2500 MAC-PHY
From: Selvamani Rajagopal @ 2026-05-04 19:21 UTC (permalink / raw)
To: Andrew Lunn
Cc: Piergiorgio Beruto, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CY8PR02MB9249082A82E8E2C503D6773683312@CY8PR02MB9249.namprd02.prod.outlook.com>
> -----Original Message-----
> From: Selvamani Rajagopal
> Sent: Monday, May 4, 2026 12:18 PM
> To: 'Andrew Lunn' <andrew@lunn.ch>
> Cc: Piergiorgio Beruto <Pier.Beruto@onsemi.com>; andrew+netdev@lunn.ch;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org; pabeni@redhat.com;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: RE: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010
> and TS2500 MAC-PHY
>
>
>
> > -----Original Message-----
> > From: Andrew Lunn <andrew@lunn.ch>
> > Sent: Monday, May 4, 2026 12:15 PM
> > To: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
> > Cc: Piergiorgio Beruto <Pier.Beruto@onsemi.com>; andrew+netdev@lunn.ch;
> > davem@davemloft.net; edumazet@google.com; kuba@kernel.org;
> pabeni@redhat.com;
> > netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> > Subject: Re: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010
> > and TS2500 MAC-PHY
> >
> >
> > This Message Is From an External Sender
> > This message came from outside your organization.
> >
> > > > So you seem to be compliant with the standard. I've not seen anything
> > > > use MDIO_MMD_POWER_UNIT so not having that should not be an
> > > > issue. MDIO_MMD_AN is used by a number of PHYs, but i assume yours
> > > > does not.
> > > >
> > > > 802.3 C45 says that if a register does not exist, it should read
> > > > 0. What would happen if a read was made to
> > > > OA_TC6_PHY_C45_AUTO_NEG_MMS5, rather than returning EOPNOTSUPP?
> > > >
> > > > Table 6 says nothing about MMD 30, which you map to 12. 10-15 are
> > > > defined as vendor specific, so that is O.K.
> > > >
> > > > But can we simply this. Add something like
> > > >
> > > > void oa_tc6_set_vend1_mms(struct oa_tc6 *tc6, int mms)
> > > > {
> > > > tc6->vend1_mms = mms;
> > > > }
> > > >
> > > > and make oa_tc6_get_phy_c45_mms() look at its value?
> > >
> > > Sure. I can do that.
> > >
> > > Since we don't support PCS, and POWER_UNIT, may I suggest alternative solution?
> >
> > I would prefer to rely on 802.3 defined C45 behaviour. A read to a
> > register which does not exists gives 0. That is what PHYs and phylib
> > expect.
> >
> > You failed to answer my question about this. What happens with your
> > device if you access C45 registers which don't exist?
>
> Sorry. Waiting for an answer from hardware designer.
It is confirmed that we will return 0 if unsupported registers are read.
>
> >
> > > This gives flexibility to vendors as mostly likely, all the vendors
> > > may not share the same set of MDIO_MMD_XXX support.
> >
> > Well, all vendors should support what is defined in the standard. It
> > is only MDIO_MMD_VEND1 which is left undefined, and different vendors
> > could put that at different MMS in the 10-15 range, but i think the
> > rest is well defined.
> >
> > Andrew
^ permalink raw reply
* [RFC PATCH 0/1] Proposal for in-band firmware update over PLDM-MCTP
From: Badal Nilawar @ 2026-05-04 19:34 UTC (permalink / raw)
To: dri-devel, intel-xe, netdev, linux-kernel
Cc: badal.nilawar, rodrigo.vivi, wojciech.drewek, michael.brooks,
heikki.krogerus, michael.j.ruhl, thomas.hellstrom,
michal.winiarski, anshuman.gupta, jacob.e.keller,
maarten.lankhorst, matthew.brost, anthony.l.nguyen,
przemyslaw.kitszel, mika.westerberg, andriy.shevchenko,
singaravelan.nallasellan, kelvin.gardiner, jk, matt,
andrew+netdev, davem, edumazet, kuba, pabeni, james.ausmus
Problem statement:
The CRI platform includes a dedicated I2C controller for in-band access to AMC.
AMC firmware updates leverage PLDM over MCTP, using the I2C controller as the
physical transport, enabled by the Linux kernel's MCTP-I2C driver
(drivers/net/mctp/mctp-i2c.c), which manages MCTP framing and delivery over the
I2C bus.
CRI Inband firmware update flow
+-----------------------------------+
| User Space |
| (PLDM requester/responder) |
| PLDM client via AF_MCTP socket |
+-----------------------------------+
|
+-----------------------------------+
| net/mctp core |
| (routing, EID resolution, |
| MCTP framing) |
+-----------------------------------+
|
+-----------------------------------+
| mctp-i2c.c |
| MCTP transport over i2c |
+-----------------------------------+
|
+-----------------------------------+
| AMC Firmware |
| (PLDM requester/responder) |
| MCTP Decode -> PLDM Processing |
+-----------------------------------+
Future GPU platforms may not include a dedicated I2C controller for MCTP
access; however, the requirement to support PLDM over MCTP persists. To
address this, a vendor-specific mailbox-based transport is proposed to
carry MCTP messages between the host and the GPU/AMC.
Solution:
The proposed approach involves implementing an MCTP transport layer with
binding type MCTP_PHYS_BINDING_VENDOR (0xFF) and incorporating it either
into the drivers/net/mctp/ directory or the drivers/gpu/drm/xe subsystem.
The latter is particularly fitting, as Xe is the exclusive consumer of
this functionality.
Option 1: MCTP Transport as Part of drivers/gpu/drm/xe Subsystem
Under this design, the Xe KMD takes sole ownership of the MCTP mailbox
transport layer. The implementation is introduced as a new source file,
xe-mctp-mailbox.c, placed within the drivers/gpu/drm/xe/ driver tree.
Although xe-mctp-mailbox.c resides within the Xe subsystem, it does not
operate in isolation from the broader networking stack. It integrates
with the standard Linux MCTP stack by registering an MCTP net device
via mctp_register_netdev(), allowing the net/mctp core to manage
routing, EID resolution, and MCTP framing in the usual way.
This means Xe retains direct ownership of the mailbox MMIO interface
(status, and data registers via BAR), while still participating as
transport in the MCTP network subsystem.
+--------------------------------------------------+
| User Space |
| (PLDM Requester / Responder) |
| PLDM Client via AF_MCTP Socket |
+--------------------------------------------------+
|
AF_MCTP API
|
+--------------------------------------------------+
| net/mctp Core |
| (Routing, EID Resolution, MCTP Framing) |
+--------------------------------------------------+
| ^
| mctp_register_netdev() | netdev / mctp_dev ops
| (called by Xe KMD) |
+--------------------------------------------------+
| [NEW] drivers/gpu/drm/xe/xe-mctp-mailbox.c |
| |
| Owned by : Xe KMD (drivers/gpu/drm/xe/) |
| - Registers directly as MCTP net device |
| - Implements MCTP transport over Mailbox MMIO |
+--------------------------------------------------+
|
Direct MMIO access (BAR registers)
|
+--------------------------------------------------+
| Intel Mailbox MMIO Registers |
| (Doorbell, Status, Data Registers via BAR) |
+--------------------------------------------------+
|
Hardware Mailbox Interface
|
+--------------------------------------------------+
| GPU / AMC Firmware |
| (PLDM Requester / Responder) |
| Mailbox Handler --> MCTP Decode |
| --> PLDM Processing |
+--------------------------------------------------+
Pros:
+ Tightly coupled with Xe and doesn't polute current generic mctp
subsystem with vendor specific mailbox solution.
Cons:
- Not a generic layer; cannot be easily reused or consumed
by other drivers or subsystems outside of Xe.
RFC Patch: "xe/xe_mctp_mailbox: Add support for MCTP transport over mailbox"
Option 2: MCTP Transport as Part of net/mctp Subsystem
The MCTP mailbox driver (intel-mctp-mailbox.c) resides under
drivers/net/mctp/ and registers itself as an Auxiliary Bus Driver on the
Linux auxiliary bus. The Xe KMD is responsible for constructing an
Auxiliary Bus Device which encapsulates the mailbox ops and registering
it against the MCTP auxiliary bus driver. This binding allows the MCTP
layer to send and receive messages through the GPU mailbox interface.
+--------------------------------------------------+
| User Space |
| (PLDM Requester / Responder) |
| PLDM Client via AF_MCTP Socket |
+--------------------------------------------------+
|
AF_MCTP API
|
+--------------------------------------------------+
| net/mctp Core |
| (Routing, EID Resolution, MCTP Framing) |
+--------------------------------------------------+
|
mctp_dev ops / netdev interface
|
+--------------------------------------------------+
| [NEW] drivers/net/mctp/intel-mctp-mailbox.c |
| |
| Registered as: Auxiliary Bus Driver |
| - Binds to Auxiliary Device exposed by Xe KMD |
| - Accesses mailbox ops shared via aux device |
+--------------------------------------------------+
| |
| auxiliary_driver_register() | auxiliary_device_register()
| |
+--------------------+ +-------------------------+
| Auxiliary Bus |<->| Auxiliary Device |
| Driver | | (created by Xe KMD) |
| (intel-mctp- | | - Contains mailbox_ops |
| mailbox.c) | | |
| drivers/net/mctp/ | | |
+--------------------+ +-------------------------+
|
mailbox_ops (send/recv via MMIO)
|
+--------------------------------------------------+
| Intel Mailbox MMIO Registers |
| (Status, Data Registers via BAR) |
+--------------------------------------------------+
|
Hardware Mailbox Interface
|
+--------------------------------------------------+
| GPU / AMC Firmware |
| (PLDM Requester / Responder) |
| Mailbox Handler --> MCTP Decode |
| --> PLDM Processing |
+--------------------------------------------------+
Pros:
+ Natively part of the MCTP stack.
+ Consistent with existing MCTP transport implementations
such as mctp-i2c and mctp-i3c. Probe occurs naturally
when the auxiliary device is created, following standard
kernel device model patterns.
Cons:
- Introduction of vendor specific cases along with current
generic mctp entries
Open for other ideas and suggestions.
Note: This RFC is prepared with AI assistance (e.g. GitHub Copilot etc).
Badal Nilawar (1):
xe/xe_mctp_mailbox: Add support for MCTP transport over mailbox
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/xe_device.c | 3 +
drivers/gpu/drm/xe/xe_device_types.h | 4 +
drivers/gpu/drm/xe/xe_mctp_mailbox.c | 186 +++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_mctp_mailbox.h | 14 ++
5 files changed, 208 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.c
create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.h
--
2.54.0
^ permalink raw reply
* [RFC PATCH 1/1] xe/xe_mctp_mailbox: Add support for MCTP transport over mailbox
From: Badal Nilawar @ 2026-05-04 19:34 UTC (permalink / raw)
To: dri-devel, intel-xe, netdev, linux-kernel
Cc: badal.nilawar, rodrigo.vivi, wojciech.drewek, michael.brooks,
heikki.krogerus, michael.j.ruhl, thomas.hellstrom,
michal.winiarski, anshuman.gupta, jacob.e.keller,
maarten.lankhorst, matthew.brost, anthony.l.nguyen,
przemyslaw.kitszel, mika.westerberg, andriy.shevchenko,
singaravelan.nallasellan, kelvin.gardiner, jk, matt,
andrew+netdev, davem, edumazet, kuba, pabeni, james.ausmus
In-Reply-To: <20260504193420.1232842-3-badal.nilawar@intel.com>
Add support for MCTP transport over the Intel vendor-specific mailbox
protocol to enable in-band firmware updates for GPU/AMC via PLDM
Signed-off-by: Badal Nilawar <badal.nilawar@intel.com>
---
drivers/gpu/drm/xe/Makefile | 1 +
drivers/gpu/drm/xe/xe_device.c | 3 +
drivers/gpu/drm/xe/xe_device_types.h | 4 +
drivers/gpu/drm/xe/xe_mctp_mailbox.c | 186 +++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_mctp_mailbox.h | 14 ++
5 files changed, 208 insertions(+)
create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.c
create mode 100644 drivers/gpu/drm/xe/xe_mctp_mailbox.h
diff --git a/drivers/gpu/drm/xe/Makefile b/drivers/gpu/drm/xe/Makefile
index 09661f079d03..d427152bc3fd 100644
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -89,6 +89,7 @@ xe-y += xe_bb.o \
xe_late_bind_fw.o \
xe_lrc.o \
xe_mem_pool.o \
+ xe_mctp_mailbox.o \
xe_migrate.o \
xe_mmio.o \
xe_mmio_gem.o \
diff --git a/drivers/gpu/drm/xe/xe_device.c b/drivers/gpu/drm/xe/xe_device.c
index 4b45b617a039..ebf456f580d1 100644
--- a/drivers/gpu/drm/xe/xe_device.c
+++ b/drivers/gpu/drm/xe/xe_device.c
@@ -49,6 +49,7 @@
#include "xe_i2c.h"
#include "xe_irq.h"
#include "xe_late_bind_fw.h"
+#include "xe_mctp_mailbox.h"
#include "xe_mmio.h"
#include "xe_module.h"
#include "xe_nvm.h"
@@ -1065,6 +1066,8 @@ int xe_device_probe(struct xe_device *xe)
for_each_gt(gt, xe, id)
xe_gt_sanitize_freq(gt);
+ xe_mctp_mailbox_init(xe);
+
xe_vsec_init(xe);
err = xe_sriov_init_late(xe);
diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
index 89437de3001a..9cfe70428c71 100644
--- a/drivers/gpu/drm/xe/xe_device_types.h
+++ b/drivers/gpu/drm/xe/xe_device_types.h
@@ -38,6 +38,7 @@
struct drm_pagemap_shrinker;
struct intel_display;
struct intel_dg_nvm_dev;
+struct xe_mctp_mailbox;
struct xe_ggtt;
struct xe_i2c;
struct xe_pat_ops;
@@ -500,6 +501,9 @@ struct xe_device {
struct llist_head async_list;
} bo_device;
+ /** @mctp_mailbox: mctp mailbox */
+ struct xe_mctp_mailbox *mctp_mailbox;
+
/** @pmu: performance monitoring unit */
struct xe_pmu pmu;
diff --git a/drivers/gpu/drm/xe/xe_mctp_mailbox.c b/drivers/gpu/drm/xe/xe_mctp_mailbox.c
new file mode 100644
index 000000000000..f1a81208a9a1
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mctp_mailbox.c
@@ -0,0 +1,186 @@
+// SPDX-License-Identifier: MIT
+/*
+ * MCTP-over-MAILBOX transport for Xe.
+ *
+ * Copyright 2026 Intel Corporation
+ */
+
+#include "xe_device_types.h"
+
+#include <linux/netdevice.h>
+#include <linux/jiffies.h>
+#include <linux/workqueue.h>
+
+#include <net/mctp.h>
+#include <net/mctpdevice.h>
+#include <net/pkt_sched.h>
+
+#include <uapi/linux/if_arp.h>
+
+#include "xe_mctp_mailbox.h"
+
+#define XE_MCTP_MAILBOX_RX_POLL_MS 100
+
+/** @mctp_mailbox: Struct for mctp over mailbox */
+struct xe_mctp_mailbox {
+ /** @mctp_mailbox.netdev: network device */
+ struct net_device *netdev;
+ /** @running: true while netdev is opened */
+ bool running;
+ /** @work: worker to handle mctp requests from firmware */
+ struct delayed_work work;
+ /** @wq: workqueue to schecdule mctp rx worker */
+ struct workqueue_struct *wq;
+};
+
+/*
+ * mailbox protocol is interrupt free so for receive path i.e. endpoint to host
+ * there is no irq available so rx handler need to be polled in worker periodically.
+ */
+static void mctp_mailbox_rx_handler(struct work_struct *work)
+{
+ struct xe_mctp_mailbox *mctp_mailbox =
+ container_of(work, struct xe_mctp_mailbox, work.work);
+ struct net_device *netdev = mctp_mailbox->netdev;
+
+ if (!netdev)
+ return;
+
+ dev_hold(netdev);
+
+ /*
+ * if (mctp_mailbox_rx_ready()) {
+ * Get data over MAILBOX
+ * Allocate skb and copy rx data to skb
+ * Queue skb to upper layer
+ * netif_rx(skb);
+ }
+ */
+ dev_put(netdev);
+
+ if (mctp_mailbox->running)
+ queue_delayed_work(mctp_mailbox->wq, &mctp_mailbox->work,
+ msecs_to_jiffies(XE_MCTP_MAILBOX_RX_POLL_MS));
+}
+
+static netdev_tx_t mctp_mailbox_start_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ /* RFC stub: send skb over MAILBOX */
+ dev_dstats_tx_dropped(dev);
+ kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static int mctp_mailbox_open(struct net_device *dev)
+{
+ struct xe_mctp_mailbox *mctp_mailbox = netdev_priv(dev);
+
+ mctp_mailbox->running = true;
+ netif_start_queue(dev);
+
+ queue_delayed_work(mctp_mailbox->wq, &mctp_mailbox->work, 0);
+
+ return 0;
+}
+
+static int mctp_mailbox_stop(struct net_device *dev)
+{
+ struct xe_mctp_mailbox *mctp_mailbox = netdev_priv(dev);
+
+ mctp_mailbox->running = false;
+ netif_stop_queue(dev);
+
+ cancel_delayed_work_sync(&mctp_mailbox->work);
+ flush_workqueue(mctp_mailbox->wq);
+
+ return 0;
+}
+
+static const struct net_device_ops mctp_mailbox_netdev_ops = {
+ .ndo_start_xmit = mctp_mailbox_start_xmit,
+ .ndo_open = mctp_mailbox_open,
+ .ndo_stop = mctp_mailbox_stop,
+};
+
+static void mctp_mailbox_netdev_setup(struct net_device *dev)
+{
+ /* Populate netdev structure */
+ dev->type = ARPHRD_MCTP;
+ /*
+ * dev->mtu = MCTP_MAILBOX_MTU_MIN;
+ * dev->min_mtu = MCTP_MAILBOX_MTU_MIN;
+ * dev->max_mtu = MCTP_MAILBOX_MTU_MAX;
+ *
+ * dev->hard_header_len = sizeof(struct mctp_mailbox_hdr);
+ * dev->tx_queue_len = DEFAULT_TX_QUEUE_LEN;
+ */
+ dev->flags = IFF_NOARP;
+ dev->netdev_ops = &mctp_mailbox_netdev_ops;
+ dev->pcpu_stat_type = NETDEV_PCPU_STAT_DSTATS;
+}
+
+static void xe_mctp_mailbox_fini(void *arg)
+{
+ struct xe_device *xe = arg;
+ struct xe_mctp_mailbox *mctp_mailbox = xe->mctp_mailbox;
+ struct net_device *netdev;
+
+ if (!mctp_mailbox)
+ return;
+
+ netdev = mctp_mailbox->netdev;
+ if (!netdev) {
+ xe->mctp_mailbox = NULL;
+ return;
+ }
+
+ if (mctp_mailbox->wq) {
+ mctp_mailbox->running = false;
+ cancel_delayed_work_sync(&mctp_mailbox->work);
+ destroy_workqueue(mctp_mailbox->wq);
+ mctp_mailbox->wq = NULL;
+ }
+
+ xe->mctp_mailbox = NULL;
+ mctp_unregister_netdev(netdev);
+ free_netdev(netdev);
+}
+
+int xe_mctp_mailbox_init(struct xe_device *xe)
+{
+ struct xe_mctp_mailbox *mctp_mailbox;
+ struct net_device *netdev;
+ int ret, err;
+
+ netdev = alloc_netdev(sizeof(*mctp_mailbox), "mctp_mailbox%d", NET_NAME_ENUM,
+ mctp_mailbox_netdev_setup);
+ if (!netdev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(netdev, xe->drm.dev);
+ mctp_mailbox = netdev_priv(netdev);
+ mctp_mailbox->netdev = netdev;
+
+ ret = mctp_register_netdev(netdev, NULL, MCTP_PHYS_BINDING_VENDOR);
+ if (ret) {
+ free_netdev(netdev);
+ return ret;
+ }
+
+ INIT_DELAYED_WORK(&mctp_mailbox->work, mctp_mailbox_rx_handler);
+ mctp_mailbox->wq = alloc_ordered_workqueue("mctp-mailbox-ordered-wq", 0);
+ if (!mctp_mailbox->wq) {
+ mctp_unregister_netdev(netdev);
+ free_netdev(netdev);
+ return -ENOMEM;
+ }
+
+ xe->mctp_mailbox = mctp_mailbox;
+ err = devm_add_action_or_reset(xe->drm.dev, xe_mctp_mailbox_fini, xe);
+ if (err)
+ return err;
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/xe/xe_mctp_mailbox.h b/drivers/gpu/drm/xe/xe_mctp_mailbox.h
new file mode 100644
index 000000000000..318ae173aaa1
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_mctp_mailbox.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ *
+ * Copyright 2026 Intel Corporation
+ */
+
+#ifndef _XE_MCTP_MAILBOX_H_
+#define _XE_MCTP_MAILBOX_H_
+
+struct xe_device;
+
+int xe_mctp_mailbox_init(struct xe_device *xe);
+
+#endif /* _XE_MCTP_MAILBOX_H_ */
--
2.54.0
^ permalink raw reply related
* Re: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010 and TS2500 MAC-PHY
From: Andrew Lunn @ 2026-05-04 19:23 UTC (permalink / raw)
To: Selvamani Rajagopal
Cc: Piergiorgio Beruto, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <CY8PR02MB9249082A82E8E2C503D6773683312@CY8PR02MB9249.namprd02.prod.outlook.com>
> > You failed to answer my question about this. What happens with your
> > device if you access C45 registers which don't exist?
>
> Sorry. Waiting for an answer from hardware designer.
It should not be too difficult to program up something like:
for (int mmd = 0 ; mmd < 32; mmd++)
for (int reg = 0; reg < 65535; reg++) {
val = phy_read_mmd(phydev, mmd, reg);
printf("%2x %4x: %4x\m", mmd, reg, val);
}
Andrew
^ permalink raw reply
* [PATCH batadv-next] batman-adv: use neigh_node's orig_node only as id
From: Sven Eckelmann @ 2026-05-04 19:32 UTC (permalink / raw)
To: Marek Lindner, Simon Wunderlich, Antonio Quartulli,
David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
Cc: Yuan Tan, Yifan Wu, Juefei Pu, Xin Liu, Jiexun Wang, Ren Wei,
b.a.t.m.a.n, netdev, linux-kernel, Sven Eckelmann
The orig_node member of struct batadv_neigh_node is no longer used in
B.A.T.M.A.N. IV. But batadv_neigh_node_create() is still storing it.
Only batadv_v_ogm_route_update() uses it to check if we route toward
it - not needing the data stored in the batadv_orig_node object itself,
but merely a pointer to identify the originator.
The field cannot hold a proper reference because that would create a
reference cycle, so it must never be dereferenced. Rename it to
orig_node_id and mark it __private to make any future attempt to
dereference it immediately noticeable.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
net/batman-adv/bat_v_ogm.c | 2 +-
net/batman-adv/originator.c | 5 ++++-
net/batman-adv/types.h | 11 +++++++++--
3 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
index e3870492dab7..10614d7c1053 100644
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -710,7 +710,7 @@ static bool batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
* don't route towards it
*/
router = batadv_orig_router_get(orig_node, if_outgoing);
- if (router && router->orig_node != orig_node && !orig_neigh_router) {
+ if (router && ACCESS_PRIVATE(router, orig_node_id) != orig_node && !orig_neigh_router) {
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Drop packet: OGM via unknown neighbor!\n");
goto out;
diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
index b3468ccab535..97375eb4cd96 100644
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -694,9 +694,12 @@ batadv_neigh_node_create(struct batadv_orig_node *orig_node,
kref_get(&hard_iface->refcount);
ether_addr_copy(neigh_node->addr, neigh_addr);
neigh_node->if_incoming = hard_iface;
- neigh_node->orig_node = orig_node;
neigh_node->last_seen = jiffies;
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+ ACCESS_PRIVATE(neigh_node, orig_node_id) = orig_node;
+#endif
+
/* increment unique neighbor refcount */
kref_get(&hardif_neigh->refcount);
neigh_node->hardif_neigh = hardif_neigh;
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index daa06f421154..ba46e414fe05 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -628,8 +628,15 @@ struct batadv_neigh_node {
/** @list: list node for &batadv_orig_node.neigh_list */
struct hlist_node list;
- /** @orig_node: pointer to corresponding orig_node */
- struct batadv_orig_node *orig_node;
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+ /**
+ * @orig_node_id: pointer to corresponding orig_node. It must only be used
+ * to identify the node but must NEVER be dereferenced. The reference counter
+ * was not increased when this was assigned because it would otherwise create
+ * an reference cycle.
+ */
+ struct batadv_orig_node *__private orig_node_id;
+#endif
/** @addr: the MAC address of the neighboring interface */
u8 addr[ETH_ALEN];
---
base-commit: 1f5ffc672165ff851063a5fd044b727ab2517ae3
change-id: 20260504-neigh_node-no-orig_node-e8bc7e79d9ba
prerequisite-patch-id: 8d01950de12c8f4715e9f4723a0b6f1c349e6a84
Best regards,
--
Sven Eckelmann <sven@narfation.org>
^ permalink raw reply related
* Re: [PATCH net-next] net/sched: speedup tc_dump_qdisc() when tcm_handle is provided
From: Jamal Hadi Salim @ 2026-05-04 19:34 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
Jiri Pirko, netdev, eric.dumazet
In-Reply-To: <CANn89iKAdEGGZ_q09-3EtY_SUhjq__T9nU-jNkgDy2urYsqpkA@mail.gmail.com>
On Mon, May 4, 2026 at 3:20 PM Eric Dumazet <edumazet@google.com> wrote:
>
> On Mon, May 4, 2026 at 12:13 PM Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> >
> > On Sun, May 3, 2026 at 7:45 AM Eric Dumazet <edumazet@google.com> wrote:
> > >
> > > "tc qdisc show ... handle xxx" filtering can be done by the kernel.
> > >
> > > A followup patch can do the same for tcm_parent.
> > >
> > > iproute2/tc needs a small companion patch.
> > >
> > > Signed-off-by: Eric Dumazet <edumazet@google.com>
> >
> > If you ever redo this for whatever reason, showing the dump of before
> > and after will be good documentation.
>
> There is no difference in tc output.
>
> One can use strace and look at all the recvmsg() values, but they are
> quite verbose :/
Ah, i see it now ;->
cheers,
jamal
^ permalink raw reply
* [PATCH net] i2c: sun6i-p2wi: fix of_node reference leak in probe
From: Shitalkumar Gandhi @ 2026-05-04 19:36 UTC (permalink / raw)
To: Niklas Söderlund
Cc: Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
Andrew Lunn, Simon Horman, netdev, linux-renesas-soc,
linux-kernel, Shitalkumar Gandhi, Felix Gu
of_get_next_available_child() returns a device_node pointer with an
incremented reference count. The reference taken in p2wi_probe() for
the optional child node was dropped on neither the early return when
the "reg" property is missing/invalid nor on the success path, so a
reference is leaked once on every successful probe and twice on every
failed one.
Use the scoped __free(device_node) cleanup helper at the point of
acquisition so the reference is dropped automatically on every exit
path.
Suggested-by: Felix Gu <ustc.gu@gmail.com>
Link: https://lore.kernel.org/linux-i2c/20260201-p2wi-v1-1-e0ec9cda82b3@gmail.com/
Fixes: 3e833490fae5 ("i2c: sunxi: add P2WI (Push/Pull 2 Wire Interface) controller support")
Signed-off-by: Shitalkumar Gandhi <shitalkumar.gandhi@cambiumnetworks.com>
---
drivers/i2c/busses/i2c-sun6i-p2wi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index fb5280b8cf7f..652b37b57159 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -184,7 +184,6 @@ static int p2wi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct device_node *childnp;
unsigned long parent_clk_freq;
u32 clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
struct p2wi *p2wi;
@@ -223,7 +222,8 @@ static int p2wi_probe(struct platform_device *pdev)
* In this case the target_addr is set to -1 and won't be checked when
* launching a P2WI transfer.
*/
- childnp = of_get_next_available_child(np, NULL);
+ struct device_node *childnp __free(device_node) =
+ of_get_next_available_child(np, NULL);
if (childnp) {
ret = of_property_read_u32(childnp, "reg", &target_addr);
if (ret) {
--
2.25.1
^ permalink raw reply related
* [PATCH net] i2c: sun6i-p2wi: fix of_node reference leak in probe
From: Shitalkumar Gandhi @ 2026-05-04 19:38 UTC (permalink / raw)
To: MD Danish Anwar, Parvathi Pudi
Cc: Roger Quadros, Mohan Reddy Putluru, Jakub Kicinski,
David S . Miller, Eric Dumazet, Paolo Abeni, Andrew Lunn,
Simon Horman, Dan Carpenter, netdev, linux-arm-kernel,
linux-kernel, Shitalkumar Gandhi, Felix Gu
of_get_next_available_child() returns a device_node pointer with an
incremented reference count. The reference taken in p2wi_probe() for
the optional child node was dropped on neither the early return when
the "reg" property is missing/invalid nor on the success path, so a
reference is leaked once on every successful probe and twice on every
failed one.
Use the scoped __free(device_node) cleanup helper at the point of
acquisition so the reference is dropped automatically on every exit
path.
Suggested-by: Felix Gu <ustc.gu@gmail.com>
Link: https://lore.kernel.org/linux-i2c/20260201-p2wi-v1-1-e0ec9cda82b3@gmail.com/
Fixes: 3e833490fae5 ("i2c: sunxi: add P2WI (Push/Pull 2 Wire Interface) controller support")
Signed-off-by: Shitalkumar Gandhi <shitalkumar.gandhi@cambiumnetworks.com>
---
drivers/i2c/busses/i2c-sun6i-p2wi.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-sun6i-p2wi.c b/drivers/i2c/busses/i2c-sun6i-p2wi.c
index fb5280b8cf7f..652b37b57159 100644
--- a/drivers/i2c/busses/i2c-sun6i-p2wi.c
+++ b/drivers/i2c/busses/i2c-sun6i-p2wi.c
@@ -184,7 +184,6 @@ static int p2wi_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- struct device_node *childnp;
unsigned long parent_clk_freq;
u32 clk_freq = I2C_MAX_STANDARD_MODE_FREQ;
struct p2wi *p2wi;
@@ -223,7 +222,8 @@ static int p2wi_probe(struct platform_device *pdev)
* In this case the target_addr is set to -1 and won't be checked when
* launching a P2WI transfer.
*/
- childnp = of_get_next_available_child(np, NULL);
+ struct device_node *childnp __free(device_node) =
+ of_get_next_available_child(np, NULL);
if (childnp) {
ret = of_property_read_u32(childnp, "reg", &target_addr);
if (ret) {
--
2.25.1
^ permalink raw reply related
* Re: [PATCH 2/2 net] selftests: fib_tests: add temporary IPv6 address renewal test
From: Fernando Fernandez Mancera @ 2026-05-04 19:45 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, linux-kselftest, horms, pabeni, kuba, edumazet, davem,
dsahern
In-Reply-To: <20260504164149.GB385401@shredder>
On 5/4/26 6:41 PM, Ido Schimmel wrote:
> On Mon, May 04, 2026 at 12:11:41AM +0200, Fernando Fernandez Mancera wrote:
>> Add a test to check that temporary IPv6 address is regenerated properly
>> after the base prefix is deprecated and restored.
>>
>> Fib6 temporary address renewal test
>> TEST: IPv6 temporary address cleanly deprecated and regenerated [ OK ]
>
> Thanks for the test, but I reverted the fix and it still passes :(
>
Ugh sorry for that. I lowered the sleep time so it takes less time to
run and I messed up the test. It seems 2 seconds isn't enough and to
reliable reproduce it, 3 seconds are required.
I am reposting with the test fixed, sorry again for the noise.
>>
>> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>> ---
>> tools/testing/selftests/net/fib_tests.sh | 55 +++++++++++++++++++++++-
>> 1 file changed, 54 insertions(+), 1 deletion(-)
>>
>> diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
>> index af64f93bb2e1..6a6e545cb40d 100755
>> --- a/tools/testing/selftests/net/fib_tests.sh
>> +++ b/tools/testing/selftests/net/fib_tests.sh
>> @@ -12,7 +12,7 @@ TESTS="unregister down carrier nexthop suppress ipv6_notify ipv4_notify \
>> ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr \
>> ipv6_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh fib6_gc_test \
>> ipv4_mpath_list ipv6_mpath_list ipv4_mpath_balance ipv6_mpath_balance \
>> - ipv4_mpath_balance_preferred fib6_ra_to_static"
>> + ipv4_mpath_balance_preferred fib6_ra_to_static fib6_temp_addr_renewal"
>>
>> VERBOSE=0
>> PAUSE_ON_FAIL=no
>> @@ -1611,6 +1611,58 @@ fib6_ra_to_static()
>> cleanup &> /dev/null
>> }
>>
>> +fib6_temp_addr_renewal() {
>> + setup
>> +
>> + echo
>> + echo "Fib6 temporary address renewal test"
>> + set -e
>> +
>> + # ra6 is required for the test. (ipv6toolkit)
>> + if [ ! -x "$(command -v ra6)" ]; then
>> + echo "SKIP: ra6 not found."
>> + set +e
>> + cleanup &> /dev/null
>> + return
>> + fi
>> +
>> + # Create a pair of veth devices to send a RA message from one
>> + # device to another.
>> + $IP link add veth1 type veth peer name veth2
>> + $IP link set dev veth1 up
>> + $IP link set dev veth2 up
>> +
>> + # Make veth1 ready to receive RA messages.
>> + $NS_EXEC sysctl -wq net.ipv6.conf.veth1.accept_ra=2
>> + $NS_EXEC sysctl -wq net.ipv6.conf.veth1.use_tempaddr=2
>> + $NS_EXEC sysctl -wq net.ipv6.conf.veth1.temp_prefered_lft=15
>> + $NS_EXEC sysctl -wq net.ipv6.conf.veth1.max_desync_factor=0
>> +
>> + # Send a RA message with a prefix from veth2.
>> + $NS_EXEC ra6 -i veth2 -s fe80::1 -d ff02::1 -P 2001:12::/64\#LA\#3600\#3600 -e
>> + sleep 2
>> +
>> + # Deprecate it
>> + $NS_EXEC ra6 -i veth2 -s fe80::1 -d ff02::1 -P 2001:12::/64\#LA\#3600\#0 -e
>> + sleep 2
>> +
>> + # Restore it
>> + $NS_EXEC ra6 -i veth2 -s fe80::1 -d ff02::1 -P 2001:12::/64\#LA\#3600\#3600 -e
>> +
>> + ret=1
>> + for i in $(seq 1 25); do
>> + sleep 1
>> + num_dep="$($IP -6 addr | grep -c "temporary deprecated" || true)"
>> + num_tot="$($IP -6 addr | grep -c "temporary" || true)"
>> +
>> + if [ "$num_dep" -eq 1 ] && [ "$num_tot" -ge 2 ]; then
>> + ret=0
>> + break
>> + fi
>> + done
>> + log_test "$ret" 0 "IPv6 temporary address cleanly deprecated and regenerated"
>
> Missing:
>
> set +e
>
> cleanup &> /dev/null
>
> Like in fib6_ra_to_static() and the skip path?
Oops, thanks!
>
>> +}
>> +
>> # add route for a prefix, flushing any existing routes first
>> # expected to be the first step of a test
>> add_route()
>> @@ -3002,6 +3054,7 @@ do
>> ipv6_mpath_balance) ipv6_mpath_balance_test;;
>> ipv4_mpath_balance_preferred) ipv4_mpath_balance_preferred_test;;
>> fib6_ra_to_static) fib6_ra_to_static;;
>> + fib6_temp_addr_renewal) fib6_temp_addr_renewal;;
>>
>> help) echo "Test names: $TESTS"; exit 0;;
>> esac
>> --
>> 2.53.0
>>
>
^ permalink raw reply
* Re: [PATCH 1/2 net] ipv6: addrconf: fix temp address generation after prefix deprecation
From: Fernando Fernandez Mancera @ 2026-05-04 19:51 UTC (permalink / raw)
To: Ido Schimmel
Cc: netdev, linux-kselftest, horms, pabeni, kuba, edumazet, davem,
dsahern, Łukasz Stelmach
In-Reply-To: <20260504163549.GA385401@shredder>
On 5/4/26 6:35 PM, Ido Schimmel wrote:
> On Mon, May 04, 2026 at 12:11:40AM +0200, Fernando Fernandez Mancera wrote:
>> When a router temporarily deprecates an IPv6 prefix (either by sending a
>> Router Advertisement with Preferred Lifetime = 0 or by letting the
>> lifetime expire) and later restores it, the kernel permanently loses its
>> ability to generate temporary privacy addresses (RFC 8981) for that
>> prefix.
>>
>> This happens because the address worker attempts to generate a
>> replacement temporary address when the current one nears expiration. As
>> the base prefix is deprecated already, the generation fails, burning the
>> retry counter for temporary address generation of that prefix.
>>
>> When the router eventually restores the prefix, the temporary address
>> becomes active again. However, once it naturally expires, the kernel
>> sees the exhausted retry limit and permanently stops generating new
>> privacy addresses.
>
> It's not clear to me to which "retry counter" you are referring to. Are
> you referring to the counter of the temporary address or to that of the
> "public address" from which it was generated?
>
> AFAICT, in the case of temporary addresses (those w/o "mngtmpaddr") this
> isn't really a counter, but a boolean that tells you if an address was
> already spawned from this address.
>
>>
>> Fix this by verifying that the base prefix has sufficient preferred
>> lifetime remaining before attempting to generate a new temporary
>> address. This prevents the worker from burning through its retry counter
>> during temporary network deprecation events like a router reboot.
>
> Again, I think that "retry counter" here is confusing. IIUC, what
> happens is that the kernel marks the temporary address as having spawned
> an address ('ifp->regen_count++'), then tries to spawn an address by
> calling ipv6_create_tempaddr(), which fails because the preferred
> lifetime of the public address is 0.
>
Yes, you are right. I used the word counter as the variable was
ifp->regen_count although for temporary addresses it is just a boolean.
Let me modify the commit message to make it clear.
Thanks Ido for reviewing!
>>
>> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
>> Reported-by: Łukasz Stelmach <steelman@post.pl>
>> Closes: https://lore.kernel.org/netdev/87340td30q.fsf%25steelman@post.pl/
>> Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de>
>> ---
>> net/ipv6/addrconf.c | 4 +++-
>> 1 file changed, 3 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
>> index 5476b6536eb7..f6a3d9da3cb1 100644
>> --- a/net/ipv6/addrconf.c
>> +++ b/net/ipv6/addrconf.c
>> @@ -4654,9 +4654,11 @@ static void addrconf_verify_rtnl(struct net *net)
>> !ifp->regen_count && ifp->ifpub) {
>> /* This is a non-regenerated temporary addr. */
>>
>> + unsigned long pub_age = (now - READ_ONCE(ifp->ifpub->tstamp)) / HZ;
>> unsigned long regen_advance = ipv6_get_regen_advance(ifp->idev);
>>
>> - if (age + regen_advance >= ifp->prefered_lft) {
>> + if (age + regen_advance >= ifp->prefered_lft &&
>> + pub_age + regen_advance < READ_ONCE(ifp->ifpub->prefered_lft)) {
>> struct inet6_ifaddr *ifpub = ifp->ifpub;
>> if (time_before(ifp->tstamp + ifp->prefered_lft * HZ, next))
>> next = ifp->tstamp + ifp->prefered_lft * HZ;
>> --
>> 2.53.0
>>
^ permalink raw reply
* [PATCH net] net: rtsn: fix mdio_node leak in rtsn_mdio_alloc()
From: Shitalkumar Gandhi @ 2026-05-04 20:03 UTC (permalink / raw)
To: Niklas Söderlund
Cc: Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
Andrew Lunn, Simon Horman, netdev, linux-renesas-soc,
linux-kernel, Shitalkumar Gandhi
of_get_child_by_name() takes a reference. The rtsn_reset() and
rtsn_change_mode() failure paths jump to out_free_bus and leak
mdio_node.
Add out_put_node to drop it before falling through.
Fixes: b0d3969d2b4d ("net: ethernet: rtsn: Add support for Renesas Ethernet-TSN")
Signed-off-by: Shitalkumar Gandhi <shitalkumar.gandhi@cambiumnetworks.com>
---
drivers/net/ethernet/renesas/rtsn.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/renesas/rtsn.c b/drivers/net/ethernet/renesas/rtsn.c
index 03a2669f0518..c46d991cceb5 100644
--- a/drivers/net/ethernet/renesas/rtsn.c
+++ b/drivers/net/ethernet/renesas/rtsn.c
@@ -797,11 +797,11 @@ static int rtsn_mdio_alloc(struct rtsn_private *priv)
/* Enter config mode before registering the MDIO bus */
ret = rtsn_reset(priv);
if (ret)
- goto out_free_bus;
+ goto out_put_node;
ret = rtsn_change_mode(priv, OCR_OPC_CONFIG);
if (ret)
- goto out_free_bus;
+ goto out_put_node;
rtsn_modify(priv, MPIC, MPIC_PSMCS_MASK | MPIC_PSMHT_MASK,
MPIC_PSMCS_DEFAULT | MPIC_PSMHT_DEFAULT);
@@ -823,7 +823,8 @@ static int rtsn_mdio_alloc(struct rtsn_private *priv)
priv->mii = mii;
return 0;
-
+out_put_node:
+ of_node_put(mdio_node);
out_free_bus:
mdiobus_free(mii);
return ret;
--
2.25.1
^ permalink raw reply related
* RE: [PATCH net v3] net/mana: Fix auxiliary device double-delete race
From: Long Li @ 2026-05-04 20:13 UTC (permalink / raw)
To: Konstantin Taranov, Shiraz Saleem, Konstantin Taranov,
pabeni@redhat.com, Haiyang Zhang, KY Srinivasan,
edumazet@google.com, kuba@kernel.org, davem@davemloft.net,
Dexuan Cui, wei.liu@kernel.org, jgg@ziepe.ca, leon@kernel.org
Cc: linux-rdma@vger.kernel.org, linux-kernel@vger.kernel.org,
netdev@vger.kernel.org
In-Reply-To: <20260504142704.159035-1-kotaranov@linux.microsoft.com>
> From: Shiraz Saleem <shirazsaleem@microsoft.com>
>
> Make remove_adev() safe to call concurrently from the service reset and PCI
> eject paths by using xchg() to atomically claim the adev pointer. This prevents
> double auxiliary_device_delete/uninit when hv_eject_device_work races with
> the service reset workqueue.
>
> Fixes: 505cc26bcae0 ("net: mana: Add support for auxiliary device servicing
> events")
> Signed-off-by: Shiraz Saleem <shirazsaleem@microsoft.com>
> Signed-off-by: Konstantin Taranov <kotaranov@microsoft.com>
Reviewed-by: Long Li <longli@microsoft.com>
> ---
> v3: Separate the xchg() call from the variable declaration in remove_adev() to
> avoid calling functions with side effects as variable initializers
> v2: rebased on the latest net
> drivers/net/ethernet/microsoft/mana/mana_en.c | 19 +++++++++++--------
> 1 file changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c
> b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index a654b3699..dd4f4215a 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -3465,14 +3465,19 @@ static void adev_release(struct device *dev)
>
> static void remove_adev(struct gdma_dev *gd) {
> - struct auxiliary_device *adev = gd->adev;
> - int id = adev->id;
> + struct auxiliary_device *adev;
> + int id;
> +
> + adev = xchg(&gd->adev, NULL);
> + if (!adev)
> + return;
> +
> + id = adev->id;
>
> auxiliary_device_delete(adev);
> auxiliary_device_uninit(adev);
>
> mana_adev_idx_free(id);
> - gd->adev = NULL;
> }
>
> static int add_adev(struct gdma_dev *gd, const char *name) @@ -3538,7
> +3543,7 @@ static void mana_rdma_service_handle(struct work_struct *work)
>
> switch (serv_work->event) {
> case GDMA_SERVICE_TYPE_RDMA_SUSPEND:
> - if (!gd->adev || gd->is_suspended)
> + if (gd->is_suspended)
> break;
>
> remove_adev(gd);
> @@ -3753,8 +3758,7 @@ void mana_remove(struct gdma_dev *gd, bool
> suspending)
> cancel_delayed_work_sync(&ac->gf_stats_work);
>
> /* adev currently doesn't support suspending, always remove it */
> - if (gd->adev)
> - remove_adev(gd);
> + remove_adev(gd);
>
> for (i = 0; i < ac->num_ports; i++) {
> ndev = ac->ports[i];
> @@ -3843,8 +3847,7 @@ void mana_rdma_remove(struct gdma_dev *gd)
> if (gc->service_wq)
> flush_workqueue(gc->service_wq);
>
> - if (gd->adev)
> - remove_adev(gd);
> + remove_adev(gd);
>
> mana_gd_deregister_device(gd);
> }
> --
> 2.43.0
^ permalink raw reply
* Re: [PATCH net v2 0/2] openvswitch: fix self-deadlock on release of tunnel vports
From: Aaron Conole @ 2026-05-04 20:24 UTC (permalink / raw)
To: Ilya Maximets
Cc: netdev, Eelco Chaudron, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Shuah Khan, Yuan Tan,
Yang Yang, dev, linux-kernel, linux-kselftest
In-Reply-To: <d9a9fcf7-07e2-4e26-afde-f1bec6108c40@ovn.org>
Ilya Maximets <i.maximets@ovn.org> writes:
> On 5/1/26 1:38 AM, Ilya Maximets wrote:
>> Two patches - the fix for the actual bug and the selftest that reproduces it.
>>
>> I missed the self-deadlock in the original patch that introduced the issue,
>> because testing required code modification in the ovs-vswitchd to force it to
>> use legacy tunnel ports. I thought I made the change correctly, but apparently
>> something went wrong and the tests were run with the standard LWT infra instead.
>> The selftest added in this patch set will at least prevent this kind of mistakes
>> in the future.
>>
>> I mentioned, however, that these tunnel vports are legacy and not actually used
>> by ovs-vswitchd. RTM_NEWLINK + COLLECT_METADATA is used in conjunction with the
>> standard OVS_VPORT_TYPE_NETDEV instead since 2017. The code to use the legacy
>> tunnels still exists in ovs-vswitchd however, but only as a fallback for older
>> kernels and we're planning to remove it in the next release. I'll be sending an
>> RFC to remove support for these legacy tunnel types from the kernel, as they
>> serve no real purpose today and only increase the uAPI surface for CVEs, but
>> we need to fix the known bugs for stable versions.
>>
>>
>> Version 2:
>> - Added Ack from Eelco to the first patch (not to the second as it
>> changed a little).
>> - Removed now unused import socket in the dpctl.py [pylint/ruff].
>>
>> - Regarding comments from both Sashiko instances on the selftest patch:
>>
>> * The background process is not waited for / not killed.
>> If it hangs it will not be killable anyway, so it's not a problem.
>
> Both sashiko instances still flag this. Looks like the cover letter is not
> included in the prompt.
>
> If someone thinks I should add the suggested kill on exit, I can, but it will
> not be effective in case the process hangs.
One option is to put a comment in the test itself documenting this kind
of behavior. At least, then the model might not flag it. I don't feel
strongly about that, however.
> Best regards, Ilya Maximets.
^ permalink raw reply
* RE: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010 and TS2500 MAC-PHY
From: Selvamani Rajagopal @ 2026-05-04 20:51 UTC (permalink / raw)
To: Andrew Lunn
Cc: Piergiorgio Beruto, andrew+netdev@lunn.ch, davem@davemloft.net,
edumazet@google.com, kuba@kernel.org, pabeni@redhat.com,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <e2f03fc4-2948-4046-83a6-7d587e09ef62@lunn.ch>
> -----Original Message-----
> From: Andrew Lunn <andrew@lunn.ch>
> Sent: Monday, May 4, 2026 12:24 PM
> To: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
> Cc: Piergiorgio Beruto <Pier.Beruto@onsemi.com>; andrew+netdev@lunn.ch;
> davem@davemloft.net; edumazet@google.com; kuba@kernel.org; pabeni@redhat.com;
> netdev@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH net-next 4/5] onsemi: ncn260xx: Add driver support for NCN26010
> and TS2500 MAC-PHY
>
>
> This Message Is From an External Sender
> This message came from outside your organization.
>
> > > You failed to answer my question about this. What happens with your
> > > device if you access C45 registers which don't exist?
> >
> > Sorry. Waiting for an answer from hardware designer.
>
> It should not be too difficult to program up something like:
>
> for (int mmd = 0 ; mmd < 32; mmd++)
> for (int reg = 0; reg < 65535; reg++) {
> val = phy_read_mmd(phydev, mmd, reg);
> printf("%2x %4x: %4x\m", mmd, reg, val);
> }
Andrew, I had replied with the answer earlier. The answer is, yes. it would return 0.
Recent update is that after talking to our product team, we want to submit the support for TS2500 first which doesn't require the quirks we are discussing. It is the older chip, NCN26010 that requires
the quirk flag you suggested.
In short, next version would have modification to OA TC6 framework to add hardware timestamp support only. We will revisit support for older, NCN26010 that requires modification to the way MDIO bus API are handled, later.
Will re-submit soon after removing support for NCN26010.
>
> Andrew
^ permalink raw reply
* Re: [PATCH 07/11] vfio: selftests: Allow drivers to specify required region size
From: David Matlack @ 2026-05-04 20:55 UTC (permalink / raw)
To: Jason Gunthorpe
Cc: Alex Williamson, kvm, Leon Romanovsky, linux-kselftest,
linux-rdma, Mark Bloch, netdev, Saeed Mahameed, Shuah Khan,
Tariq Toukan, patches
In-Reply-To: <7-v1-dc5fa250ca1d+3213-mlx5st_jgg@nvidia.com>
On 2026-04-30 09:08 PM, Jason Gunthorpe wrote:
> Add a region_size field to struct vfio_pci_driver_ops so drivers can
> declare how much DMA-mapped region they need. The mlx5 driver will
> need ~18MB for firmware pages. Existing drivers leave region_size as
> 0 and get the current default of SZ_2M.
I would like to get rid of the magic SZ_2M to make it easier for other
tests to use the driver framework. Can you make this commit update all
the drivers to set region_size? They can all use the same approach:
struct vfio_pci_driver_ops foo_driver = {
...
.region_size = roundup_pow_of_two(sizeof(struct foo)),
...
};
^ permalink raw reply
* [PATCH v2 bpf 0/6] bpf: tcp: Fix type confusion in bpf helper functions.
From: Kuniyuki Iwashima @ 2026-05-04 21:04 UTC (permalink / raw)
To: Martin KaFai Lau, Daniel Borkmann, Alexei Starovoitov,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: John Fastabend, Stanislav Fomichev, Song Liu, Yonghong Song,
Jiri Olsa, Eric Dumazet, Kuniyuki Iwashima, Kuniyuki Iwashima,
bpf, netdev
bpf_tcp_sock() only check if sk->sk_protocol is IPPROTO_TCP,
but RAW socket can bypass it:
socket(AF_INET, SOCK_RAW, IPPROTO_TCP)
The same issues exist in other bpf functions:
* bpf_mptcp_sock_from_subflow()
* bpf_skc_to_tcp_sock()
* bpf_skc_to_tcp6_sock()
* sol_tcp_sockopt()
Patch 1 fixes bpf_tcp_sock() and Patch 2 adds a test for it.
Patch 3 ~ 6 fix the rest of the functions above.
Changes:
v2:
* Inverse if (err) to if (!err) in the selftest
* Add patch 3 ~ 6
v1: https://lore.kernel.org/bpf/20260430184405.1227386-1-kuniyu@google.com/
https://lore.kernel.org/mptcp/20260430-mptcp-bpf-mptcp-sock-type-v1-1-d2ed5cda7da9@kernel.org/
Kuniyuki Iwashima (5):
bpf: tcp: Fix type confusion in bpf_tcp_sock().
selftest: bpf: Add test for bpf_tcp_sock() and RAW socket.
bpf: tcp: Fix type confusion in bpf_skc_to_tcp_sock().
bpf: tcp: Fix type confusion in bpf_skc_to_tcp6_sock().
bpf: tcp: Fix type confusion in sol_tcp_sockopt().
Matthieu Baerts (NGI0) (1):
mptcp: bpf: fix type confusion in bpf_mptcp_sock_from_subflow()
net/core/filter.c | 8 ++++----
net/mptcp/bpf.c | 2 +-
.../selftests/bpf/prog_tests/sockopt_sk.c | 18 +++++++++++++++++-
tools/testing/selftests/bpf/progs/sockopt_sk.c | 16 ++++++++++++++++
4 files changed, 38 insertions(+), 6 deletions(-)
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply
* [PATCH v2 bpf 1/6] bpf: tcp: Fix type confusion in bpf_tcp_sock().
From: Kuniyuki Iwashima @ 2026-05-04 21:04 UTC (permalink / raw)
To: Martin KaFai Lau, Daniel Borkmann, Alexei Starovoitov,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: John Fastabend, Stanislav Fomichev, Song Liu, Yonghong Song,
Jiri Olsa, Eric Dumazet, Kuniyuki Iwashima, Kuniyuki Iwashima,
bpf, netdev, Damiano Melotti
In-Reply-To: <20260504210610.180150-1-kuniyu@google.com>
bpf_tcp_sock() only checks if sk->sk_protocol is IPPROTO_TCP,
but RAW socket can bypass it:
socket(AF_INET, SOCK_RAW, IPPROTO_TCP)
Calling bpf_setsockopt() in SOCKOPT prog triggers out-of-bounds
access to another slab object. [0]
Let's use sk_is_tcp().
[0]:
BUG: KASAN: slab-out-of-bounds in sol_tcp_sockopt (net/core/filter.c:5519)
Read of size 8 at addr ffff88801083d760 by task test_progs/1259
CPU: 1 UID: 0 PID: 1259 Comm: test_progs Tainted: G OE 7.0.0-11175-gb5c111f4967b #1 PREEMPT(full)
Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014
Call Trace:
<TASK>
dump_stack_lvl (lib/dump_stack.c:94 lib/dump_stack.c:120)
print_report (mm/kasan/report.c:378 mm/kasan/report.c:482)
kasan_report (mm/kasan/report.c:595)
sol_tcp_sockopt (net/core/filter.c:5519)
__bpf_getsockopt (net/core/filter.c:5633)
bpf_sk_getsockopt (net/core/filter.c:5654)
bpf_prog_629ba00a1601e9f2__setsockopt+0x86/0x22c
__cgroup_bpf_run_filter_setsockopt (./include/linux/bpf.h:1402 ./include/linux/filter.h:722 ./include/linux/filter.h:729 kernel/bpf/cgroup.c:81 kernel/bpf/cgroup.c:2026)
do_sock_setsockopt (net/socket.c:2363)
__x64_sys_setsockopt (net/socket.c:2406)
do_syscall_64 (arch/x86/entry/syscall_64.c:63)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
RIP: 0033:0x7f85f82fe7de
Code: 55 48 63 c9 48 63 ff 45 89 c9 48 89 e5 48 83 ec 08 6a 2c e8 34 69 f7 ff c9 c3 66 90 f3 0f 1e fa 49 89 ca b8 36 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 0a c3 66 0f 1f 84 00 00 00 00 00 48 8b 15 e1
RSP: 002b:00007ffe59dcecd8 EFLAGS: 00000202 ORIG_RAX: 0000000000000036
RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f85f82fe7de
RDX: 000000000000001c RSI: 0000000000000006 RDI: 000000000000000d
RBP: 00007ffe59dcef20 R08: 000000000000003c R09: 0000000000000000
R10: 00007ffe59dcef00 R11: 0000000000000202 R12: 00007ffe59dcf268
R13: 0000000000000003 R14: 00007f85f9da5000 R15: 000055b2f3201400
</TASK>
The buggy address belongs to the object at ffff88801083d280
which belongs to the cache RAW of size 1792
The buggy address is located 1248 bytes inside of
allocated 1792-byte region [ffff88801083d280, ffff88801083d980)
Fixes: 655a51e536c0 ("bpf: Add struct bpf_tcp_sock and BPF_FUNC_tcp_sock")
Reported-by: Damiano Melotti <melotti@google.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
---
net/core/filter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index bc96c18df4e0..cd88633f8dc1 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -7475,7 +7475,7 @@ u32 bpf_tcp_sock_convert_ctx_access(enum bpf_access_type type,
BPF_CALL_1(bpf_tcp_sock, struct sock *, sk)
{
- if (sk_fullsock(sk) && sk->sk_protocol == IPPROTO_TCP)
+ if (sk_fullsock(sk) && sk_is_tcp(sk))
return (unsigned long)sk;
return (unsigned long)NULL;
--
2.54.0.545.g6539524ca2-goog
^ permalink raw reply related
* [PATCH v2 bpf 2/6] selftest: bpf: Add test for bpf_tcp_sock() and RAW socket.
From: Kuniyuki Iwashima @ 2026-05-04 21:04 UTC (permalink / raw)
To: Martin KaFai Lau, Daniel Borkmann, Alexei Starovoitov,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi
Cc: John Fastabend, Stanislav Fomichev, Song Liu, Yonghong Song,
Jiri Olsa, Eric Dumazet, Kuniyuki Iwashima, Kuniyuki Iwashima,
bpf, netdev
In-Reply-To: <20260504210610.180150-1-kuniyu@google.com>
Let's extend sockopt_sk.c to cover bpf_tcp_sock() for the
wrong socket type.
Before:
# ./test_progs -t sockopt_sk
[ 151.948613] ==================================================================
[ 151.951376] BUG: KASAN: slab-out-of-bounds in sol_tcp_sockopt+0xc7/0x8e0
[ 151.954159] Read of size 8 at addr ffff88801083d760 by task test_progs/1259
...
run_test:FAIL:getsetsockopt unexpected error: -1 (errno 0)
#427 sockopt_sk:FAIL
After:
#427 sockopt_sk:OK
While at it, missing free() is fixed up.
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
---
v2: Inverted if (err) to if (!err)
---
.../selftests/bpf/prog_tests/sockopt_sk.c | 18 +++++++++++++++++-
tools/testing/selftests/bpf/progs/sockopt_sk.c | 16 ++++++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
index 53637431ec5d..5fd33ad2eaaf 100644
--- a/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c
@@ -190,7 +190,7 @@ static int getsetsockopt(void)
fd = socket(AF_NETLINK, SOCK_RAW, 0);
if (fd < 0) {
log_err("Failed to create AF_NETLINK socket");
- return -1;
+ goto err;
}
buf.u32 = 1;
@@ -211,6 +211,22 @@ static int getsetsockopt(void)
}
ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value");
+ /* Trick bpf_tcp_sock() with IPPROTO_TCP */
+ close(fd);
+ fd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP);
+ if (fd < 0) {
+ log_err("Failed to create RAW socket");
+ goto err;
+ }
+
+ optlen = 20;
+ errno = 0;
+ err = setsockopt(fd, SOL_TCP, TCP_SAVED_SYN, &buf, optlen);
+ if (!err) {
+ log_err("Unexpected setsockopt(TCP_SAVED_SYN)");
+ goto err;
+ }
+
free(big_buf);
close(fd);
return 0;
diff --git a/tools/testing/selftests/bpf/progs/sockopt_sk.c b/tools/testing/selftests/bpf/progs/sockopt_sk.c
index cb990a7d3d45..5e0b27e7855c 100644
--- a/tools/testing/selftests/bpf/progs/sockopt_sk.c
+++ b/tools/testing/selftests/bpf/progs/sockopt_sk.c
@@ -149,6 +149,20 @@ int _setsockopt(struct bpf_sockopt *ctx)
if (sk && sk->family == AF_NETLINK)
goto out;
+ if (sk && sk->family == AF_INET && sk->type == SOCK_RAW) {
+ struct bpf_tcp_sock *tp = bpf_tcp_sock(sk);
+
+ if (tp) {
+ char saved_syn[60];
+
+ bpf_getsockopt(sk, SOL_TCP, TCP_SAVED_SYN,
+ &saved_syn, sizeof(saved_syn));
+ goto consumed;
+ }
+
+ goto out;
+ }
+
/* Make sure bpf_get_netns_cookie is callable.
*/
if (bpf_get_netns_cookie(NULL) == 0)
@@ -224,6 +238,8 @@ int _setsockopt(struct bpf_sockopt *ctx)
return 0; /* couldn't get sk storage */
storage->val = optval[0];
+
+consumed:
ctx->optlen = -1; /* BPF has consumed this option, don't call kernel
* setsockopt handler.
*/
--
2.54.0.545.g6539524ca2-goog
^ 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