* Re: [PATCH iproute2] ss: fix vsock port filter
From: Luigi Leonardi @ 2026-04-21 14:01 UTC (permalink / raw)
To: sgarzare, stefanha, netdev
In-Reply-To: <20260421-fix_vsock-v1-1-812c80a76c1a@redhat.com>
On Tue, Apr 21, 2026 at 02:35:12PM +0200, Luigi Leonardi wrote:
>parse_hostcond() uses get_u32() to parse the vsock port into the
>aafilter.port field, which is a long. On 64-bit systems, get_u32()
>only writes the lower 32 bits, leaving the upper 32 bits set from
>the -1 initialization. This causes the port comparison
>"a->port != s->rport" in run_ssfilter() to always fail, since the
>corrupted long value never matches the int rport.
>
>Fix by using get_long() instead, consistent with how AF_PACKET and
>AF_NETLINK handle the same field.
>
>Fixes: c759116a0b2b ("ss: add AF_VSOCK support")
>Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
>---
Apparently this fixes `sport` but breaks `dport` filtering.
Will send a v2. Please ignore this patch.
Luigi
^ permalink raw reply
* Re: [PATCH iproute2] ss: fix vsock port filter
From: Stefano Garzarella @ 2026-04-21 14:07 UTC (permalink / raw)
To: Luigi Leonardi; +Cc: stefanha, netdev
In-Reply-To: <20260421-fix_vsock-v1-1-812c80a76c1a@redhat.com>
On Tue, Apr 21, 2026 at 02:35:12PM +0200, Luigi Leonardi wrote:
>parse_hostcond() uses get_u32() to parse the vsock port into the
>aafilter.port field, which is a long. On 64-bit systems, get_u32()
>only writes the lower 32 bits, leaving the upper 32 bits set from
>the -1 initialization. This causes the port comparison
>"a->port != s->rport" in run_ssfilter() to always fail, since the
>corrupted long value never matches the int rport.
>
>Fix by using get_long() instead, consistent with how AF_PACKET and
>AF_NETLINK handle the same field.
>
>Fixes: c759116a0b2b ("ss: add AF_VSOCK support")
Can this more related to commit 012cb515 ("ss: change aafilter port from
int to long (inode support)") ?
I don't know this code at all, just asking.
Stefano
>Signed-off-by: Luigi Leonardi <leonardi@redhat.com>
>---
> misc/ss.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/misc/ss.c b/misc/ss.c
>index 14e9f27a..6e3321ac 100644
>--- a/misc/ss.c
>+++ b/misc/ss.c
>@@ -2323,7 +2323,7 @@ void *parse_hostcond(char *addr, bool is_port)
> port = find_port(addr, is_port);
>
> if (port && strcmp(port, "*") &&
>- get_u32((__u32 *)&a.port, port, 0))
>+ get_long(&a.port, port, 0))
> return NULL;
>
> if (!is_port && addr[0] && strcmp(addr, "*")) {
>
>---
>base-commit: e0517e612199cacaf2dc4d54cbed52deec640c94
>change-id: 20260421-fix_vsock-40c2ef4928aa
>
>Best regards,
>--
>Luigi Leonardi <leonardi@redhat.com>
>
^ permalink raw reply
* Re: Path forward for NFC in the kernel
From: Jakub Kicinski @ 2026-04-21 14:10 UTC (permalink / raw)
To: David Heidelberg
Cc: Krzysztof Kozlowski, Michael Thalmeier, Raymond Hackley,
Michael Walle, Bongsu Jeon, Mark Greer, netdev
In-Reply-To: <1725ea8d-ac1f-49d2-8d8c-2e09721454c2@ixit.cz>
On Fri, 17 Apr 2026 10:12:22 +0200 David Heidelberg wrote:
> > +Cc David Heidelberg recently trying to use Linux NFC stack,
> >
> > Just "collecting" patches is not a big deal, I could do this, but
> > actually reviewing the patches with necessary due diligence is the
> > effort I could not provide in a reasonable time frame. And picking up
> > patches without proper review feels risky...
>
> Hello Krzystof, Jakub,
>
> thanks for putting me into loop.
>
> I can do limited reviews and basic maintenance. My knowledge about NFC is for
> now somehow limited (but I'm willing to invest my limited time into learning more).
>
> As "I & LLM" wrote [1] userspace very basic reader for GNOME and planning to do
> more tight integration into GNOME, so would make sense to keep the kernel stack
> alive.
Hi David!
Sorry for the delay, we (core maintainers) discussed the situation
off-list and since our choices are either delete all this code or give
you a chance, everyone agreed that the latter is strictly better :)
It's a little unusual to designate someone who doesn't have a proven
track record acting as a de facto maintainer, but such are the times...
Our expectation would be that:
- you'd create your own tree to gather NFC patches and send us
periodic pull requests every 2 or 3 weeks, with what you gathered
- act upon submissions within 48h of posting (excluding weekends)
Of course we'll happy to provide any support and guidance you need,
specially for the first few months.
Is this what you had in mind? The phrase "limited reviews and basic
maintenance" is slightly worrying, we assumed it's an expression of
modesty rather than commitment? :)
^ permalink raw reply
* Re: [PATCH] net/intel: Replace manual array size calculation with ARRAY_SIZE
From: Dan Carpenter @ 2026-04-21 14:11 UTC (permalink / raw)
To: Jakub Raczynski
Cc: netdev, kuba, przemyslaw.kitszel, anthony.l.nguyen,
kernel-janitors
In-Reply-To: <20260421114029.2689961-1-j.raczynski@samsung.com>
On Tue, Apr 21, 2026 at 01:40:29PM +0200, Jakub Raczynski wrote:
> There are still places in the code where manual calculation of array size
> exist, but it is good to enforce usage of single macro through the whole
> code as it makes code bit more readable.
>
> Signed-off-by: Jakub Raczynski <j.raczynski@samsung.com>
> ---
> drivers/net/ethernet/intel/i40e/i40e_adminq.h | 2 +-
> drivers/net/ethernet/intel/iavf/iavf_adminq.h | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
> index 1be97a3a86ce..0e7cecd00169 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
> +++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
> @@ -109,7 +109,7 @@ static inline int i40e_aq_rc_to_posix(int aq_ret, int aq_rc)
> -EFBIG, /* I40E_AQ_RC_EFBIG */
> };
>
> - if (!((u32)aq_rc < (sizeof(aq_to_posix) / sizeof((aq_to_posix)[0]))))
> + if (!((u32)aq_rc < ARRAY_SIZE(aq_to_posix)))
This still isn't beautiful. There are so many parens. The !(foo < size)
formulation is weird. The cast is unnnecessary. Better to write it as:
if (aq_rc >= ARRAY_SIZE(aq_to_posix))
return -ERANGE;
> return -ERANGE;
>
> return aq_to_posix[aq_rc];
regards,
dan carpenter
^ permalink raw reply
* Re: [PATCH 03/23] tick/nohz: Make nohz_full parameter optional
From: Waiman Long @ 2026-04-21 14:14 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <875x5kd88d.ffs@tglx>
On 4/21/26 4:32 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> To provide nohz_full tick support, there is a set of tick dependency
>> masks that need to be evaluated on every IRQ and context switch.
> s/IRQ/interrupt/
>
> This is a changelog and not a SMS service.
>> Switching on nohz_full tick support at runtime will be problematic
>> as some of the tick dependency masks may not be properly set causing
>> problem down the road.
> That's useless blurb with zero content.
>
>> Allow nohz_full boot option to be specified without any
>> parameter to force enable nohz_full tick support without any
>> CPU in the tick_nohz_full_mask yet. The context_tracking_key and
>> tick_nohz_full_running flag will be enabled in this case to make
>> tick_nohz_full_enabled() return true.
> I kinda can crystal-ball what you are trying to say here, but that does
> not make it qualified as a proper change log.
>
>> There is still a small performance overhead by force enable nohz_full
>> this way. So it should only be used if there is a chance that some
>> CPUs may become isolated later via the cpuset isolated partition
>> functionality and better CPU isolation closed to nohz_full is desired.
> Why has this key to be enabled on boot if there are no CPUs in the
> isolated mask?
>
> If you want to manage this dynamically at runtime then enable the key
> once CPUs are isolated. Yes, it's more work, but that avoids the "should
> only be used" nonsense and makes this more robust down the road.
OK, I will try to make it fully dynamic. Of course, it will be more work.
Cheers,
Longman
> Thanks,
>
> tglx
>
>
^ permalink raw reply
* Re: [PATCH v4 net] net: ax25: fix integer overflow in ax25_rx_fragment()
From: Jakub Kicinski @ 2026-04-21 14:16 UTC (permalink / raw)
To: Hugh Blemings
Cc: hugh, Paolo Abeni, Mashiro Chen, netdev, linux-hams, horms, davem,
edumazet, Greg KH
In-Reply-To: <e2a47378-9008-45a2-92e3-d1f374b5e766@blemings.org>
On Tue, 21 Apr 2026 18:45:39 +1000 Hugh Blemings wrote:
> We'd hoped to have a period of a few months to do an orderly exit from
> the tree to minimise the impact on the (admittedly small, but non-zero)
> users that build trees/make use of the in kernel support.
Sorry about the CC, I trusted get_maintainer.pl too much, clearly :(
If you only need a few months I'd strongly prefer to delete now.
We are getting multiple "fixes" for this code a day, and if we don't
delete it now we have to process these fixes for 2.5 more months,
until the next merge window. IOW even if we delete now you have
2.5 months until 7.1 is actually released, and of course LTS is
available, too.
^ permalink raw reply
* [PATCH net] net/sched: sch_sfb: annotate data-races in sfb_dump_stats()
From: Eric Dumazet @ 2026-04-21 14:16 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
Eric Dumazet
sfb_dump_stats() only runs with RTNL held,
reading fields that can be changed in qdisc fast path.
Add READ_ONCE()/WRITE_ONCE() annotations.
Alternative would be to acquire the qdisc spinlock, but our long-term
goal is to make qdisc dump operations lockless as much as we can.
tc_sfb_xstats fields don't need to be latched atomically,
otherwise this bug would have been caught earlier.
Fixes: edb09eb17ed8 ("net: sched: do not acquire qdisc spinlock in qdisc/class stats dump")
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_sfb.c | 54 +++++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 01373866212894c57e7de58706ee464879303955..bd5ef561030fea07aed44b958ebf73e02eae04cf 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -130,7 +130,7 @@ static void increment_one_qlen(u32 sfbhash, u32 slot, struct sfb_sched_data *q)
sfbhash >>= SFB_BUCKET_SHIFT;
if (b[hash].qlen < 0xFFFF)
- b[hash].qlen++;
+ WRITE_ONCE(b[hash].qlen, b[hash].qlen + 1);
b += SFB_NUMBUCKETS; /* next level */
}
}
@@ -159,7 +159,7 @@ static void decrement_one_qlen(u32 sfbhash, u32 slot,
sfbhash >>= SFB_BUCKET_SHIFT;
if (b[hash].qlen > 0)
- b[hash].qlen--;
+ WRITE_ONCE(b[hash].qlen, b[hash].qlen - 1);
b += SFB_NUMBUCKETS; /* next level */
}
}
@@ -179,12 +179,12 @@ static void decrement_qlen(const struct sk_buff *skb, struct sfb_sched_data *q)
static void decrement_prob(struct sfb_bucket *b, struct sfb_sched_data *q)
{
- b->p_mark = prob_minus(b->p_mark, q->decrement);
+ WRITE_ONCE(b->p_mark, prob_minus(b->p_mark, q->decrement));
}
static void increment_prob(struct sfb_bucket *b, struct sfb_sched_data *q)
{
- b->p_mark = prob_plus(b->p_mark, q->increment);
+ WRITE_ONCE(b->p_mark, prob_plus(b->p_mark, q->increment));
}
static void sfb_zero_all_buckets(struct sfb_sched_data *q)
@@ -202,11 +202,14 @@ static u32 sfb_compute_qlen(u32 *prob_r, u32 *avgpm_r, const struct sfb_sched_da
const struct sfb_bucket *b = &q->bins[q->slot].bins[0][0];
for (i = 0; i < SFB_LEVELS * SFB_NUMBUCKETS; i++) {
- if (qlen < b->qlen)
- qlen = b->qlen;
- totalpm += b->p_mark;
- if (prob < b->p_mark)
- prob = b->p_mark;
+ u32 b_qlen = READ_ONCE(b->qlen);
+ u32 b_mark = READ_ONCE(b->p_mark);
+
+ if (qlen < b_qlen)
+ qlen = b_qlen;
+ totalpm += b_mark;
+ if (prob < b_mark)
+ prob = b_mark;
b++;
}
*prob_r = prob;
@@ -295,7 +298,8 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (unlikely(sch->q.qlen >= q->limit)) {
qdisc_qstats_overlimit(sch);
- q->stats.queuedrop++;
+ WRITE_ONCE(q->stats.queuedrop,
+ q->stats.queuedrop + 1);
goto drop;
}
@@ -348,7 +352,8 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (unlikely(minqlen >= q->max)) {
qdisc_qstats_overlimit(sch);
- q->stats.bucketdrop++;
+ WRITE_ONCE(q->stats.bucketdrop,
+ q->stats.bucketdrop + 1);
goto drop;
}
@@ -374,7 +379,8 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
if (sfb_rate_limit(skb, q)) {
qdisc_qstats_overlimit(sch);
- q->stats.penaltydrop++;
+ WRITE_ONCE(q->stats.penaltydrop,
+ q->stats.penaltydrop + 1);
goto drop;
}
goto enqueue;
@@ -390,14 +396,17 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
* In either case, we want to start dropping packets.
*/
if (r < (p_min - SFB_MAX_PROB / 2) * 2) {
- q->stats.earlydrop++;
+ WRITE_ONCE(q->stats.earlydrop,
+ q->stats.earlydrop + 1);
goto drop;
}
}
if (INET_ECN_set_ce(skb)) {
- q->stats.marked++;
+ WRITE_ONCE(q->stats.marked,
+ q->stats.marked + 1);
} else {
- q->stats.earlydrop++;
+ WRITE_ONCE(q->stats.earlydrop,
+ q->stats.earlydrop + 1);
goto drop;
}
}
@@ -410,7 +419,8 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
sch->q.qlen++;
increment_qlen(&cb, q);
} else if (net_xmit_drop_count(ret)) {
- q->stats.childdrop++;
+ WRITE_ONCE(q->stats.childdrop,
+ q->stats.childdrop + 1);
qdisc_qstats_drop(sch);
}
return ret;
@@ -599,12 +609,12 @@ static int sfb_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
{
struct sfb_sched_data *q = qdisc_priv(sch);
struct tc_sfb_xstats st = {
- .earlydrop = q->stats.earlydrop,
- .penaltydrop = q->stats.penaltydrop,
- .bucketdrop = q->stats.bucketdrop,
- .queuedrop = q->stats.queuedrop,
- .childdrop = q->stats.childdrop,
- .marked = q->stats.marked,
+ .earlydrop = READ_ONCE(q->stats.earlydrop),
+ .penaltydrop = READ_ONCE(q->stats.penaltydrop),
+ .bucketdrop = READ_ONCE(q->stats.bucketdrop),
+ .queuedrop = READ_ONCE(q->stats.queuedrop),
+ .childdrop = READ_ONCE(q->stats.childdrop),
+ .marked = READ_ONCE(q->stats.marked),
};
st.maxqlen = sfb_compute_qlen(&st.maxprob, &st.avgprob, q);
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
* Re: [EXTERNAL] Re: [PATCH net v2] hv_sock: Report EOF instead of -EIO for FIN
From: Jakub Kicinski @ 2026-04-21 14:18 UTC (permalink / raw)
To: Stefano Garzarella
Cc: Dexuan Cui, patchwork-bot+netdevbpf@kernel.org, KY Srinivasan,
Haiyang Zhang, wei.liu@kernel.org, Long Li, davem@davemloft.net,
edumazet@google.com, pabeni@redhat.com, horms@kernel.org,
niuxuewei.nxw@antgroup.com, linux-hyperv@vger.kernel.org,
virtualization@lists.linux.dev, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org, Ben Hillis,
levymitchell0@gmail.com
In-Reply-To: <CAGxU2F6DVcLDLg3dT5DsDmsaOuhOcD+4VSG5dqXcFRwsN1NZ+A@mail.gmail.com>
On Tue, 21 Apr 2026 09:28:19 +0200 Stefano Garzarella wrote:
> > I'm sorry -- I just posted v3
> > https://lore.kernel.org/linux-hyperv/20260421025950.1099495-1-decui@microsoft.com/T/#u
> > and then I realized that the v2 had been merged into the main branch :-(
> >
> > Should I post a new delta patch(with a Fixes tag against the v2) based on the main branch?
>
> Ehm, I'm not sure about the process but if it's merged in net tree,
> maybe we need a follow up patch.
>
> Anyway, let's wait for Jakub's or other net maintainers' suggestions.
Yes, you have to post an incremental fix
^ permalink raw reply
* Re: [PATCH 05/23] tick: Pass timer tick job to an online HK CPU in tick_cpu_dying()
From: Waiman Long @ 2026-04-21 14:22 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <87zf2wbsli.ffs@tglx>
On 4/21/26 4:55 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> In tick_cpu_dying(), if the dying CPU is the current timekeeper,
>> it has to pass the job over to another CPU. The current code passes
>> it to another online CPU. However, that CPU may not be a timer tick
>> housekeeping CPU. If that happens, another CPU will have to manually
>> take it over again later. Avoid this unnecessary work by directly
>> assigning an online housekeeping CPU.
>>
>> Use READ_ONCE/WRITE_ONCE() to access tick_do_timer_cpu in case the
>> non-HK CPUs may not be in stop machine in the future.
> 'may not be in the future' is yet more handwaving without
> content. Please write your change logs in a way so that people who have
> not spent months on this can follow.
>
>> @@ -394,12 +395,19 @@ int tick_cpu_dying(unsigned int dying_cpu)
>> {
>> /*
>> * If the current CPU is the timekeeper, it's the only one that can
>> - * safely hand over its duty. Also all online CPUs are in stop
>> - * machine, guaranteed not to be idle, therefore there is no
>> + * safely hand over its duty. Also all online housekeeping CPUs are
>> + * in stop machine, guaranteed not to be idle, therefore there is no
>> * concurrency and it's safe to pick any online successor.
>> */
>> - if (tick_do_timer_cpu == dying_cpu)
>> - tick_do_timer_cpu = cpumask_first(cpu_online_mask);
>> + if (READ_ONCE(tick_do_timer_cpu) == dying_cpu) {
>> + unsigned int new_cpu;
>> +
>> + guard(rcu)();
> What's this guard for?
>
>> + new_cpu = cpumask_first_and(cpu_online_mask, housekeeping_cpumask(HK_TYPE_TICK));
> Why has this to use housekeeping_cpumask() and does not use
> tick_nohz_full_mask?
The RCU guard is for accessing the HK_TYPE_TICK(HK_TYPE_KERNEL_NOISE)
cpumask. tick_nohz_full_mask cpumask is actually the inverse of
HK_TYPE_TICK cpumask. Yes, I could use cpumask_first_andnot() with
tick_nohz_full_mask. If we make tick_nohz_full_mask an RCU protected
pointer, we still need the guard.
Cheers,
Longman
^ permalink raw reply
* [PATCH net] net/sched: sch_red: annotate data-races in red_dump_stats()
From: Eric Dumazet @ 2026-04-21 14:23 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
Eric Dumazet
red_dump_stats() only runs with RTNL held,
reading fields that can be changed in qdisc fast path.
Add READ_ONCE()/WRITE_ONCE() annotations.
Alternative would be to acquire the qdisc spinlock, but our long-term
goal is to make qdisc dump operations lockless as much as we can.
tc_red_xstats fields don't need to be latched atomically,
otherwise this bug would have been caught earlier.
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>
---
net/sched/sch_red.c | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index c8d3d09f15e3919d6468964561130bfc79fb215b..432b8a3000a57b4688b3ddb5501f604d5752c67c 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -90,17 +90,20 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
case RED_PROB_MARK:
qdisc_qstats_overlimit(sch);
if (!red_use_ecn(q)) {
- q->stats.prob_drop++;
+ WRITE_ONCE(q->stats.prob_drop,
+ q->stats.prob_drop + 1);
goto congestion_drop;
}
if (INET_ECN_set_ce(skb)) {
- q->stats.prob_mark++;
+ WRITE_ONCE(q->stats.prob_mark,
+ q->stats.prob_mark + 1);
skb = tcf_qevent_handle(&q->qe_mark, sch, skb, to_free, &ret);
if (!skb)
return NET_XMIT_CN | ret;
} else if (!red_use_nodrop(q)) {
- q->stats.prob_drop++;
+ WRITE_ONCE(q->stats.prob_drop,
+ q->stats.prob_drop + 1);
goto congestion_drop;
}
@@ -111,17 +114,20 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
reason = QDISC_DROP_OVERLIMIT;
qdisc_qstats_overlimit(sch);
if (red_use_harddrop(q) || !red_use_ecn(q)) {
- q->stats.forced_drop++;
+ WRITE_ONCE(q->stats.forced_drop,
+ q->stats.forced_drop + 1);
goto congestion_drop;
}
if (INET_ECN_set_ce(skb)) {
- q->stats.forced_mark++;
+ WRITE_ONCE(q->stats.forced_mark,
+ q->stats.forced_mark + 1);
skb = tcf_qevent_handle(&q->qe_mark, sch, skb, to_free, &ret);
if (!skb)
return NET_XMIT_CN | ret;
} else if (!red_use_nodrop(q)) {
- q->stats.forced_drop++;
+ WRITE_ONCE(q->stats.forced_drop,
+ q->stats.forced_drop + 1);
goto congestion_drop;
}
@@ -135,7 +141,8 @@ static int red_enqueue(struct sk_buff *skb, struct Qdisc *sch,
sch->qstats.backlog += len;
sch->q.qlen++;
} else if (net_xmit_drop_count(ret)) {
- q->stats.pdrop++;
+ WRITE_ONCE(q->stats.pdrop,
+ q->stats.pdrop + 1);
qdisc_qstats_drop(sch);
}
return ret;
@@ -463,9 +470,13 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED,
&hw_stats_request);
}
- st.early = q->stats.prob_drop + q->stats.forced_drop;
- st.pdrop = q->stats.pdrop;
- st.marked = q->stats.prob_mark + q->stats.forced_mark;
+ st.early = READ_ONCE(q->stats.prob_drop) +
+ READ_ONCE(q->stats.forced_drop);
+
+ st.pdrop = READ_ONCE(q->stats.pdrop);
+
+ st.marked = READ_ONCE(q->stats.prob_mark) +
+ READ_ONCE(q->stats.forced_mark);
return gnet_stats_copy_app(d, &st, sizeof(st));
}
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
* Re: [PATCH 04/23] tick/nohz: Allow runtime changes in full dynticks CPUs
From: Waiman Long @ 2026-04-21 14:24 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <87340od7ev.ffs@tglx>
On 4/21/26 4:50 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> Full dynticks can only be enabled if "nohz_full" boot option has been
>> been specified with or without parameter. Any change in the list of
>> nohz_full CPUs have to be reflected in tick_nohz_full_mask. Introduce
>> a new tick_nohz_full_update_cpus() helper that can be called to update
>> the tick_nohz_full_mask at run time. The housekeeping_update() function
>> is modified to call the new helper when the HK_TYPE_KERNEL_NOSIE cpumask
>> is going to be changed.
>>
>> We also need to enable CPU context tracking for those CPUs that
> We need nothing. Use passive voice for change logs as requested in
> documentation.
>
>> are in tick_nohz_full_mask. So remove __init from tick_nohz_init()
>> and ct_cpu_track_user() so that they be called later when an isolated
>> cpuset partition is being created. The __ro_after_init attribute is
>> taken away from context_tracking_key as well.
>>
>> Also add a new ct_cpu_untrack_user() function to reverse the action of
>> ct_cpu_track_user() in case we need to disable the nohz_full mode of
>> a CPU.
>>
>> With nohz_full enabled, the boot CPU (typically CPU 0) will be the
>> tick CPU which cannot be shut down easily. So the boot CPU should not
>> be used in an isolated cpuset partition.
>>
>> With runtime modification of nohz_full CPUs, tick_do_timer_cpu can become
>> TICK_DO_TIMER_NONE. So remove the two TICK_DO_TIMER_NONE WARN_ON_ONCE()
>> checks in tick-sched.c to avoid unnecessary warnings.
> in tick-sched.c? Describe the functions which contain that.
>
>> static inline void tick_nohz_task_switch(void)
>> diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c
>> index 925999de1a28..394e432630a3 100644
>> --- a/kernel/context_tracking.c
>> +++ b/kernel/context_tracking.c
>> @@ -411,7 +411,7 @@ static __always_inline void ct_kernel_enter(bool user, int offset) { }
>> #define CREATE_TRACE_POINTS
>> #include <trace/events/context_tracking.h>
>>
>> -DEFINE_STATIC_KEY_FALSE_RO(context_tracking_key);
>> +DEFINE_STATIC_KEY_FALSE(context_tracking_key);
>> EXPORT_SYMBOL_GPL(context_tracking_key);
>>
>> static noinstr bool context_tracking_recursion_enter(void)
>> @@ -674,9 +674,9 @@ void user_exit_callable(void)
>> }
>> NOKPROBE_SYMBOL(user_exit_callable);
>>
>> -void __init ct_cpu_track_user(int cpu)
>> +void ct_cpu_track_user(int cpu)
>> {
>> - static __initdata bool initialized = false;
>> + static bool initialized;
>>
>> if (cpu == CONTEXT_TRACKING_FORCE_ENABLE) {
>> static_branch_inc(&context_tracking_key);
>> @@ -700,6 +700,15 @@ void __init ct_cpu_track_user(int cpu)
>> initialized = true;
>> }
>>
>> +void ct_cpu_untrack_user(int cpu)
>> +{
>> + if (!per_cpu(context_tracking.active, cpu))
>> + return;
>> +
>> + per_cpu(context_tracking.active, cpu) = false;
>> + static_branch_dec(&context_tracking_key);
>> +}
>> +
> Why is this in a patch which makes tick/nohz related changes? This is a
> preparatory change, so make it that way and do not bury it inside
> something else.
Sure, I will break out the context tracking change into its own patch.
>> +/* Get the new set of run-time nohz CPU list & update accordingly */
>> +void tick_nohz_full_update_cpus(struct cpumask *cpumask)
>> +{
>> + int cpu;
>> +
>> + if (!tick_nohz_full_running) {
>> + pr_warn_once("Full dynticks cannot be enabled without the nohz_full kernel boot parameter!\n");
> That's the result of this enforced enable hackery. Make this work
> properly.
>
>> + return;
>> + }
>> +
>> + /*
>> + * To properly enable/disable nohz_full dynticks for the affected CPUs,
>> + * the new nohz_full CPUs have to be copied to tick_nohz_full_mask and
>> + * ct_cpu_track_user/ct_cpu_untrack_user() will have to be called
>> + * for those CPUs that have their states changed. Those CPUs should be
>> + * in an offline state.
>> + */
>> + for_each_cpu_andnot(cpu, cpumask, tick_nohz_full_mask) {
>> + WARN_ON_ONCE(cpu_online(cpu));
>> + ct_cpu_track_user(cpu);
>> + cpumask_set_cpu(cpu, tick_nohz_full_mask);
>> + }
>> +
>> + for_each_cpu_andnot(cpu, tick_nohz_full_mask, cpumask) {
>> + WARN_ON_ONCE(cpu_online(cpu));
>> + ct_cpu_untrack_user(cpu);
>> + cpumask_clear_cpu(cpu, tick_nohz_full_mask);
>> + }
>> +}
> So this writes to tick_nohz_full_mask while other CPUs can access
> it. That's just wrong and I'm not at all interested in the resulting
> KCSAN warnings.
>
> tick_nohz_full_mask needs to become a RCU protected pointer, which is
> updated once the new mask is established in a separately allocated one.
I will work on that.
Cheers,
Longman
>
> Thanks,
>
> tglx
>
>
^ permalink raw reply
* [PATCH net] net/sched: sch_fq_codel: remove data-races from fq_codel_dump_stats()
From: Eric Dumazet @ 2026-04-21 14:25 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
Eric Dumazet
fq_codel_dump_stats() acquires the qdisc spinlock a bit too late.
Move this acquisition before we fill st.qdisc_stats with live data.
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>
---
net/sched/sch_fq_codel.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c
index 2a3d758f67ab43d17128442fd8b51c6ba7775d52..0664b2f2d6f28041e5250a44fc92311116ae0cf1 100644
--- a/net/sched/sch_fq_codel.c
+++ b/net/sched/sch_fq_codel.c
@@ -585,6 +585,8 @@ static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
};
struct list_head *pos;
+ sch_tree_lock(sch);
+
st.qdisc_stats.maxpacket = q->cstats.maxpacket;
st.qdisc_stats.drop_overlimit = q->drop_overlimit;
st.qdisc_stats.ecn_mark = q->cstats.ecn_mark;
@@ -593,7 +595,6 @@ static int fq_codel_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
st.qdisc_stats.memory_usage = q->memory_usage;
st.qdisc_stats.drop_overmemory = q->drop_overmemory;
- sch_tree_lock(sch);
list_for_each(pos, &q->new_flows)
st.qdisc_stats.new_flows_len++;
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
* Re: [PATCH net] net: ipv6: fix NOREF dst use in seg6 and rpl lwtunnels
From: Simon Horman @ 2026-04-21 14:25 UTC (permalink / raw)
To: Andrea Mayer
Cc: davem, dsahern, edumazet, kuba, pabeni, bigeasy, clrkwllms,
rostedt, david.lebrun, alex.aring, stefano.salsano, netdev,
linux-rt-devel, linux-kernel, stable
In-Reply-To: <20260421094735.20997-1-andrea.mayer@uniroma2.it>
On Tue, Apr 21, 2026 at 11:47:35AM +0200, Andrea Mayer wrote:
> seg6_input_core() and rpl_input() call ip6_route_input() which sets a
> NOREF dst on the skb, then pass it to dst_cache_set_ip6() invoking
> dst_hold() unconditionally.
> On PREEMPT_RT, ksoftirqd is preemptible and a higher-priority task can
> release the underlying pcpu_rt between the lookup and the caching
> through a concurrent FIB lookup on a shared nexthop.
> Simplified race sequence:
>
> ksoftirqd/X higher-prio task (same CPU X)
> ----------- --------------------------------
> seg6_input_core(,skb)/rpl_input(skb)
> dst_cache_get()
> -> miss
> ip6_route_input(skb)
> -> ip6_pol_route(,skb,flags)
> [RT6_LOOKUP_F_DST_NOREF in flags]
> -> FIB lookup resolves fib6_nh
> [nhid=N route]
> -> rt6_make_pcpu_route()
> [creates pcpu_rt, refcount=1]
> pcpu_rt->sernum = fib6_sernum
> [fib6_sernum=W]
> -> cmpxchg(fib6_nh.rt6i_pcpu,
> NULL, pcpu_rt)
> [slot was empty, store succeeds]
> -> skb_dst_set_noref(skb, dst)
> [dst is pcpu_rt, refcount still 1]
>
> rt_genid_bump_ipv6()
> -> bumps fib6_sernum
> [fib6_sernum from W to Z]
> ip6_route_output()
> -> ip6_pol_route()
> -> FIB lookup resolves fib6_nh
> [nhid=N]
> -> rt6_get_pcpu_route()
> pcpu_rt->sernum != fib6_sernum
> [W <> Z, stale]
> -> prev = xchg(rt6i_pcpu, NULL)
> -> dst_release(prev)
> [prev is pcpu_rt,
> refcount 1->0, dead]
>
> dst = skb_dst(skb)
> [dst is the dead pcpu_rt]
> dst_cache_set_ip6(dst)
> -> dst_hold() on dead dst
> -> WARN / use-after-free
>
> For the race to occur, ksoftirqd must be preemptible (PREEMPT_RT without
> PREEMPT_RT_NEEDS_BH_LOCK) and a concurrent task must be able to release
> the pcpu_rt. Shared nexthop objects provide such a path, as two routes
> pointing to the same nhid share the same fib6_nh and its rt6i_pcpu
> entry.
>
> Fix seg6_input_core() and rpl_input() by calling skb_dst_force() after
> ip6_route_input() to force the NOREF dst into a refcounted one before
> caching.
> The output path is not affected as ip6_route_output() already returns a
> refcounted dst.
>
> Fixes: af4a2209b134 ("ipv6: sr: use dst_cache in seg6_input")
> Fixes: a7a29f9c361f ("net: ipv6: add rpl sr tunnel")
> Cc: stable@vger.kernel.org
> Signed-off-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Reviewed-by: Simon Horman <horms@kernel.org>
^ permalink raw reply
* Re: [PATCH 10/23] cpu: Use RCU to protect access of HK_TYPE_TIMER cpumask
From: Waiman Long @ 2026-04-21 14:25 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <87wly0bsh5.ffs@tglx>
On 4/21/26 4:57 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>> As HK_TYPE_TIMER cpumask is going to be changeable at run time, use
>> RCU to protect access to the cpumask.
>>
>> Signed-off-by: Waiman Long <longman@redhat.com>
>> ---
>> kernel/cpu.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/kernel/cpu.c b/kernel/cpu.c
>> index bc4f7a9ba64e..0d02b5d7a7ba 100644
>> --- a/kernel/cpu.c
>> +++ b/kernel/cpu.c
>> @@ -1890,6 +1890,8 @@ int freeze_secondary_cpus(int primary)
>> cpu_maps_update_begin();
>> if (primary == -1) {
>> primary = cpumask_first(cpu_online_mask);
>> +
>> + guard(rcu)();
>> if (!housekeeping_cpu(primary, HK_TYPE_TIMER))
>> primary = housekeeping_any_cpu(HK_TYPE_TIMER);
> housekeeping_cpu() and housekeeping_any_cpu() can operate on two
> different CPU masks once the runtime update is enabled.
>
> Seriously?
Good point, will fix that in the next version.
Cheers,
Longman
^ permalink raw reply
* Re: [PATCH v2 1/2] drm/drm_ras: Add clear-error-counter netlink command to drm_ras
From: Tauro, Riana @ 2026-04-21 14:25 UTC (permalink / raw)
To: Rodrigo Vivi, maarten.lankhorst
Cc: intel-xe, dri-devel, netdev, Zack McKevitt, joonas.lahtinen,
aravind.iddamsetty, anshuman.gupta, simona.vetter, airlied,
pratik.bari, joshua.santosh.ranjan, ashwin.kumar.kulkarni,
shubham.kumar, ravi.kishore.koppuravuri, raag.jadav,
anvesh.bakwad, Jakub Kicinski, Lijo Lazar, Hawking Zhang,
David S. Miller, Paolo Abeni, Eric Dumazet
In-Reply-To: <ee2681bd-5223-4957-b10e-5dbde0c0e974@intel.com>
Hi Maarten
Could you please help with an ack for this patch so we can merge this
through drm-xe-next?
Thanks
Riana
On 4/10/2026 10:51 AM, Tauro, Riana wrote:
> Hi Rodrigo
>
> On 4/9/2026 7:07 PM, Rodrigo Vivi wrote:
>> On Thu, Apr 09, 2026 at 12:51:44PM +0530, Tauro, Riana wrote:
>>> Hi Zack
>>>
>>> Could you please take a look at this patch if applicable to your
>>> usecase.
>>> Please let me know if any
>>> changes are required
>>>
>>> @Rodrigo This is already reviewed by Jakub and Raag.
>>> If there are no opens, can this be merged via drm_misc
>> if we push this to drm-misc-next, it might take a few weeks to propagate
>> back to drm-xe-next. With other work from you and Raag going fast pace
>> on drm-xe-next around this area, I'm afraid it could cause some
>> conflicts.
>>
>> It is definitely fine by me, but another option is to get ack from
>> drm-misc maintainers to get this through drm-xe-next.
>>
>
> Yeah this would be better with the other RAS patches close to merge.
>
> @Maarten Can you please help with an ack if this patch looks good to you?
> This has been reviewed by Jakub from netdev and Raag from intel-xe
> There are no other opens.
>
> Thanks
> Riana
>
>>
>> so, really okay with drm-misc-next?
>>
>>> Thanks
>>> Riana
>>>
>>> On 4/9/2026 1:03 PM, Riana Tauro wrote:
>>>> Introduce a new 'clear-error-counter' drm_ras command to reset the
>>>> counter
>>>> value for a specific error counter of a given node.
>>>>
>>>> The command is a 'do' netlink request with 'node-id' and 'error-id'
>>>> as parameters with no response payload.
>>>>
>>>> Usage:
>>>>
>>>> $ sudo ynl --family drm_ras --do clear-error-counter --json \
>>>> '{"node-id":1, "error-id":1}'
>>>> None
>>>>
>>>> Cc: Jakub Kicinski <kuba@kernel.org>
>>>> Cc: Zack McKevitt <zachary.mckevitt@oss.qualcomm.com>
>>>> Cc: Lijo Lazar <lijo.lazar@amd.com>
>>>> Cc: Hawking Zhang <Hawking.Zhang@amd.com>
>>>> Cc: David S. Miller <davem@davemloft.net>
>>>> Cc: Paolo Abeni <pabeni@redhat.com>
>>>> Cc: Eric Dumazet <edumazet@google.com>
>>>> Signed-off-by: Riana Tauro <riana.tauro@intel.com>
>>>> Reviewed-by: Jakub Kicinski <kuba@kernel.org>
>>>> Reviewed-by: Raag Jadav <raag.jadav@intel.com>
>>>> ---
>>>> Documentation/gpu/drm-ras.rst | 8 +++++
>>>> Documentation/netlink/specs/drm_ras.yaml | 13 ++++++-
>>>> drivers/gpu/drm/drm_ras.c | 43
>>>> +++++++++++++++++++++++-
>>>> drivers/gpu/drm/drm_ras_nl.c | 13 +++++++
>>>> drivers/gpu/drm/drm_ras_nl.h | 2 ++
>>>> include/drm/drm_ras.h | 11 ++++++
>>>> include/uapi/drm/drm_ras.h | 1 +
>>>> 7 files changed, 89 insertions(+), 2 deletions(-)
>>>>
>>>> diff --git a/Documentation/gpu/drm-ras.rst
>>>> b/Documentation/gpu/drm-ras.rst
>>>> index 70b246a78fc8..4636e68f5678 100644
>>>> --- a/Documentation/gpu/drm-ras.rst
>>>> +++ b/Documentation/gpu/drm-ras.rst
>>>> @@ -52,6 +52,8 @@ User space tools can:
>>>> as a parameter.
>>>> * Query specific error counter values with the
>>>> ``get-error-counter`` command, using both
>>>> ``node-id`` and ``error-id`` as parameters.
>>>> +* Clear specific error counters with the ``clear-error-counter``
>>>> command, using both
>>>> + ``node-id`` and ``error-id`` as parameters.
>>>> YAML-based Interface
>>>> --------------------
>>>> @@ -101,3 +103,9 @@ Example: Query an error counter for a given node
>>>> sudo ynl --family drm_ras --do get-error-counter --json
>>>> '{"node-id":0, "error-id":1}'
>>>> {'error-id': 1, 'error-name': 'error_name1', 'error-value': 0}
>>>> +Example: Clear an error counter for a given node
>>>> +
>>>> +.. code-block:: bash
>>>> +
>>>> + sudo ynl --family drm_ras --do clear-error-counter --json
>>>> '{"node-id":0, "error-id":1}'
>>>> + None
>>>> diff --git a/Documentation/netlink/specs/drm_ras.yaml
>>>> b/Documentation/netlink/specs/drm_ras.yaml
>>>> index 79af25dac3c5..e113056f8c01 100644
>>>> --- a/Documentation/netlink/specs/drm_ras.yaml
>>>> +++ b/Documentation/netlink/specs/drm_ras.yaml
>>>> @@ -99,7 +99,7 @@ operations:
>>>> flags: [admin-perm]
>>>> do:
>>>> request:
>>>> - attributes:
>>>> + attributes: &id-attrs
>>>> - node-id
>>>> - error-id
>>>> reply:
>>>> @@ -113,3 +113,14 @@ operations:
>>>> - node-id
>>>> reply:
>>>> attributes: *errorinfo
>>>> + -
>>>> + name: clear-error-counter
>>>> + doc: >-
>>>> + Clear error counter for a given node.
>>>> + The request includes the error-id and node-id of the
>>>> + counter to be cleared.
>>>> + attribute-set: error-counter-attrs
>>>> + flags: [admin-perm]
>>>> + do:
>>>> + request:
>>>> + attributes: *id-attrs
>>>> diff --git a/drivers/gpu/drm/drm_ras.c b/drivers/gpu/drm/drm_ras.c
>>>> index b2fa5ab86d87..d6eab29a1394 100644
>>>> --- a/drivers/gpu/drm/drm_ras.c
>>>> +++ b/drivers/gpu/drm/drm_ras.c
>>>> @@ -26,7 +26,7 @@
>>>> * efficient lookup by ID. Nodes can be registered or unregistered
>>>> * dynamically at runtime.
>>>> *
>>>> - * A Generic Netlink family `drm_ras` exposes two main operations to
>>>> + * A Generic Netlink family `drm_ras` exposes the below operations to
>>>> * userspace:
>>>> *
>>>> * 1. LIST_NODES: Dump all currently registered RAS nodes.
>>>> @@ -37,6 +37,10 @@
>>>> * Returns all counters of a node if only Node ID is provided
>>>> or specific
>>>> * error counters.
>>>> *
>>>> + * 3. CLEAR_ERROR_COUNTER: Clear error counter of a given node.
>>>> + * Userspace must provide Node ID, Error ID.
>>>> + * Clears specific error counter of a node if supported.
>>>> + *
>>>> * Node registration:
>>>> *
>>>> * - drm_ras_node_register(): Registers a new node and assigns
>>>> @@ -66,6 +70,8 @@
>>>> * operation, fetching all counters from a specific node.
>>>> * - drm_ras_nl_get_error_counter_doit(): Implements the
>>>> GET_ERROR_COUNTER doit
>>>> * operation, fetching a counter value from a specific node.
>>>> + * - drm_ras_nl_clear_error_counter_doit(): Implements the
>>>> CLEAR_ERROR_COUNTER doit
>>>> + * operation, clearing a counter value from a specific node.
>>>> */
>>>> static DEFINE_XARRAY_ALLOC(drm_ras_xa);
>>>> @@ -314,6 +320,41 @@ int drm_ras_nl_get_error_counter_doit(struct
>>>> sk_buff *skb,
>>>> return doit_reply_value(info, node_id, error_id);
>>>> }
>>>> +/**
>>>> + * drm_ras_nl_clear_error_counter_doit() - Clear an error counter
>>>> of a node
>>>> + * @skb: Netlink message buffer
>>>> + * @info: Generic Netlink info containing attributes of the request
>>>> + *
>>>> + * Extracts the node ID and error ID from the netlink attributes and
>>>> + * clears the current value.
>>>> + *
>>>> + * Return: 0 on success, or negative errno on failure.
>>>> + */
>>>> +int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,
>>>> + struct genl_info *info)
>>>> +{
>>>> + struct drm_ras_node *node;
>>>> + u32 node_id, error_id;
>>>> +
>>>> + if (!info->attrs ||
>>>> + GENL_REQ_ATTR_CHECK(info,
>>>> DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID) ||
>>>> + GENL_REQ_ATTR_CHECK(info,
>>>> DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID))
>>>> + return -EINVAL;
>>>> +
>>>> + node_id =
>>>> nla_get_u32(info->attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID]);
>>>> + error_id =
>>>> nla_get_u32(info->attrs[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID]);
>>>> +
>>>> + node = xa_load(&drm_ras_xa, node_id);
>>>> + if (!node || !node->clear_error_counter)
>>>> + return -ENOENT;
>>>> +
>>>> + if (error_id < node->error_counter_range.first ||
>>>> + error_id > node->error_counter_range.last)
>>>> + return -EINVAL;
>>>> +
>>>> + return node->clear_error_counter(node, error_id);
>>>> +}
>>>> +
>>>> /**
>>>> * drm_ras_node_register() - Register a new RAS node
>>>> * @node: Node structure to register
>>>> diff --git a/drivers/gpu/drm/drm_ras_nl.c
>>>> b/drivers/gpu/drm/drm_ras_nl.c
>>>> index 16803d0c4a44..dea1c1b2494e 100644
>>>> --- a/drivers/gpu/drm/drm_ras_nl.c
>>>> +++ b/drivers/gpu/drm/drm_ras_nl.c
>>>> @@ -22,6 +22,12 @@ static const struct nla_policy
>>>> drm_ras_get_error_counter_dump_nl_policy[DRM_RAS_
>>>> [DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID] = { .type = NLA_U32, },
>>>> };
>>>> +/* DRM_RAS_CMD_CLEAR_ERROR_COUNTER - do */
>>>> +static const struct nla_policy
>>>> drm_ras_clear_error_counter_nl_policy[DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID
>>>> + 1] = {
>>>> + [DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID] = { .type = NLA_U32, },
>>>> + [DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID] = { .type = NLA_U32, },
>>>> +};
>>>> +
>>>> /* Ops table for drm_ras */
>>>> static const struct genl_split_ops drm_ras_nl_ops[] = {
>>>> {
>>>> @@ -43,6 +49,13 @@ static const struct genl_split_ops
>>>> drm_ras_nl_ops[] = {
>>>> .maxattr = DRM_RAS_A_ERROR_COUNTER_ATTRS_NODE_ID,
>>>> .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DUMP,
>>>> },
>>>> + {
>>>> + .cmd = DRM_RAS_CMD_CLEAR_ERROR_COUNTER,
>>>> + .doit = drm_ras_nl_clear_error_counter_doit,
>>>> + .policy = drm_ras_clear_error_counter_nl_policy,
>>>> + .maxattr = DRM_RAS_A_ERROR_COUNTER_ATTRS_ERROR_ID,
>>>> + .flags = GENL_ADMIN_PERM | GENL_CMD_CAP_DO,
>>>> + },
>>>> };
>>>> struct genl_family drm_ras_nl_family __ro_after_init = {
>>>> diff --git a/drivers/gpu/drm/drm_ras_nl.h
>>>> b/drivers/gpu/drm/drm_ras_nl.h
>>>> index 06ccd9342773..a398643572a5 100644
>>>> --- a/drivers/gpu/drm/drm_ras_nl.h
>>>> +++ b/drivers/gpu/drm/drm_ras_nl.h
>>>> @@ -18,6 +18,8 @@ int drm_ras_nl_get_error_counter_doit(struct
>>>> sk_buff *skb,
>>>> struct genl_info *info);
>>>> int drm_ras_nl_get_error_counter_dumpit(struct sk_buff *skb,
>>>> struct netlink_callback *cb);
>>>> +int drm_ras_nl_clear_error_counter_doit(struct sk_buff *skb,
>>>> + struct genl_info *info);
>>>> extern struct genl_family drm_ras_nl_family;
>>>> diff --git a/include/drm/drm_ras.h b/include/drm/drm_ras.h
>>>> index 5d50209e51db..f2a787bc4f64 100644
>>>> --- a/include/drm/drm_ras.h
>>>> +++ b/include/drm/drm_ras.h
>>>> @@ -58,6 +58,17 @@ struct drm_ras_node {
>>>> int (*query_error_counter)(struct drm_ras_node *node, u32
>>>> error_id,
>>>> const char **name, u32 *val);
>>>> + /**
>>>> + * @clear_error_counter:
>>>> + *
>>>> + * This callback is used by drm_ras to clear a specific error
>>>> counter.
>>>> + * Driver should implement this callback to support clearing
>>>> error counters
>>>> + * of a node.
>>>> + *
>>>> + * Returns: 0 on success, negative error code on failure.
>>>> + */
>>>> + int (*clear_error_counter)(struct drm_ras_node *node, u32
>>>> error_id);
>>>> +
>>>> /** @priv: Driver private data */
>>>> void *priv;
>>>> };
>>>> diff --git a/include/uapi/drm/drm_ras.h b/include/uapi/drm/drm_ras.h
>>>> index 5f40fa5b869d..218a3ee86805 100644
>>>> --- a/include/uapi/drm/drm_ras.h
>>>> +++ b/include/uapi/drm/drm_ras.h
>>>> @@ -41,6 +41,7 @@ enum {
>>>> enum {
>>>> DRM_RAS_CMD_LIST_NODES = 1,
>>>> DRM_RAS_CMD_GET_ERROR_COUNTER,
>>>> + DRM_RAS_CMD_CLEAR_ERROR_COUNTER,
>>>> __DRM_RAS_CMD_MAX,
>>>> DRM_RAS_CMD_MAX = (__DRM_RAS_CMD_MAX - 1)
^ permalink raw reply
* Re: [PATCH net 1/2] net/mlx5e: psp: Fix invalid access on PSP dev registration fail
From: Jakub Kicinski @ 2026-04-21 14:26 UTC (permalink / raw)
To: Cosmin Ratiu
Cc: Boris Pismenny, willemdebruijn.kernel@gmail.com,
andrew+netdev@lunn.ch, daniel.zahka@gmail.com,
davem@davemloft.net, leon@kernel.org, Rahul Rameshbabu,
linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org,
pabeni@redhat.com, Raed Salem, Dragos Tatulea, kees@kernel.org,
Mark Bloch, edumazet@google.com, Tariq Toukan, Saeed Mahameed,
netdev@vger.kernel.org, Gal Pressman
In-Reply-To: <f327ce67e69c27ed971f4ed38f46381cd2f97ec7.camel@nvidia.com>
On Tue, 21 Apr 2026 12:29:13 +0000 Cosmin Ratiu wrote:
> > Sure but why are you leaving the priv->psp struct in place and
> > whatever
> > FS init has been done? IOW if you really want PSP init to not block
> > probe why is mlx5e_psp_register() a void function rather than
> > mlx5e_psp_init() ? Ignoring errors from psp_dev_create()
> > makes no sense to me - what are you protecting from?
> > kmalloc(GFP_KERNEL)
> > failing?
>
> priv->psp and steering at the time of mlx5e_psp_register() is inert
> without the PSP device. Cleaning it on psp_dev_create() failure would
> be weird, it's cleaned up anyway on netdev teardown. The fact that only
> memory allocations can fail inside psp_dev_create() is irrelevant here.
> psp_dev_create() failing shouldn't bring down the whole netdevice, so
> logging a message and continuing is ok (which is what is also done for
> macsec and ktls).
This is a misguided cargo cult. Or something motivated by OOT
compatibility. Alex D sometimes tries to do the same thing with Meta
drivers. I don't get it. Of course we want the device to be operational
if some *device* init fails. The compatibility matrix with all device
generations and fw versions could justify that. But continuing init
when a single-page kmalloc failed is pure silliness.
> mlx5e_psp_register() is void because it's called from
> mlx5e_nic_enable() which can't fail, so it really can't do much other
> than complain to dmesg.
>
> But while thinking about this, I suppose we could change the entire PSP
> initialization to happen at the time of the current
> mlx5e_psp_register(), and that would simplify the number of states.
> I will do that in the next planned PSP series for net-next.
>
> Meanwhile, could you please take the 2nd patch and leave this one out?
> It should apply with no conflicts by itself.
>
> Or you would like to see a separate submission with the 2nd patch
> alone?
Please resubmit.
^ permalink raw reply
* [PATCH net] net/sched: sch_pie: annotate data-races in pie_dump_stats()
From: Eric Dumazet @ 2026-04-21 14:29 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
Eric Dumazet
pie_dump_stats() only runs with RTNL held,
reading fields that can be changed in qdisc fast path.
Add READ_ONCE()/WRITE_ONCE() annotations.
Alternative would be to acquire the qdisc spinlock, but our long-term
goal is to make qdisc dump operations lockless as much as we can.
tc_pie_xstats fields don't need to be latched atomically,
otherwise this bug would have been caught earlier.
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>
---
include/net/pie.h | 2 +-
net/sched/sch_pie.c | 38 +++++++++++++++++++-------------------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/include/net/pie.h b/include/net/pie.h
index 01cbc66825a40bd21c0a044b1180cbbc346785df..1f3db0c355149b41823a891c9156cac625122031 100644
--- a/include/net/pie.h
+++ b/include/net/pie.h
@@ -104,7 +104,7 @@ static inline void pie_vars_init(struct pie_vars *vars)
vars->dq_tstamp = DTIME_INVALID;
vars->accu_prob = 0;
vars->dq_count = DQCOUNT_INVALID;
- vars->avg_dq_rate = 0;
+ WRITE_ONCE(vars->avg_dq_rate, 0);
}
static inline struct pie_skb_cb *get_pie_cb(const struct sk_buff *skb)
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index 16f3f629cb8e4be71431f7e50a278e3c7fdba8d0..fb53fbf0e328571be72b66ba4e75a938e1963422 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -90,7 +90,7 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
bool enqueue = false;
if (unlikely(qdisc_qlen(sch) >= sch->limit)) {
- q->stats.overlimit++;
+ WRITE_ONCE(q->stats.overlimit, q->stats.overlimit + 1);
goto out;
}
@@ -104,7 +104,7 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
/* If packet is ecn capable, mark it if drop probability
* is lower than 10%, else drop it.
*/
- q->stats.ecn_mark++;
+ WRITE_ONCE(q->stats.ecn_mark, q->stats.ecn_mark + 1);
enqueue = true;
}
@@ -114,15 +114,15 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
if (!q->params.dq_rate_estimator)
pie_set_enqueue_time(skb);
- q->stats.packets_in++;
+ WRITE_ONCE(q->stats.packets_in, q->stats.packets_in + 1);
if (qdisc_qlen(sch) > q->stats.maxq)
- q->stats.maxq = qdisc_qlen(sch);
+ WRITE_ONCE(q->stats.maxq, qdisc_qlen(sch));
return qdisc_enqueue_tail(skb, sch);
}
out:
- q->stats.dropped++;
+ WRITE_ONCE(q->stats.dropped, q->stats.dropped + 1);
q->vars.accu_prob = 0;
return qdisc_drop_reason(skb, sch, to_free, reason);
}
@@ -267,11 +267,11 @@ void pie_process_dequeue(struct sk_buff *skb, struct pie_params *params,
count = count / dtime;
if (vars->avg_dq_rate == 0)
- vars->avg_dq_rate = count;
+ WRITE_ONCE(vars->avg_dq_rate, count);
else
- vars->avg_dq_rate =
+ WRITE_ONCE(vars->avg_dq_rate,
(vars->avg_dq_rate -
- (vars->avg_dq_rate >> 3)) + (count >> 3);
+ (vars->avg_dq_rate >> 3)) + (count >> 3));
/* If the queue has receded below the threshold, we hold
* on to the last drain rate calculated, else we reset
@@ -381,7 +381,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
if (delta > 0) {
/* prevent overflow */
if (vars->prob < oldprob) {
- vars->prob = MAX_PROB;
+ WRITE_ONCE(vars->prob, MAX_PROB);
/* Prevent normalization error. If probability is at
* maximum value already, we normalize it here, and
* skip the check to do a non-linear drop in the next
@@ -392,7 +392,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
} else {
/* prevent underflow */
if (vars->prob > oldprob)
- vars->prob = 0;
+ WRITE_ONCE(vars->prob, 0);
}
/* Non-linear drop in probability: Reduce drop probability quickly if
@@ -403,7 +403,7 @@ void pie_calculate_probability(struct pie_params *params, struct pie_vars *vars,
/* Reduce drop probability to 98.4% */
vars->prob -= vars->prob / 64;
- vars->qdelay = qdelay;
+ WRITE_ONCE(vars->qdelay, qdelay);
vars->backlog_old = backlog;
/* We restart the measurement cycle if the following conditions are met
@@ -502,21 +502,21 @@ static int pie_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
struct pie_sched_data *q = qdisc_priv(sch);
struct tc_pie_xstats st = {
.prob = q->vars.prob << BITS_PER_BYTE,
- .delay = ((u32)PSCHED_TICKS2NS(q->vars.qdelay)) /
+ .delay = ((u32)PSCHED_TICKS2NS(READ_ONCE(q->vars.qdelay))) /
NSEC_PER_USEC,
- .packets_in = q->stats.packets_in,
- .overlimit = q->stats.overlimit,
- .maxq = q->stats.maxq,
- .dropped = q->stats.dropped,
- .ecn_mark = q->stats.ecn_mark,
+ .packets_in = READ_ONCE(q->stats.packets_in),
+ .overlimit = READ_ONCE(q->stats.overlimit),
+ .maxq = READ_ONCE(q->stats.maxq),
+ .dropped = READ_ONCE(q->stats.dropped),
+ .ecn_mark = READ_ONCE(q->stats.ecn_mark),
};
/* avg_dq_rate is only valid if dq_rate_estimator is enabled */
st.dq_rate_estimating = q->params.dq_rate_estimator;
/* unscale and return dq_rate in bytes per sec */
- if (q->params.dq_rate_estimator)
- st.avg_dq_rate = q->vars.avg_dq_rate *
+ if (st.dq_rate_estimating)
+ st.avg_dq_rate = READ_ONCE(q->vars.avg_dq_rate) *
(PSCHED_TICKS_PER_SEC) >> PIE_SCALE;
return gnet_stats_copy_app(d, &st, sizeof(st));
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
* Re: [PATCH 16/23] genirq/cpuhotplug: Use RCU to protect access of HK_TYPE_MANAGED_IRQ cpumask
From: Waiman Long @ 2026-04-21 14:29 UTC (permalink / raw)
To: Thomas Gleixner, Tejun Heo, Johannes Weiner, Michal Koutný,
Jonathan Corbet, Shuah Khan, Catalin Marinas, Will Deacon,
K. Y. Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Long Li,
Guenter Roeck, Frederic Weisbecker, Paul E. McKenney,
Neeraj Upadhyay, Joel Fernandes, Josh Triplett, Boqun Feng,
Uladzislau Rezki, Steven Rostedt, Mathieu Desnoyers,
Lai Jiangshan, Zqiang, Anna-Maria Behnsen, Ingo Molnar,
Chen Ridong, Peter Zijlstra, Juri Lelli, Vincent Guittot,
Dietmar Eggemann, Ben Segall, Mel Gorman, Valentin Schneider,
K Prateek Nayak, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Simon Horman
Cc: cgroups, linux-doc, linux-kernel, linux-arm-kernel, linux-hyperv,
linux-hwmon, rcu, netdev, linux-kselftest, Costa Shulyupin,
Qiliang Yuan
In-Reply-To: <87qzo8bs9m.ffs@tglx>
On 4/21/26 5:02 AM, Thomas Gleixner wrote:
> On Mon, Apr 20 2026 at 23:03, Waiman Long wrote:
>
>> As HK_TYPE_MANAGED_IRQ cpumask is going to be changeable at run time,
>> use RCU to protect access to the cpumask.
>>
>> To enable the new HK_TYPE_MANAGED_IRQ cpumask to take effect, the
>> following steps can be done.
> Can be done?
>
>> 1) Update the HK_TYPE_MANAGED_IRQ cpumask to take out the newly isolated
>> CPUs and add back the de-isolated CPUs.
>> 2) Tear down the affected CPUs to cause irq_migrate_all_off_this_cpu()
>> to be called on the affected CPUs to migrate the irqs to other
>> HK_TYPE_MANAGED_IRQ housekeeping CPUs.
>> 3) Bring up the previously offline CPUs to invoke
>> irq_affinity_online_cpu() to allow the newly de-isolated CPUs to
>> be used for managed irqs.
> Which previously offline CPUs?
This part should go into another patch.
>
>> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
>> index 2e8072437826..8270c4de260b 100644
>> --- a/kernel/irq/manage.c
>> +++ b/kernel/irq/manage.c
>> @@ -263,6 +263,7 @@ int irq_do_set_affinity(struct irq_data *data, const struct cpumask *mask, bool
>> housekeeping_enabled(HK_TYPE_MANAGED_IRQ)) {
>> const struct cpumask *hk_mask;
>>
>> + guard(rcu)();
>> hk_mask = housekeeping_cpumask(HK_TYPE_MANAGED_IRQ);
>>
>> cpumask_and(tmp_mask, mask, hk_mask);
> How is this hunk related to $Subject?
The subject is actually about using RCU to protect access to
housekeeping cpumask. There are extra info in the commit log that
should go to another patch.
Cheers,
Longman
>
^ permalink raw reply
* Re: [PATCH net-next v6 11/11] net: wangxun: implement pci_error_handlers ops
From: Lukas Wunner @ 2026-04-21 14:33 UTC (permalink / raw)
To: Jiawen Wu
Cc: netdev, Mengyuan Lou, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Richard Cochran, Russell King,
Simon Horman, Michal Swiatkowski, Jacob Keller, Kees Cook,
Joe Damato, Larysa Zaremba, Abdun Nihaal, Breno Leitao
In-Reply-To: <20260326021406.30444-12-jiawenwu@trustnetic.com>
On Thu, Mar 26, 2026 at 10:14:06AM +0800, Jiawen Wu wrote:
> +static pci_ers_result_t wx_io_slot_reset(struct pci_dev *pdev)
> +{
> + struct wx *wx = pci_get_drvdata(pdev);
> + pci_ers_result_t result;
> +
> + if (pci_enable_device_mem(pdev)) {
> + wx_err(wx, "Cannot re-enable PCI device after reset.\n");
> + result = PCI_ERS_RESULT_DISCONNECT;
> + } else {
> + /* make all bar access done before reset. */
> + smp_mb__before_atomic();
> + clear_bit(WX_STATE_DISABLED, wx->state);
> + pci_set_master(pdev);
> + pci_restore_state(pdev);
> + pci_save_state(pdev);
The pci_save_state() is no longer necessary here, please drop it.
See commits a2f1e22390ac and 383d89699c50 for details.
Thanks,
Lukas
^ permalink raw reply
* [PATCH net] net_sched: sch_hhf: annotate data-races in hhf_dump_stats()
From: Eric Dumazet @ 2026-04-21 14:33 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, Jamal Hadi Salim, Jiri Pirko, netdev, eric.dumazet,
Eric Dumazet
hhf_dump_stats() only runs with RTNL held,
reading fields that can be changed in qdisc fast path.
Add 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>
---
net/sched/sch_hhf.c | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index 95e5d9bfd9c8c0cac08e080b8f1e0332e722aa3b..96021f52d835b56339509565ca03fe796593e231 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -198,7 +198,8 @@ static struct hh_flow_state *seek_list(const u32 hash,
return NULL;
list_del(&flow->flowchain);
kfree(flow);
- q->hh_flows_current_cnt--;
+ WRITE_ONCE(q->hh_flows_current_cnt,
+ q->hh_flows_current_cnt - 1);
} else if (flow->hash_id == hash) {
return flow;
}
@@ -226,7 +227,7 @@ static struct hh_flow_state *alloc_new_hh(struct list_head *head,
}
if (q->hh_flows_current_cnt >= q->hh_flows_limit) {
- q->hh_flows_overlimit++;
+ WRITE_ONCE(q->hh_flows_overlimit, q->hh_flows_overlimit + 1);
return NULL;
}
/* Create new entry. */
@@ -234,7 +235,7 @@ static struct hh_flow_state *alloc_new_hh(struct list_head *head,
if (!flow)
return NULL;
- q->hh_flows_current_cnt++;
+ WRITE_ONCE(q->hh_flows_current_cnt, q->hh_flows_current_cnt + 1);
INIT_LIST_HEAD(&flow->flowchain);
list_add_tail(&flow->flowchain, head);
@@ -309,7 +310,7 @@ static enum wdrr_bucket_idx hhf_classify(struct sk_buff *skb, struct Qdisc *sch)
return WDRR_BUCKET_FOR_NON_HH;
flow->hash_id = hash;
flow->hit_timestamp = now;
- q->hh_flows_total_cnt++;
+ WRITE_ONCE(q->hh_flows_total_cnt, q->hh_flows_total_cnt + 1);
/* By returning without updating counters in q->hhf_arrays,
* we implicitly implement "shielding" (see Optimization O1).
@@ -403,7 +404,7 @@ static int hhf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
return NET_XMIT_SUCCESS;
prev_backlog = sch->qstats.backlog;
- q->drop_overlimit++;
+ WRITE_ONCE(q->drop_overlimit, q->drop_overlimit + 1);
/* Return Congestion Notification only if we dropped a packet from this
* bucket.
*/
@@ -686,10 +687,10 @@ static int hhf_dump_stats(struct Qdisc *sch, struct gnet_dump *d)
{
struct hhf_sched_data *q = qdisc_priv(sch);
struct tc_hhf_xstats st = {
- .drop_overlimit = q->drop_overlimit,
- .hh_overlimit = q->hh_flows_overlimit,
- .hh_tot_count = q->hh_flows_total_cnt,
- .hh_cur_count = q->hh_flows_current_cnt,
+ .drop_overlimit = READ_ONCE(q->drop_overlimit),
+ .hh_overlimit = READ_ONCE(q->hh_flows_overlimit),
+ .hh_tot_count = READ_ONCE(q->hh_flows_total_cnt),
+ .hh_cur_count = READ_ONCE(q->hh_flows_current_cnt),
};
return gnet_stats_copy_app(d, &st, sizeof(st));
--
2.54.0.rc2.533.g4f5dca5207-goog
^ permalink raw reply related
* Re: [PATCH net 1/2] net/mlx5e: psp: Fix invalid access on PSP dev registration fail
From: Cosmin Ratiu @ 2026-04-21 14:33 UTC (permalink / raw)
To: kuba@kernel.org
Cc: Boris Pismenny, willemdebruijn.kernel@gmail.com,
andrew+netdev@lunn.ch, daniel.zahka@gmail.com,
davem@davemloft.net, leon@kernel.org,
linux-kernel@vger.kernel.org, edumazet@google.com,
linux-rdma@vger.kernel.org, Rahul Rameshbabu, Raed Salem,
Dragos Tatulea, kees@kernel.org, Mark Bloch, pabeni@redhat.com,
Tariq Toukan, Saeed Mahameed, netdev@vger.kernel.org,
Gal Pressman
In-Reply-To: <20260421072609.4b15e7b9@kernel.org>
On Tue, 2026-04-21 at 07:26 -0700, Jakub Kicinski wrote:
> On Tue, 21 Apr 2026 12:29:13 +0000 Cosmin Ratiu wrote:
> > > Sure but why are you leaving the priv->psp struct in place and
> > > whatever
> > > FS init has been done? IOW if you really want PSP init to not
> > > block
> > > probe why is mlx5e_psp_register() a void function rather than
> > > mlx5e_psp_init() ? Ignoring errors from psp_dev_create()
> > > makes no sense to me - what are you protecting from?
> > > kmalloc(GFP_KERNEL)
> > > failing?
> >
> > priv->psp and steering at the time of mlx5e_psp_register() is inert
> > without the PSP device. Cleaning it on psp_dev_create() failure
> > would
> > be weird, it's cleaned up anyway on netdev teardown. The fact that
> > only
> > memory allocations can fail inside psp_dev_create() is irrelevant
> > here.
> > psp_dev_create() failing shouldn't bring down the whole netdevice,
> > so
> > logging a message and continuing is ok (which is what is also done
> > for
> > macsec and ktls).
>
> This is a misguided cargo cult. Or something motivated by OOT
> compatibility. Alex D sometimes tries to do the same thing with Meta
> drivers. I don't get it. Of course we want the device to be
> operational
> if some *device* init fails. The compatibility matrix with all device
> generations and fw versions could justify that. But continuing init
> when a single-page kmalloc failed is pure silliness.
I am not sure about the wider context, but from the POV of the driver,
it's calling $thing from the kernel which can fail and it needs to do
something about it, either fail the entire netdev bringup or accept
that $thing won't be functional and continue without it. The driver
shouldn't need to know what $thing does inside and how it can fail,
which can change over time. Today it's a kmalloc(), tomorrow it may be
something else. It doesn't and shouldn't matter for the local decision
to continue or not without $thing working.
Isn't this reasonable?
>
> > mlx5e_psp_register() is void because it's called from
> > mlx5e_nic_enable() which can't fail, so it really can't do much
> > other
> > than complain to dmesg.
> >
> > But while thinking about this, I suppose we could change the entire
> > PSP
> > initialization to happen at the time of the current
> > mlx5e_psp_register(), and that would simplify the number of states.
> > I will do that in the next planned PSP series for net-next.
> >
> > Meanwhile, could you please take the 2nd patch and leave this one
> > out?
> > It should apply with no conflicts by itself.
> >
> > Or you would like to see a separate submission with the 2nd patch
> > alone?
>
> Please resubmit.
^ permalink raw reply
* Re: [PATCH net v2 1/1] net: hsr: avoid learning unknown senders for local delivery
From: Haoze Xie @ 2026-04-21 14:39 UTC (permalink / raw)
To: Felix Maurer, Ao Zhou
Cc: netdev, Sebastian Andrzej Siewior, David S . Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Murali Karicheri,
Shaurya Rane, Ingo Molnar, Kees Cook, Yifan Wu, Juefei Pu,
Yuan Tan, Xin Liu, Yuqi Xu, royenheart
In-Reply-To: <adYwjxLBBaLY52Wb@thinkpad>
On 4/8/2026 6:40 PM, Felix Maurer wrote:
> On Sat, Apr 04, 2026 at 07:30:47PM +0800, Ao Zhou wrote:
>> From: Haoze Xie <royenheart@gmail.com>
>>
>> Traffic that is directly addressed to the local HSR/PRP master can be
>> delivered locally without creating a persistent node entry. Learning one
>> node per previously unseen source MAC lets forged sender floods grow
>> node_db until the prune timer catches up.
>>
>> Determine whether a frame is locally exclusive before node lookup and
>> skip learning for unknown senders in that case. When no node state
>> exists, also skip duplicate discard checks that depend on it.
>>
>> This keeps locally-destined traffic reachable while avoiding node table
>> growth from source-MAC floods in both the PRP SAN path and the HSR/PRP
>> tagged sender paths.
>
> I see the problem you are trying to solve here, but I don't think this
> patch provides a significant improvement over the current situation.
> Yes, this will disable learning of new nodes from regular traffic (and
> thereby completely prevent the duplicate discard algorithm from
> working). New nodes would only be learned from supervision frames. But
> nothing prevents a malicious host in the network from spoofing tons of
> supervision frames.
>
> HSR and PRP are supposed to be used in pretty restricted network
> environments, so the whole protocol design doesn't really expect
> malicious actors in the network and doesn't provide good options to
> safeguard against misuse.
>
> IMHO, the only real way to prevent excessive resource use on our side is
> to put a limit on these resources. In this case, limit the size of the
> node table (bonus: make that limit configurable as Paolo suggested).
>
> Thanks,
> Felix
>
I agree and therefore dropped the v2 learning-suppression approach and
reworked the fix toward directly bounding node-table growth in v3 patch.
If the node-table-limit approach in v3 looks acceptable, I can also follow
up later with refinements such as per-device configurability and better
visibility when the table is saturated.
Best regards,
Haoze Xie
>
>> Fixes: f421436a591d ("net/hsr: Add support for the High-availability Seamless Redundancy protocol (HSRv0)")
>> Fixes: 451d8123f897 ("net: prp: add packet handling support")
>> Reported-by: Yifan Wu <yifanwucs@gmail.com>
>> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
>> Co-developed-by: Yuan Tan <yuantan098@gmail.com>
>> Signed-off-by: Yuan Tan <yuantan098@gmail.com>
>> Suggested-by: Xin Liu <bird@lzu.edu.cn>
>> Tested-by: Yuqi Xu <xuyuqiabc@gmail.com>
>> Signed-off-by: Haoze Xie <royenheart@gmail.com>
>> Signed-off-by: Ao Zhou <n05ec@lzu.edu.cn>
>> ---
>> changes in v2:
>> - generalize the fix beyond PRP SAN traffic and cover HSR/PRP tagged sender floods
>> - decide whether learning is needed from local-exclusive delivery instead of protocol-specific SAN checks
>> - use the normal NULL return semantics from hsr_get_node() instead of ERR_PTR-based error plumbing
>> - skip duplicate-discard state checks when no node state exists
>>
>> net/hsr/hsr_forward.c | 23 +++++++++++++----------
>> net/hsr/hsr_framereg.c | 5 ++++-
>> net/hsr/hsr_framereg.h | 2 +-
>> 3 files changed, 18 insertions(+), 12 deletions(-)
>>
>> diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c
>> index aefc9b6936ba..15bd17b4ee17 100644
>> --- a/net/hsr/hsr_forward.c
>> +++ b/net/hsr/hsr_forward.c
>> @@ -403,7 +403,8 @@ static void hsr_deliver_master(struct sk_buff *skb, struct net_device *dev,
>> int res, recv_len;
>>
>> was_multicast_frame = (skb->pkt_type == PACKET_MULTICAST);
>> - hsr_addr_subst_source(node_src, skb);
>> + if (node_src)
>> + hsr_addr_subst_source(node_src, skb);
>> skb_pull(skb, ETH_HLEN);
>> recv_len = skb->len;
>> res = netif_rx(skb);
>> @@ -545,7 +546,7 @@ static void hsr_forward_do(struct hsr_frame_info *frame)
>> /* Don't send frame over port where it has been sent before.
>> * Also for SAN, this shouldn't be done.
>> */
>> - if (!frame->is_from_san &&
>> + if (frame->node_src && !frame->is_from_san &&
>> hsr->proto_ops->register_frame_out &&
>> hsr->proto_ops->register_frame_out(port, frame))
>> continue;
>> @@ -688,21 +689,25 @@ static int fill_frame_info(struct hsr_frame_info *frame,
>> return -EINVAL;
>>
>> memset(frame, 0, sizeof(*frame));
>> + frame->port_rcv = port;
>> frame->is_supervision = is_supervision_frame(port->hsr, skb);
>> if (frame->is_supervision && hsr->redbox)
>> frame->is_proxy_supervision =
>> is_proxy_supervision_frame(port->hsr, skb);
>>
>> + ethhdr = (struct ethhdr *)skb_mac_header(skb);
>> + check_local_dest(port->hsr, skb, frame);
>> +
>> n_db = &hsr->node_db;
>> if (port->type == HSR_PT_INTERLINK)
>> n_db = &hsr->proxy_node_db;
>>
>> frame->node_src = hsr_get_node(port, n_db, skb,
>> - frame->is_supervision, port->type);
>> - if (!frame->node_src)
>> - return -1; /* Unknown node and !is_supervision, or no mem */
>> + frame->is_supervision, port->type,
>> + !frame->is_local_exclusive);
>> + if (!frame->node_src && !frame->is_local_exclusive)
>> + return -1;
>>
>> - ethhdr = (struct ethhdr *)skb_mac_header(skb);
>> frame->is_vlan = false;
>> proto = ethhdr->h_proto;
>>
>> @@ -720,13 +725,10 @@ static int fill_frame_info(struct hsr_frame_info *frame,
>> }
>>
>> frame->is_from_san = false;
>> - frame->port_rcv = port;
>> ret = hsr->proto_ops->fill_frame_info(proto, skb, frame);
>> if (ret)
>> return ret;
>>
>> - check_local_dest(port->hsr, skb, frame);
>> -
>> return 0;
>> }
>>
>> @@ -739,7 +741,8 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port)
>> if (fill_frame_info(&frame, skb, port) < 0)
>> goto out_drop;
>>
>> - hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
>> + if (frame.node_src)
>> + hsr_register_frame_in(frame.node_src, port, frame.sequence_nr);
>> hsr_forward_do(&frame);
>> rcu_read_unlock();
>> /* Gets called for ingress frames as well as egress from master port.
>> diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c
>> index 50996f4de7f9..2bc6f8f154c2 100644
>> --- a/net/hsr/hsr_framereg.c
>> +++ b/net/hsr/hsr_framereg.c
>> @@ -221,7 +221,7 @@ void prp_update_san_info(struct hsr_node *node, bool is_sup)
>> */
>> struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
>> struct sk_buff *skb, bool is_sup,
>> - enum hsr_port_type rx_port)
>> + enum hsr_port_type rx_port, bool learn)
>> {
>> struct hsr_priv *hsr = port->hsr;
>> struct hsr_node *node;
>> @@ -270,6 +270,9 @@ struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
>> san = true;
>> }
>>
>> + if (!learn)
>> + return NULL;
>> +
>> return hsr_add_node(hsr, node_db, ethhdr->h_source, san, rx_port);
>> }
>>
>> diff --git a/net/hsr/hsr_framereg.h b/net/hsr/hsr_framereg.h
>> index c65ecb925734..3d9c88e83090 100644
>> --- a/net/hsr/hsr_framereg.h
>> +++ b/net/hsr/hsr_framereg.h
>> @@ -33,7 +33,7 @@ void hsr_del_self_node(struct hsr_priv *hsr);
>> void hsr_del_nodes(struct list_head *node_db);
>> struct hsr_node *hsr_get_node(struct hsr_port *port, struct list_head *node_db,
>> struct sk_buff *skb, bool is_sup,
>> - enum hsr_port_type rx_port);
>> + enum hsr_port_type rx_port, bool learn);
>> void hsr_handle_sup_frame(struct hsr_frame_info *frame);
>> bool hsr_addr_is_self(struct hsr_priv *hsr, unsigned char *addr);
>> bool hsr_addr_is_redbox(struct hsr_priv *hsr, unsigned char *addr);
>> --
>> 2.53.0
>>
>
^ permalink raw reply
* Re: [PATCH net v2] ipv6: rpl: reserve mac_len headroom when recompressed SRH grows
From: Jakub Kicinski @ 2026-04-21 14:39 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: netdev, linux-kernel, David S. Miller, David Ahern, Eric Dumazet,
Paolo Abeni, Simon Horman, stable
In-Reply-To: <2026042142-vanquish-unhealthy-7a85@gregkh>
On Tue, 21 Apr 2026 15:11:57 +0200 Greg Kroah-Hartman wrote:
> Crap, nope, this is wrong, let me go fix this...
Please honor the 24h between reposts rule on netdev.
Also known as "look at the patch before you send it not on the list" rule.
^ permalink raw reply
* Re: Discuss: Future of AX25, NETROM and ROSE in the kernel ?
From: Steven R. Loomis @ 2026-04-21 14:43 UTC (permalink / raw)
To: Dan Cross; +Cc: hugh, Steve Conklin, Stuart Longland VK4MSL, linux-hams, netdev
In-Reply-To: <CAEoi9W4L3WTVv5Hhiec8D8J=654h-p+Mh_Nd9bbm_cDyardsVA@mail.gmail.com>
So, is an important next step, having a repo with *just* the ham items with its own build structure? because there are a number of other modules in the repo mentioned:
https://github.com/linux-netdev/mod-orphan
--
Steven R. Loomis
K6SPI
> El abr 21, 2026, a las 7:06 a.m., Dan Cross <crossd@gmail.com> escribió:
>
> On Tue, Apr 21, 2026 at 2:28 AM Hugh Blemings <hugh@blemings.org> wrote:
>> Hi All,
>>
>> Just to note in this thread (top posting as it's a bit orthogonal to the
>> rest of this discussion) that events have preceeded us somewhat here
>>
>> A patch just recently submitted removes the AX25, NETROM and ROSE code
>> from the kernel moving it to the mod-orphan sub tree of netdev
>>
>> https://lore.kernel.org/netdev/20260421021824.1293976-1-kuba@kernel.org/T/#u
>
> Wow, that happened much faster than I had anticipated.
>
>> A shame but perhaps inevitable - but I think we have a good plan
>> unfolding to both take care of medium term maintenance of the kernel
>> code (in tree or out as it may be) as well as a move to userspace in the
>> longer term.
>>
>> For the benefit of the netdev readership - we had a thread over in
>> linux-hams on this but that may not have been visible to folks in
>> netdev. TL;DR: we think we have a way forward but appreciate this may
>> not be quick enough to meet the requirements/concerns put forward
>>
>> If we can delay removal, that'd be grand, but appreciate that moment may
>> have passed.
>
> Personally, I think this may actually turn out to be a good thing. If
> nothing else, it's a forcing function for the ham community to get
> serious about providing an implementation that works well, and in the
> short term, an out-of-tree module can keep things working for folks
> while alternatives are investigated and prepared.
>
> I appreciate that folks want to discuss timing, but it doesn't appear
> that there is much else to be done at this point. It would make sense
> to continue discussion of alternatives over on linux-hams, sparing the
> already-overloaded readers of the netdev list from the sordid details.
>
> - Dan C.
> (KZ2X)
^ permalink raw reply
* Re: [PATCH net-next] nfp: fix swapped arguments in nfp_encode_basic_qdr() calls
From: Jakub Kicinski @ 2026-04-21 14:46 UTC (permalink / raw)
To: Alexey Kodanev
Cc: netdev, Simon Horman, Andrew Lunn, David S . Miller, Eric Dumazet,
Paolo Abeni, oss-drivers
In-Reply-To: <20260421085124.147049-1-aleksei.kodanev@bell-sw.com>
On Tue, 21 Apr 2026 08:51:24 +0000 Alexey Kodanev wrote:
> Fixes: 4cb584e0ee7d ("nfp: add CPP access core")
Fixes should be tagged for net, not net-next.
> Signed-off-by: Alexey Kodanev <aleksei.kodanev@bell-sw.com>
> ---
> drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c
> index 79470f198a62..5c1edd143cee 100644
> --- a/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c
> +++ b/drivers/net/ethernet/netronome/nfp/nfpcore/nfp_target.c
> @@ -493,7 +493,7 @@ static int nfp_encode_basic(u64 *addr, int dest_island, int cpp_tgt,
> * the address but we can verify if the existing
> * contents will point to a valid island.
> */
> - return nfp_encode_basic_qdr(*addr, cpp_tgt, dest_island,
> + return nfp_encode_basic_qdr(*addr, dest_island, cpp_tgt,
> mode, addr40, isld1, isld0);
Please add warning prints to the error branches in
nfp_encode_basic_qdr() to help identify the source of failure.
Since this code worked and this is just a safety check there's
a high chance we'll break more than we fix with this.
^ permalink raw reply
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