* Re: [RFC PATCH] xprtrdma: Move long delayed work on system_dfl_long_wq
From: Chuck Lever @ 2026-04-30 15:09 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Marco Crivellari, linux-kernel, linux-nfs, netdev, Tejun Heo,
Lai Jiangshan, Sebastian Andrzej Siewior, Michal Hocko,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
In-Reply-To: <afNvZKtiQPLbi-3F@localhost.localdomain>
On Thu, Apr 30, 2026, at 11:04 AM, Frederic Weisbecker wrote:
> Le Thu, Apr 30, 2026 at 10:05:52AM -0400, Chuck Lever a écrit :
>> Does the patch address a bug (work isn't getting rescheduled at
>> all) or is it merely a minor optimization for certain platforms?
>>
>> What's the user-visible issue that will be improved with this
>> change?
>
> It's not a bug, it's an optimization power-wise and performance-wise
> and also part of a bigger sanity change:
>
> - Long works have no reason to stick to a single CPU. If they are converted to
> be unbound, the scheduler can move them to relevant targets to optimize
> performances and power consumption. Hence the new system_unbound_long_wq.
> The goal is to remove system_long_wq if none of its users rely on locality.
>
> - Using queue_delayed_work() with a bound workqueue doesn't make any sense
> since the target is completely random.
The light dawns (for me). That's what I'd like to see in the commit message.
I don't have any technical objections to the code change.
--
Chuck Lever
^ permalink raw reply
* [PATCH net-next v2 3/3] net: eth: fbnic: Add pma read and write access
From: mike.marciniszyn @ 2026-04-30 15:08 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Heiner Kallweit,
Russell King, Jacob Keller, Mohsin Bashir, Lee Trager,
Andrew Lunn
Cc: mike.marciniszyn, netdev, linux-kernel
In-Reply-To: <20260430150802.3521-1-mike.marciniszyn@gmail.com>
From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>
Document the MDIO interface topology with an ASCII diagram
showing the MAC, PCS (MMD 3), FEC, Separated PMA (MMD 8), and PMD
(MMD 1) blocks and their interconnects. The diagram illustrates how
4 lanes connect the MAC through PCS, FEC, and PMA, then narrow to
2 lanes at the PMD.
The c45 read and write routines are enhanced to support
read and write of the separated PMA for the fbnic.
Co-developed-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Alexander Duyck <alexanderduyck@fb.com>
Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
---
v2:
- no changes
v1: https://lore.kernel.org/all/20260428172810.175077-5-mike.marciniszyn@gmail.com/
drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_mdio.c | 71 ++++++++++++++++++++
2 files changed, 72 insertions(+)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
index 81794bd326e1..64b958df7774 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_csr.h
@@ -805,6 +805,7 @@ enum {
#define FBNIC_CSR_END_PCS 0x10668 /* CSR section delimiter */
#define FBNIC_CSR_START_RSFEC 0x10800 /* CSR section delimiter */
+#define FBNIC_RSFEC_CONTROL(n) (0x10800 + 8 * (n)) /* 0x42000 + 32*n */
/* We have 4 RSFEC engines present in our part, however we are only using 1.
* As such only CCW(0) and NCCW(0) will never be non-zero and the other
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
index a3a072597a2c..7a8727e8f6f2 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
@@ -7,6 +7,25 @@
#include "fbnic.h"
#include "fbnic_netdev.h"
+/* fbnic MDIO Interface Layout
+ *
+ * +-------------------+
+ * | MAC |
+ * +-------------------+
+ * | | | | <-- 25GMII, 50GMII, or CGMII
+ * +-------------------+
+ * MMD 3 | PCS |
+ * +-------------------+
+ * | FEC |
+ * +-------------------+
+ * MMD 8 | Separated PMA |
+ * +-------------------+
+ * | | <-- PMD Service Interface
+ * +-------------------+
+ * MMD 1 | PMD |
+ * +-------------------+
+ */
+
#define DW_VENDOR BIT(15)
#define FBNIC_PCS_VENDOR BIT(9)
#define FBNIC_PCS_ZERO_MASK (DW_VENDOR - FBNIC_PCS_VENDOR)
@@ -111,6 +130,32 @@ fbnic_mdio_read_pcs(struct fbnic_dev *fbd, int addr, int regnum)
return ret;
}
+static int
+fbnic_mdio_read_pma(struct fbnic_dev *fbd, int addr, int regnum)
+{
+ int ret = 0;
+
+ /* We will need access to both PMA instances to get config info */
+ if (addr >= 2)
+ return 0;
+
+ switch (regnum) {
+ case MDIO_PMA_RSFEC_CTRL ... MDIO_PMA_RSFEC_LANE_MAP:
+ ret = fbnic_rd32(fbd, FBNIC_RSFEC_CONTROL(addr) +
+ regnum - MDIO_PMA_RSFEC_CTRL);
+ break;
+ default:
+ ret = fbnic_mdio_ids(MP_FBNIC_XPCS_PMA_100G_ID, regnum);
+ break;
+ }
+
+ dev_dbg(fbd->dev,
+ "SWMII PMA Rd: Addr: %d RegNum: %d Value: 0x%04x\n",
+ addr, regnum, ret);
+
+ return ret;
+}
+
static int
fbnic_mdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum)
{
@@ -122,6 +167,9 @@ fbnic_mdio_read_c45(struct mii_bus *bus, int addr, int devnum, int regnum)
if (devnum == MDIO_MMD_PCS)
return fbnic_mdio_read_pcs(fbd, addr, regnum);
+ if (devnum == MDIO_MMD_SEP_PMA1)
+ return fbnic_mdio_read_pma(fbd, addr, regnum);
+
return 0;
}
@@ -155,6 +203,26 @@ fbnic_mdio_write_pcs(struct fbnic_dev *fbd, int addr, int regnum, u16 val)
fbnic_wr32(fbd, FBNIC_PCS_PAGE(addr) + regnum, val);
}
+static void
+fbnic_mdio_write_pma(struct fbnic_dev *fbd, int addr, int regnum, u16 val)
+{
+ dev_dbg(fbd->dev,
+ "SWMII PMA Wr: Addr: %d RegNum: %d Value: 0x%04x\n",
+ addr, regnum, val);
+
+ if (addr >= 2)
+ return;
+
+ switch (regnum) {
+ case MDIO_PMA_RSFEC_CTRL ... MDIO_PMA_RSFEC_LANE_MAP:
+ fbnic_wr32(fbd, FBNIC_RSFEC_CONTROL(addr) +
+ regnum - MDIO_PMA_RSFEC_CTRL, val);
+ break;
+ default:
+ break;
+ }
+}
+
static int
fbnic_mdio_write_c45(struct mii_bus *bus, int addr, int devnum,
int regnum, u16 val)
@@ -167,6 +235,9 @@ fbnic_mdio_write_c45(struct mii_bus *bus, int addr, int devnum,
if (devnum == MDIO_MMD_PCS)
fbnic_mdio_write_pcs(fbd, addr, regnum, val);
+ if (devnum == MDIO_MMD_SEP_PMA1)
+ fbnic_mdio_write_pma(fbd, addr, regnum, val);
+
return 0;
}
--
2.43.0
^ permalink raw reply related
* [PATCH net-next v2 2/3] net: eth: fbnic: Consolidate register reads for ids and devs
From: mike.marciniszyn @ 2026-04-30 15:08 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Heiner Kallweit,
Russell King, Jacob Keller, Mohsin Bashir, Lee Trager,
Andrew Lunn
Cc: mike.marciniszyn, netdev, linux-kernel
In-Reply-To: <20260430150802.3521-1-mike.marciniszyn@gmail.com>
From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>
Consolidate the register reads for boiler plate registers
to reduce LOC and cleanup pcs reads for DEVS1 to
fetch overrides for reserved bits that the hardware does not
return.
Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
---
v2:
- Restore pcs register read for DEVS2
- read pcs DEVS1 overrides and or into return
v1: https://lore.kernel.org/all/20260428172810.175077-4-mike.marciniszyn@gmail.com/
drivers/net/ethernet/meta/fbnic/fbnic_mdio.c | 64 ++++++++++++--------
1 file changed, 40 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
index 709041f7fc43..a3a072597a2c 100644
--- a/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
+++ b/drivers/net/ethernet/meta/fbnic/fbnic_mdio.c
@@ -11,6 +11,26 @@
#define FBNIC_PCS_VENDOR BIT(9)
#define FBNIC_PCS_ZERO_MASK (DW_VENDOR - FBNIC_PCS_VENDOR)
+static int
+fbnic_mdio_ids(int id, int regnum)
+{
+ /* return correct IDs */
+ switch (regnum) {
+ case MDIO_DEVID1:
+ return id >> 16;
+ case MDIO_DEVID2:
+ return id & 0xffff;
+ case MDIO_DEVS1:
+ return MDIO_DEVS_SEP_PMA1 | MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
+ case MDIO_DEVS2:
+ return 0;
+ case MDIO_STAT2:
+ return MDIO_STAT2_DEVPRST_VAL;
+ }
+
+ return 0;
+}
+
static int
fbnic_mdio_read_pmd(struct fbnic_dev *fbd, int addr, int regnum)
{
@@ -29,18 +49,6 @@ fbnic_mdio_read_pmd(struct fbnic_dev *fbd, int addr, int regnum)
}
switch (regnum) {
- case MDIO_DEVID1:
- ret = MP_FBNIC_XPCS_PMA_100G_ID >> 16;
- break;
- case MDIO_DEVID2:
- ret = MP_FBNIC_XPCS_PMA_100G_ID & 0xffff;
- break;
- case MDIO_DEVS1:
- ret = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
- break;
- case MDIO_STAT2:
- ret = MDIO_STAT2_DEVPRST_VAL;
- break;
case MDIO_PMA_RXDET:
/* If training isn't complete default to 0 */
if (fbd->pmd_state != FBNIC_PMD_SEND_DATA)
@@ -51,6 +59,7 @@ fbnic_mdio_read_pmd(struct fbnic_dev *fbd, int addr, int regnum)
(MDIO_PMD_RXDET_1 / FBNIC_AUI_MODE_R2));
break;
default:
+ ret = fbnic_mdio_ids(MP_FBNIC_XPCS_PMA_100G_ID, regnum);
break;
}
@@ -64,7 +73,7 @@ fbnic_mdio_read_pmd(struct fbnic_dev *fbd, int addr, int regnum)
static int
fbnic_mdio_read_pcs(struct fbnic_dev *fbd, int addr, int regnum)
{
- int ret, offset = 0;
+ int ret, offset = 0, overrides = 0;
/* We will need access to both PCS instances to get config info */
if (addr >= 2)
@@ -75,18 +84,25 @@ fbnic_mdio_read_pcs(struct fbnic_dev *fbd, int addr, int regnum)
return 0;
/* Intercept and return correct ID for PCS */
- if (regnum == MDIO_DEVID1)
- return DW_XPCS_ID >> 16;
- if (regnum == MDIO_DEVID2)
- return DW_XPCS_ID & 0xffff;
- if (regnum == MDIO_DEVS1)
- return MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS;
-
- /* Swap vendor page bit for FBNIC PCS vendor page bit */
- if (regnum & DW_VENDOR)
- offset ^= DW_VENDOR | FBNIC_PCS_VENDOR;
+ switch (regnum) {
+ case MDIO_DEVID1 ... MDIO_DEVID2:
+ ret = fbnic_mdio_ids(DW_XPCS_ID, regnum);
+ break;
+ case MDIO_DEVS1:
+ /* DW IP returns MDIO_DEVS_SEP_PMA1, MDIO_DEVS_PMAPMD,
+ * and MDIO_DEVS_PCS as 0
+ */
+ overrides = fbnic_mdio_ids(DW_XPCS_ID, regnum);
+ fallthrough;
+ default:
+ /* Swap vendor page bit for FBNIC PCS vendor page bit */
+ if (regnum & DW_VENDOR)
+ offset ^= DW_VENDOR | FBNIC_PCS_VENDOR;
- ret = fbnic_rd32(fbd, FBNIC_PCS_PAGE(addr) + (regnum ^ offset));
+ ret = fbnic_rd32(fbd, FBNIC_PCS_PAGE(addr) + (regnum ^ offset));
+ ret |= overrides;
+ break;
+ }
dev_dbg(fbd->dev,
"SWMII PCS Rd: Addr: %d RegNum: %d Value: 0x%04x\n",
--
2.43.0
^ permalink raw reply related
* [PATCH net-next v2 1/3] net: mdio: Add support for RSFEC Control register for PMA
From: mike.marciniszyn @ 2026-04-30 15:08 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Heiner Kallweit,
Russell King, Jacob Keller, Mohsin Bashir, Lee Trager,
Andrew Lunn
Cc: mike.marciniszyn, netdev, linux-kernel
In-Reply-To: <20260430150802.3521-1-mike.marciniszyn@gmail.com>
From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>
Add the constants associated with RS-FEC configuration
and status as well as the indicated separated bits for
DEVS1 to convey a separated PMA.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Mike Marciniszyn (Meta) <mike.marciniszyn@gmail.com>
---
v2:
- Added Reviewed-by
v1: https://lore.kernel.org/all/20260428172810.175077-3-mike.marciniszyn@gmail.com/
- initial revision
include/uapi/linux/mdio.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/uapi/linux/mdio.h b/include/uapi/linux/mdio.h
index 8d769f100de6..b2541c948fc1 100644
--- a/include/uapi/linux/mdio.h
+++ b/include/uapi/linux/mdio.h
@@ -23,6 +23,10 @@
#define MDIO_MMD_DTEXS 5 /* DTE Extender Sublayer */
#define MDIO_MMD_TC 6 /* Transmission Convergence */
#define MDIO_MMD_AN 7 /* Auto-Negotiation */
+#define MDIO_MMD_SEP_PMA1 8 /* Separated PMA (1) */
+#define MDIO_MMD_SEP_PMA2 9 /* Separated PMA (2) */
+#define MDIO_MMD_SEP_PMA3 10 /* Separated PMA (3) */
+#define MDIO_MMD_SEP_PMA4 11 /* Separated PMA (4) */
#define MDIO_MMD_POWER_UNIT 13 /* PHY Power Unit */
#define MDIO_MMD_C22EXT 29 /* Clause 22 extension */
#define MDIO_MMD_VEND1 30 /* Vendor specific 1 */
@@ -63,6 +67,8 @@
* Lanes B-D are numbered 134-136. */
#define MDIO_PMA_10GBR_FSRT_CSR 147 /* 10GBASE-R fast retrain status and control */
#define MDIO_PMA_10GBR_FECABLE 170 /* 10GBASE-R FEC ability */
+#define MDIO_PMA_RSFEC_CTRL 200 /* RSFEC control */
+#define MDIO_PMA_RSFEC_LANE_MAP 206 /* RSFEC lane mapping */
#define MDIO_PCS_10GBX_STAT1 24 /* 10GBASE-X PCS status 1 */
#define MDIO_PCS_10GBRT_STAT1 32 /* 10GBASE-R/-T PCS status 1 */
#define MDIO_PCS_10GBRT_STAT2 33 /* 10GBASE-R/-T PCS status 2 */
@@ -175,6 +181,10 @@
#define MDIO_DEVS_DTEXS MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
#define MDIO_DEVS_TC MDIO_DEVS_PRESENT(MDIO_MMD_TC)
#define MDIO_DEVS_AN MDIO_DEVS_PRESENT(MDIO_MMD_AN)
+#define MDIO_DEVS_SEP_PMA1 MDIO_DEVS_PRESENT(MDIO_MMD_SEP_PMA1)
+#define MDIO_DEVS_SEP_PMA2 MDIO_DEVS_PRESENT(MDIO_MMD_SEP_PMA2)
+#define MDIO_DEVS_SEP_PMA3 MDIO_DEVS_PRESENT(MDIO_MMD_SEP_PMA3)
+#define MDIO_DEVS_SEP_PMA4 MDIO_DEVS_PRESENT(MDIO_MMD_SEP_PMA4)
#define MDIO_DEVS_C22EXT MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
#define MDIO_DEVS_VEND1 MDIO_DEVS_PRESENT(MDIO_MMD_VEND1)
#define MDIO_DEVS_VEND2 MDIO_DEVS_PRESENT(MDIO_MMD_VEND2)
--
2.43.0
^ permalink raw reply related
* [PATCH net-next v2 0/3] first series for xpcs based rsfec configuration
From: mike.marciniszyn @ 2026-04-30 15:07 UTC (permalink / raw)
To: Alexander Duyck, Jakub Kicinski, kernel-team, Andrew Lunn,
David S. Miller, Eric Dumazet, Paolo Abeni, Heiner Kallweit,
Russell King, Jacob Keller, Mohsin Bashir, Lee Trager,
Andrew Lunn
Cc: mike.marciniszyn, netdev, linux-kernel
From: "Mike Marciniszyn (Meta)" <mike.marciniszyn@gmail.com>
The series:
- Fixes an addr validation error
- Adds MDIO defines associated with RS-FEC
- consolidates the handling of the boilerplat ID registers
into a routine to report id'ish registers and reduces the lines
of code across the entire set of c45 routines.
- adds PMA read/write routines
https://lore.kernel.org/all/20260428172810.175077-2-mike.marciniszyn@gmail.com/
has been removed from the series and submitted to net as
https://lore.kernel.org/all/20260429150049.1643-1-mike.marciniszyn@gmail.com/
pcs reads for DEVS1 and DEVS2 cleaned up 2/3
Mike Marciniszyn (Meta) (3):
net: mdio: Add support for RSFEC Control register for PMA
net: eth: fbnic: Consolidate register reads for ids and devs
net: eth: fbnic: Add pma read and write access
drivers/net/ethernet/meta/fbnic/fbnic_csr.h | 1 +
drivers/net/ethernet/meta/fbnic/fbnic_mdio.c | 135 +++++++++++++++----
include/uapi/linux/mdio.h | 10 ++
3 files changed, 122 insertions(+), 24 deletions(-)
--
2.43.0
^ permalink raw reply
* Re: [RFC PATCH] xprtrdma: Move long delayed work on system_dfl_long_wq
From: Frederic Weisbecker @ 2026-04-30 15:04 UTC (permalink / raw)
To: Chuck Lever
Cc: Marco Crivellari, linux-kernel, linux-nfs, netdev, Tejun Heo,
Lai Jiangshan, Sebastian Andrzej Siewior, Michal Hocko,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
In-Reply-To: <1e220a70-4318-49de-aaac-332c0a1cfab4@app.fastmail.com>
Le Thu, Apr 30, 2026 at 10:05:52AM -0400, Chuck Lever a écrit :
>
>
> On Thu, Apr 30, 2026, at 10:01 AM, Frederic Weisbecker wrote:
> > Le Thu, Apr 30, 2026 at 09:35:20AM -0400, Chuck Lever a écrit :
> >>
> >> On Thu, Apr 30, 2026, at 4:54 AM, Marco Crivellari wrote:
> >> > Currently the code enqueue work items using {queue|mod}_delayed_work(),
> >> > using system_long_wq. This workqueue should be used when long works are
> >> > expected, but it is a per-cpu workqueue.
> >> >
> >> > This is important because queue_delayed_work() queue the work using:
> >> >
> >> > queue_delayed_work_on(WORK_CPU_UNBOUND, ...);
> >> >
> >> > Note that WORK_CPU_UNBOUND = NR_CPUS.
> >> >
> >> > This would end up calling __queue_delayed_work() that does:
> >> >
> >> > if (housekeeping_enabled(HK_TYPE_TIMER)) {
> >> > // [....]
> >> > } else {
> >> > if (likely(cpu == WORK_CPU_UNBOUND))
> >> > add_timer_global(timer);
> >> > else
> >> > add_timer_on(timer, cpu);
> >> > }
> >> >
> >> > So when cpu == WORK_CPU_UNBOUND the timer is global and is
> >> > not using a specific CPU. Later, when __queue_work() is called:
> >> >
> >> > if (req_cpu == WORK_CPU_UNBOUND) {
> >> > if (wq->flags & WQ_UNBOUND)
> >> > cpu = wq_select_unbound_cpu(raw_smp_processor_id());
> >> > else
> >> > cpu = raw_smp_processor_id();
> >> > }
> >> >
> >> > Because the wq is not unbound, it takes the CPU where the timer
> >> > fired and enqueue the work on that CPU.
> >> > The consequence of all of this is that the work can run anywhere,
> >> > depending on where the timer fired.
> >> >
> >> > Recently, a new unbound workqueue specific for long running work has
> >> > been added:
> >> >
> >> > c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")
> >> >
> >> > So change system_long_wq with system_dfl_long_wq so that the work may
> >> > benefit from scheduler task placement.
> >>
> >> The patch description confuses me.
> >>
> >> The message ends with "the work can run anywhere, depending on where
> >> the timer fired." Read literally, "can run anywhere" sounds like a
> >> feature, not a bug
> >
> > A feature, but incomplete :)
> >
> >> — and the proposed fix (WQ_UNBOUND) also lets it
> >> run anywhere, just via a different selection path. Without a sentence
> >> saying "and that anywhere includes isolated CPUs, which we don't want,"
> >> the reader is left to fill in the gap.
> >
> > Not quite, global timers don't fire on isolated CPUs. And since it gets enqueued
> > on the CPU where it fired, it won't be enqueued on an isolated CPU.
> >
> >>
> >> So, could the commit message lead with the motivation? My guess is that
> >> this is about respecting HK_TYPE_TIMER housekeeping on isolated systems,
> >> which system_long_wq cannot do because its per-CPU pool ignores the
> >> housekeeping mask once the global timer fires. If that is the case,
> >> please say so directly and the mechanism trace becomes a supporting
> >> argument rather than the whole argument.
> >
> > The purpose is explained on the last line:
> >
> > """
> > So change system_long_wq with system_dfl_long_wq so that the work may
> > benefit from scheduler task placement.
> > """
> >
> > Arguably this could be elaborated. For example we can change that:
> >
> > """
> > The consequence of all of this is that the work can run anywhere,
> > depending on where the timer fired.
> > """
> >
> > into that:
> >
> > """
> > The consequence of all of this is that the work can run on any
> > housekeeping CPU, irrespective of the scheduler that knows better
> > about the best task placement, which would apply if the work were
> > to be queued on an unbound workqueue.
> > """
> >
> > Would that help?
>
> It's still not clearing it up for me.
>
> Does the patch address a bug (work isn't getting rescheduled at
> all) or is it merely a minor optimization for certain platforms?
>
> What's the user-visible issue that will be improved with this
> change?
It's not a bug, it's an optimization power-wise and performance-wise
and also part of a bigger sanity change:
- Long works have no reason to stick to a single CPU. If they are converted to
be unbound, the scheduler can move them to relevant targets to optimize
performances and power consumption. Hence the new system_unbound_long_wq.
The goal is to remove system_long_wq if none of its users rely on locality.
- Using queue_delayed_work() with a bound workqueue doesn't make any sense
since the target is completely random.
Thanks.
--
Frederic Weisbecker
SUSE Labs
^ permalink raw reply
* Transaction Overview – File Attached for Reference
From: ysaminushawai @ 2026-04-30 15:02 UTC (permalink / raw)
To: netdev
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 545 bytes --]
Dear Valued Customer,
We’ve detected unusual activity on your PayPal, Inc. account and want to ensure your account remains secure.
Transaction Details:
• Transaction ID: 641029-9798
• Amount: $492.45
Need Help?
Our dedicated support team is here to assist you:
📞 (802)-278-0978 (Available 24/7)
📧 security@PayPal, Inc..com
For your security, we recommend:
✓ Enabling two-factor authentication
✓ Monitoring your account regularly
Thank you for your prompt attention to this matter.
Sincerely,
The PayPal, Inc. Security Team
^ permalink raw reply
* Re: [PATCH net-next 0/2] dpll: rework fractional frequency offset reporting
From: Ivan Vecera @ 2026-04-30 14:58 UTC (permalink / raw)
To: netdev
Cc: Andrew Lunn, Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
Leon Romanovsky, Mark Bloch, Michal Schmidt, Paolo Abeni,
Pasi Vaananen, Petr Oros, Prathosh Satish, Saeed Mahameed,
Shuah Khan, Simon Horman, Tariq Toukan, Vadim Fedorenko,
linux-doc, linux-kernel, linux-rdma
In-Reply-To: <20260429150817.3059763-1-ivecera@redhat.com>
On 4/29/26 5:08 PM, Ivan Vecera wrote:
> Rework how the fractional frequency offset (FFO) is reported in
> the DPLL subsystem.
>
> The fractional-frequency-offset-ppt attribute is moved from the
> top-level pin attributes into the pin-parent-device nested attribute
> set. This makes it consistent with phase-offset (which is already
> per-parent) and clarifies that FFO PPT represents the frequency
> difference between a pin and its parent DPLL device.
>
> The two FFO contexts are distinguished in the ffo_get callback:
> dpll=NULL for the top-level RX vs TX symbol rate offset and a valid
> dpll pointer for the nested pin vs DPLL offset.
>
> Patch 1 restructures the DPLL subsystem netlink handling, updates
> the YAML spec and driver-api documentation, and adds NULL guards
> to mlx5 and zl3073x drivers.
>
> Patch 2 implements the nested FFO for zl3073x using the
> dpll_df_offset_x register with ref_ofst=1, providing 2^-48
> resolution. The old per-reference frequency measurement is removed
> as it was redundant with measured-frequency.
>
> Ivan Vecera (2):
> dpll: move fractional-frequency-offset-ppt under pin-parent-device
> dpll: zl3073x: report FFO as DPLL vs input reference offset
>
> Documentation/driver-api/dpll.rst | 16 +++++++
> Documentation/netlink/specs/dpll.yaml | 11 +++--
> drivers/dpll/dpll_netlink.c | 34 ++++++++++----
> drivers/dpll/dpll_nl.c | 1 +
> drivers/dpll/zl3073x/chan.c | 31 ++++++++++++-
> drivers/dpll/zl3073x/chan.h | 14 ++++++
> drivers/dpll/zl3073x/core.c | 45 -------------------
> drivers/dpll/zl3073x/dpll.c | 34 +++++++-------
> drivers/dpll/zl3073x/ref.h | 14 ------
> drivers/dpll/zl3073x/regs.h | 15 +++++++
> .../net/ethernet/mellanox/mlx5/core/dpll.c | 4 ++
> 11 files changed, 126 insertions(+), 93 deletions(-)
After merge of "dpll: add pin operational state" this needs to be rebased...
Will send v2.
I.
^ permalink raw reply
* Re: [PATCH net] net: phy: micrel: fix LAN8814 QSGMII soft reset
From: Andrew Lunn @ 2026-04-30 14:49 UTC (permalink / raw)
To: Paolo Abeni
Cc: Robert Marko, hkallweit1, linux, davem, edumazet, kuba,
Divya.Koppera, horatiu.vultur, netdev, linux-kernel
In-Reply-To: <0060104c-bb38-45d5-8f8e-14708702feac@redhat.com>
> > @@ -4548,6 +4548,13 @@ static int lan8814_config_init(struct phy_device *phydev)
> > struct kszphy_priv *lan8814 = phydev->priv;
> > int ret;
> >
> > + if (phy_package_init_once(phydev))
> > + /* Reset the PHY */
> > + lanphy_modify_page_reg(phydev, LAN8814_PAGE_COMMON_REGS,
> > + LAN8814_QSGMII_SOFT_RESET,
> > + LAN8814_QSGMII_SOFT_RESET_BIT,
> > + LAN8814_QSGMII_SOFT_RESET_BIT)
>
> Sashiko says:
>
> ---
> Could this introduce a race condition if multiple ports are brought up
> concurrently?
> Because phy_package_init_once() does not provide a synchronization
> barrier for followers, they might proceed immediately to configure their
> registers while the leader is still performing the reset.
> ---
>
> on top of my head IDK if such race is possible at all.
config_init() is called from phy_init_hw(). That is called from
mdio_bus_phy_resume() and phy_attach_direct().
It seems unlikely resumes of devices on one bus is done in parallel,
same as probing of devices on one bus is not performed in parallel.
phy_attach_direct() is either used in the MAC drivers probe() or
open(). Again, probe should not be running in parallel especially
since this PHY is likely connect to a switch, and the ports are
created sequentially by the DSA core. open() should be protected by
RTNL.
So it seems unlikely to me.
lanphy_modify_page_reg() also takes the MDIO bus lock. That will
prevent any other MDIO operations being performed in parallel. This
does however make the assumption the software reset can be performed
within one MDIO bus cycle.
So a race here seems pretty theoretical to me.
Andrew
^ permalink raw reply
* Re: [PATCH 0/5] ice: five small fixes and cleanups
From: Jakub Kicinski @ 2026-04-30 14:48 UTC (permalink / raw)
To: Aleksandr Loktionov; +Cc: intel-wired-lan, anthony.l.nguyen, netdev
In-Reply-To: <20260430122602.126722-1-aleksandr.loktionov@intel.com>
On Thu, 30 Apr 2026 14:25:57 +0200 Aleksandr Loktionov wrote:
> Subject: [PATCH 0/5] ice: five small fixes and cleanups
Please tag your submissions with iwl-* if you are cross posting.
--
pw-bot: au
^ permalink raw reply
* Re: [PATCH iwl-next v4 0/3] igc: add support for forcing link speed without autonegotiation
From: David Laight @ 2026-04-30 14:41 UTC (permalink / raw)
To: KhaiWenTan
Cc: anthony.l.nguyen, andrew+netdev, davem, edumazet, kuba, pabeni,
intel-wired-lan, netdev, linux-kernel, faizal.abdul.rahim,
hong.aun.looi, khai.wen.tan, Faizal Rahim
In-Reply-To: <20260428060009.311393-1-khai.wen.tan@linux.intel.com>
On Tue, 28 Apr 2026 14:00:06 +0800
KhaiWenTan <khai.wen.tan@linux.intel.com> wrote:
> From: Faizal Rahim <faizal.abdul.rahim@linux.intel.com>
>
> This series adds support for forcing 10/100 Mb/s link speed via ethtool
> when autonegotiation is disabled on the igc driver.
I'll ask 'why' ?
In particular forcing half/full duplex has always been a very good way
of 'breaking' a network connection.
It really is much better to restrict the advertised link modes and let
the autodetect/autonegotiation logic in the phy/mac do its job.
About the only think I can think of is to force 10M HDX when connected
to a remote system that supports 10M/100M HDX.
In that case you need to send out single link test pulses, not the
burst used to identify 100M HDX, or the pattern encoded on the burst
used by autonegotiation.
But you need to got back to the mid 1990s to find such systems.
Anything that supports FDX will do autonegotiation.
David
>
> Changes in v4:
> - Validate that autoneg is AUTONEG_ENABLE or AUTONEG_DISABLE early
> in igc_ethtool_set_link_ksettings() to avoid passing unexpected
> values to igc_handle_autoneg_disabled(). (Simon Horman)
>
> Changes in v3:
> - Modify condition from "if (duplex == DUPLEX_HALF)" to
> "if (duplex != DUPLEX_FULL)". (Simon Horman)
>
> Changes in v2:
> - When forcing half-duplex, set hw->fc.requested_mode = igc_fc_none,
> since half-duplex cannot support flow control per IEEE 802.3.
> (Simon Horman)
> - Split the original single patch into three patches for clarity:
> patches 1 and 2 are preparatory cleanups; patch 3 carries the
> functional change.
>
> v3 at:
> https://patchwork.ozlabs.org/project/intel-wired-lan/cover/20260422155701.7420-1-khai.wen.tan@linux.intel.com/
>
> v2 at:
> https://patchwork.kernel.org/project/netdevbpf/patch/20260416015520.6090-4-khai.wen.tan@linux.intel.com/
>
> v1 at:
> https://patchwork.ozlabs.org/project/intel-wired-lan/patch/20260409072747.217836-1-khai.wen.tan@linux.intel.com/
>
> Faizal Rahim (3):
> igc: remove unused autoneg_failed field
> igc: move autoneg-enabled settings into igc_handle_autoneg_enabled()
> igc: add support for forcing link speed without autonegotiation
>
> drivers/net/ethernet/intel/igc/igc_base.c | 35 +++-
> drivers/net/ethernet/intel/igc/igc_defines.h | 9 +-
> drivers/net/ethernet/intel/igc/igc_ethtool.c | 209 +++++++++++++------
> drivers/net/ethernet/intel/igc/igc_hw.h | 10 +-
> drivers/net/ethernet/intel/igc/igc_mac.c | 16 +-
> drivers/net/ethernet/intel/igc/igc_main.c | 2 +-
> drivers/net/ethernet/intel/igc/igc_phy.c | 65 +++++-
> drivers/net/ethernet/intel/igc/igc_phy.h | 1 +
> 8 files changed, 257 insertions(+), 90 deletions(-)
>
> --
> 2.43.0
>
>
^ permalink raw reply
* Re: [PATCH net-next 0/2] dpll: add pin operational state
From: patchwork-bot+netdevbpf @ 2026-04-30 14:30 UTC (permalink / raw)
To: Ivan Vecera
Cc: netdev, arkadiusz.kubalewski, davem, donald.hunter, edumazet,
kuba, jiri, corbet, mschmidt, pabeni, pvaanane, poros,
Prathosh.Satish, skhan, horms, vadim.fedorenko, linux-doc,
linux-kernel
In-Reply-To: <20260428154907.2820654-1-ivecera@redhat.com>
Hello:
This series was applied to netdev/net-next.git (main)
by Paolo Abeni <pabeni@redhat.com>:
On Tue, 28 Apr 2026 17:49:05 +0200 you wrote:
> Add pin operational state (operstate) to the DPLL subsystem to
> separate administrative intent from actual hardware status.
>
> Currently pin-state mixes what the user requested (connected,
> selectable, disconnected) with what the hardware is actually doing.
> This makes it difficult to diagnose situations where a user sets
> a pin as selectable or connected but the hardware cannot use it
> due to signal issues.
>
> [...]
Here is the summary with links:
- [net-next,1/2] dpll: add pin operational state
https://git.kernel.org/netdev/net-next/c/781c8893a5da
- [net-next,2/2] dpll: zl3073x: implement pin operational state reporting
https://git.kernel.org/netdev/net-next/c/c53f8f8dce77
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH v1 11/11] drm/xe/ras: Add flag for Xe RAS
From: Tauro, Riana @ 2026-04-30 14:24 UTC (permalink / raw)
To: Raag Jadav, intel-xe, dri-devel, netdev
Cc: simona.vetter, airlied, kuba, lijo.lazar, Hawking.Zhang, davem,
pabeni, edumazet, maarten, zachary.mckevitt, rodrigo.vivi,
michal.wajdeczko, matthew.d.roper, umesh.nerlige.ramappa,
mallesh.koujalagi, soham.purkait, anoop.c.vijay,
aravind.iddamsetty
In-Reply-To: <20260417211730.837345-12-raag.jadav@intel.com>
On 4/18/2026 2:46 AM, Raag Jadav wrote:
> From: Riana Tauro <riana.tauro@intel.com>
>
> Add a flag for RAS. If enabled, XE driver registers with
> drm_ras and exposes supported counters.
>
> Currently this is enabled for PVC and CRI.
Can you please replace this with the latest
patch in the next rev [PATCH v4 6/6] drm/xe/xe_ras: Control xe drm_ras
registration with a flag - Riana Tauro
<https://lore.kernel.org/intel-xe/20260429055147.1579576-14-riana.tauro@intel.com/>
Thanks
Riana
<https://lore.kernel.org/intel-xe/20260429055147.1579576-14-riana.tauro@intel.com/>
>
> Signed-off-by: Riana Tauro <riana.tauro@intel.com>
> ---
> drivers/gpu/drm/xe/xe_device_types.h | 2 ++
> drivers/gpu/drm/xe/xe_hw_error.c | 2 +-
> drivers/gpu/drm/xe/xe_pci.c | 3 +++
> drivers/gpu/drm/xe/xe_pci_types.h | 1 +
> 4 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/gpu/drm/xe/xe_device_types.h b/drivers/gpu/drm/xe/xe_device_types.h
> index 31df9debcbb0..7a8afd06e6b8 100644
> --- a/drivers/gpu/drm/xe/xe_device_types.h
> +++ b/drivers/gpu/drm/xe/xe_device_types.h
> @@ -191,6 +191,8 @@ struct xe_device {
> u8 has_ctx_tlb_inval:1;
> /** @info.has_range_tlb_inval: Has range based TLB invalidations */
> u8 has_range_tlb_inval:1;
> + /** @info.has_ras: Device supports RAS (Reliability, Availability, Serviceability) */
> + u8 has_ras:1;
> /** @info.has_soc_remapper_sysctrl: Has SoC remapper system controller */
> u8 has_soc_remapper_sysctrl:1;
> /** @info.has_soc_remapper_telem: Has SoC remapper telemetry support */
> diff --git a/drivers/gpu/drm/xe/xe_hw_error.c b/drivers/gpu/drm/xe/xe_hw_error.c
> index 2a31b430570e..3ab0fceb151f 100644
> --- a/drivers/gpu/drm/xe/xe_hw_error.c
> +++ b/drivers/gpu/drm/xe/xe_hw_error.c
> @@ -520,7 +520,7 @@ void xe_hw_error_irq_handler(struct xe_tile *tile, const u32 master_ctl)
>
> static int hw_error_info_init(struct xe_device *xe)
> {
> - if (xe->info.platform != XE_PVC)
> + if (!xe->info.has_ras)
> return 0;
>
> return xe_drm_ras_init(xe);
> diff --git a/drivers/gpu/drm/xe/xe_pci.c b/drivers/gpu/drm/xe/xe_pci.c
> index 278c2860a4f6..10ff207affa9 100644
> --- a/drivers/gpu/drm/xe/xe_pci.c
> +++ b/drivers/gpu/drm/xe/xe_pci.c
> @@ -365,6 +365,7 @@ static const __maybe_unused struct xe_device_desc pvc_desc = {
> .vm_max_level = 4,
> .vram_flags = XE_VRAM_FLAGS_NEED64K,
> .has_mbx_power_limits = false,
> + .has_ras = true,
> };
>
> static const struct xe_device_desc mtl_desc = {
> @@ -472,6 +473,7 @@ static const struct xe_device_desc cri_desc = {
> .require_force_probe = true,
> .va_bits = 57,
> .vm_max_level = 4,
> + .has_ras = true,
> };
>
> static const struct xe_device_desc nvlp_desc = {
> @@ -761,6 +763,7 @@ static int xe_info_init_early(struct xe_device *xe,
> xe->info.has_page_reclaim_hw_assist = desc->has_page_reclaim_hw_assist;
> xe->info.has_pre_prod_wa = desc->has_pre_prod_wa;
> xe->info.has_pxp = desc->has_pxp;
> + xe->info.has_ras = desc->has_ras;
> xe->info.has_soc_remapper_sysctrl = desc->has_soc_remapper_sysctrl;
> xe->info.has_soc_remapper_telem = desc->has_soc_remapper_telem;
> xe->info.has_sriov = xe_configfs_primary_gt_allowed(to_pci_dev(xe->drm.dev)) &&
> diff --git a/drivers/gpu/drm/xe/xe_pci_types.h b/drivers/gpu/drm/xe/xe_pci_types.h
> index 5b85e2c24b7b..70a9d4995cbd 100644
> --- a/drivers/gpu/drm/xe/xe_pci_types.h
> +++ b/drivers/gpu/drm/xe/xe_pci_types.h
> @@ -54,6 +54,7 @@ struct xe_device_desc {
> u8 has_pre_prod_wa:1;
> u8 has_page_reclaim_hw_assist:1;
> u8 has_pxp:1;
> + u8 has_ras:1;
> u8 has_soc_remapper_sysctrl:1;
> u8 has_soc_remapper_telem:1;
> u8 has_sriov:1;
^ permalink raw reply
* [PATCH iwl-net] ice: reject out-of-range ptype in ice_parser_profile_init
From: Aleksandr Loktionov @ 2026-04-30 14:21 UTC (permalink / raw)
To: intel-wired-lan, anthony.l.nguyen, aleksandr.loktionov; +Cc: netdev
set_bit(rslt->ptype, prof->ptypes) operates on a DECLARE_BITMAP of
ICE_FLOW_PTYPE_MAX (1024) bits. Nothing prevents a malicious VF from
providing ptype >= 1024 through VIRTCHNL, resulting in a write past
the end of the bitmap and a kernel page fault.
Reproduced with a custom kernel module injecting a crafted
VIRTCHNL_OP_ADD_RSS_CFG on E810-C QSFP (8086:1592),
FW 4.91 0x800214af 1.3909.0, ICE COMMS DDP 1.3.53.0,
kernel 7.1.0-rc1.
crash_parser: ice_parser_profile_init @ ffffffffc0d61b60
crash_parser: setting ptype=0xffff (max valid=1023)
crash_parser: calling ice_parser_profile_init -- expect OOB crash!
BUG: kernel NULL pointer dereference, address: 0000000000000000
#PF: supervisor write access in kernel mode
#PF: error_code(0x0002) - not-present page
Oops: Oops: 0002 [#1] SMP NOPTI
CPU: 56 UID: 0 PID: 165011 Comm: insmod Kdump: loaded Tainted: G S U OE 7.1.0-rc1 #1
Hardware name: Intel Corporation S2600BPB/S2600BPB
RIP: 0010:ice_parser_profile_init+0x2d/0x1d0 [ice]
Call Trace:
<TASK>
? __pfx_ice_parser_profile_init+0x10/0x10 [ice]
crash_init+0x127/0xff0 [crash_parser]
do_one_initcall+0x45/0x310
do_init_module+0x64/0x270
init_module_from_file+0xcc/0xf0
idempotent_init_module+0x17b/0x280
__x64_sys_finit_module+0x6e/0xe0
Bail out early with -EINVAL when ptype is out of range.
Fixes: e312b3a1e209 ("ice: add API for parser profile initialization")
Cc: stable@vger.kernel.org
Signed-off-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
---
drivers/net/ethernet/intel/ice/ice_parser.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/intel/ice/ice_parser.c b/drivers/net/ethernet/intel/ice/ice_parser.c
index f8e6963..3ede4c1 100644
--- a/drivers/net/ethernet/intel/ice/ice_parser.c
+++ b/drivers/net/ethernet/intel/ice/ice_parser.c
@@ -2368,6 +2368,9 @@ int ice_parser_profile_init(struct ice_parser_result *rslt,
u16 proto_off = 0;
u16 off;
+ if (rslt->ptype >= ICE_FLOW_PTYPE_MAX)
+ return -EINVAL;
+
memset(prof, 0, sizeof(*prof));
set_bit(rslt->ptype, prof->ptypes);
if (blk == ICE_BLK_SW) {
--
2.52.0
^ permalink raw reply related
* Re: [PATCH v2 net-next] selftests/net: packetdrill: add tcp_syncookies_ip[46]_9k
From: Neal Cardwell @ 2026-04-30 14:21 UTC (permalink / raw)
To: Eric Dumazet
Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
Kuniyuki Iwashima, netdev, eric.dumazet
In-Reply-To: <20260430021444.2929534-1-edumazet@google.com>
On Wed, Apr 29, 2026 at 10:14 PM Eric Dumazet <edumazet@google.com> wrote:
>
> These tests check syncookie mode is able to reconstruct some
> client options when TCP TS are used:
>
> - wscale option.
> - sackOK.
> - MSS (in a limited way, especially for IPv4).
> - ECN : not enabled.
>
> Note that IPv4 and IPv6 have different msstab[] values:
>
> IPv4 msstab[4] = { 536, 1300, 1440, 1460 }
> IPv6 msstab[4] = { 1280 - 60, 1480 - 60, 1500 - 60, 9000 - 60 }
>
> IPv4 is currently capping SND_MSS to 1460, even on a 9K MTU network.
>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
Reviewed-by: Neal Cardwell <ncardwell@google.com>
Very nice. Thanks, Eric!
neal
^ permalink raw reply
* Re: [PATCH net-next 2/2] dpll: zl3073x: implement pin operational state reporting
From: Paolo Abeni @ 2026-04-30 14:21 UTC (permalink / raw)
To: Ivan Vecera, netdev
Cc: Arkadiusz Kubalewski, David S. Miller, Donald Hunter,
Eric Dumazet, Jakub Kicinski, Jiri Pirko, Jonathan Corbet,
Michal Schmidt, Pasi Vaananen, Petr Oros, Prathosh Satish,
Shuah Khan, Simon Horman, Vadim Fedorenko, linux-doc,
linux-kernel
In-Reply-To: <20260428154907.2820654-3-ivecera@redhat.com>
On 4/28/26 5:49 PM, Ivan Vecera wrote:
> @@ -1828,7 +1862,7 @@ zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
> }
Sashiko says:
---
Will input pin operational state changes fail to generate netlink
notifications when the DPLL channel is in FREERUN or HOLDOVER modes?
---
but such modes can not generate any real notification as explicitly
documented in a previous comment.
/P
^ permalink raw reply
* Re: [PATCH net-next 3/4] r8152: Add irq mitigation for RTL8157/9
From: Andrew Lunn @ 2026-04-30 14:19 UTC (permalink / raw)
To: Birger Koblitz
Cc: Michal Pecio, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, linux-usb, netdev, linux-kernel,
Chih Kai Hsu
In-Reply-To: <4446ad8c-0f5f-4f5a-8166-557ce9cc91b7@birger-koblitz.de>
> Also, I only see the issue on slow 5GBit USB-C connections, sometimes with
> the RTL8157, basically every time with the RTL8159, and so far never on a
> 20GBit USB-C connection, so the mitigation is probably some kind of
> interrupt coalescing.
Do you notice any latency changes with this setting in place? Or CPU load.
ping can be a good measure for latency.
If this is interrupt coalescing, it normally means don't interrupt as
soon as one packet has been received. Delay the interrupt, so there
are likely to be more packets in the receive queue. The cost of the
interrupt handling is then spread over a number of packets.
If this register setting is disabling coalescing, you should see the
latency go down, but the CPU load go up.
If you are getting interrupts after the device has been disabled, i
guess it is because the timer for a delayed interrupt is not cancelled
by the firmware. If so you might be able to work around this firmware
bug. Disable the receiver, sleep for 10ms but keep processing
interrupts, and then continue with the tear down.
Andrew
^ permalink raw reply
* Re: [PATCH v4 3/3 omap] ARM: dts: omap2: add stlc4560 spi-wireless node
From: Bartosz Golaszewski @ 2026-04-30 14:19 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Arnd Bergmann, Aaro Koskinen, Andreas Kemnade,
Bartosz Golaszewski, Benoît Cousson, David S. Miller,
Dmitry Torokhov, Eric Dumazet, Felipe Balbi, Jakub Kicinski,
Johannes Berg, Kevin Hilman, Krzysztof Kozlowski, Linus Walleij,
Paolo Abeni, Rob Herring, Roger Quadros, Tony Lindgren,
linux-wireless, devicetree, linux-kernel, linux-arm-kernel,
linux-gpio, linux-omap, Krzysztof Kozlowski, netdev
In-Reply-To: <20260430081242.3686993-4-arnd@kernel.org>
On Thu, 30 Apr 2026 10:12:42 +0200, Arnd Bergmann <arnd@kernel.org> said:
> From: Arnd Bergmann <arnd@arndb.de>
>
> Converted from the platform_device creation in board-n8x0.c.
>
> Link: https://lore.kernel.org/all/20230314163201.955689-1-arnd@kernel.org/
> Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> ---
Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
^ permalink raw reply
* [PATCH] kcov: refactor common handle ID into kcov_common_handle_id
From: Jann Horn @ 2026-04-30 14:15 UTC (permalink / raw)
To: Dmitry Vyukov, Andrey Konovalov, kasan-dev, Andrew Morton
Cc: Alexander Potapenko, Valentina Manea, Shuah Khan, Shuah Khan,
Hongren Zheng, linux-usb, Michael S. Tsirkin, Jason Wang,
Eugenio Pérez, kvm, virtualization, netdev, linux-kernel,
Jann Horn
Store common handle IDs in "struct kcov_common_handle_id", which consumes
no space in non-KCOV builds.
This cleanup removes #ifdef boilerplate code from subsystems that
integrate with KCOV (in particular in usbip_common.h and skbuff.h, see the
diffstat).
This should also make it easier to add KCOV remote coverage to more
subsystems in the future.
Signed-off-by: Jann Horn <jannh@google.com>
---
drivers/usb/usbip/usbip_common.h | 29 +----------------------------
drivers/usb/usbip/vhci_rx.c | 4 ++--
drivers/usb/usbip/vhci_sysfs.c | 2 +-
drivers/vhost/vhost.h | 2 +-
include/linux/kcov.h | 12 ++++++------
include/linux/skbuff.h | 14 +++-----------
include/linux/types.h | 6 ++++++
kernel/kcov.c | 6 +++---
8 files changed, 23 insertions(+), 52 deletions(-)
diff --git a/drivers/usb/usbip/usbip_common.h b/drivers/usb/usbip/usbip_common.h
index 282efca64a01..be4c5e65a7f8 100644
--- a/drivers/usb/usbip/usbip_common.h
+++ b/drivers/usb/usbip/usbip_common.h
@@ -282,9 +282,7 @@ struct usbip_device {
void (*unusable)(struct usbip_device *);
} eh_ops;
-#ifdef CONFIG_KCOV
- u64 kcov_handle;
-#endif
+ struct kcov_common_handle_id kcov_handle;
};
#define kthread_get_run(threadfn, data, namefmt, ...) \
@@ -339,29 +337,4 @@ static inline int interface_to_devnum(struct usb_interface *interface)
return udev->devnum;
}
-#ifdef CONFIG_KCOV
-
-static inline void usbip_kcov_handle_init(struct usbip_device *ud)
-{
- ud->kcov_handle = kcov_common_handle();
-}
-
-static inline void usbip_kcov_remote_start(struct usbip_device *ud)
-{
- kcov_remote_start_common(ud->kcov_handle);
-}
-
-static inline void usbip_kcov_remote_stop(void)
-{
- kcov_remote_stop();
-}
-
-#else /* CONFIG_KCOV */
-
-static inline void usbip_kcov_handle_init(struct usbip_device *ud) { }
-static inline void usbip_kcov_remote_start(struct usbip_device *ud) { }
-static inline void usbip_kcov_remote_stop(void) { }
-
-#endif /* CONFIG_KCOV */
-
#endif /* __USBIP_COMMON_H */
diff --git a/drivers/usb/usbip/vhci_rx.c b/drivers/usb/usbip/vhci_rx.c
index a75f4a898a41..a678e7c89837 100644
--- a/drivers/usb/usbip/vhci_rx.c
+++ b/drivers/usb/usbip/vhci_rx.c
@@ -261,9 +261,9 @@ int vhci_rx_loop(void *data)
if (usbip_event_happened(ud))
break;
- usbip_kcov_remote_start(ud);
+ kcov_remote_start_common(ud->kcov_handle);
vhci_rx_pdu(ud);
- usbip_kcov_remote_stop();
+ kcov_remote_stop();
}
return 0;
diff --git a/drivers/usb/usbip/vhci_sysfs.c b/drivers/usb/usbip/vhci_sysfs.c
index 5bc8c47788d4..b98d14c43d13 100644
--- a/drivers/usb/usbip/vhci_sysfs.c
+++ b/drivers/usb/usbip/vhci_sysfs.c
@@ -425,7 +425,7 @@ static ssize_t attach_store(struct device *dev, struct device_attribute *attr,
vdev->ud.tcp_rx = tcp_rx;
vdev->ud.tcp_tx = tcp_tx;
vdev->ud.status = VDEV_ST_NOTASSIGNED;
- usbip_kcov_handle_init(&vdev->ud);
+ vdev->ud.kcov_handle = kcov_common_handle();
spin_unlock(&vdev->ud.lock);
spin_unlock_irqrestore(&vhci->lock, flags);
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 4fe99765c5c7..0192ade6e749 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -44,7 +44,7 @@ struct vhost_worker {
/* Used to serialize device wide flushing with worker swapping. */
struct mutex mutex;
struct llist_head work_list;
- u64 kcov_handle;
+ struct kcov_common_handle_id kcov_handle;
u32 id;
int attachment_cnt;
bool killed;
diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 0143358874b0..cdb72b3859d8 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -43,11 +43,11 @@ do { \
/* See Documentation/dev-tools/kcov.rst for usage details. */
void kcov_remote_start(u64 handle);
void kcov_remote_stop(void);
-u64 kcov_common_handle(void);
+struct kcov_common_handle_id kcov_common_handle(void);
-static inline void kcov_remote_start_common(u64 id)
+static inline void kcov_remote_start_common(struct kcov_common_handle_id id)
{
- kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id));
+ kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_COMMON, id.val));
}
static inline void kcov_remote_start_usb(u64 id)
@@ -99,11 +99,11 @@ static inline void kcov_prepare_switch(struct task_struct *t) {}
static inline void kcov_finish_switch(struct task_struct *t) {}
static inline void kcov_remote_start(u64 handle) {}
static inline void kcov_remote_stop(void) {}
-static inline u64 kcov_common_handle(void)
+static inline struct kcov_common_handle_id kcov_common_handle(void)
{
- return 0;
+ return (struct kcov_common_handle_id){};
}
-static inline void kcov_remote_start_common(u64 id) {}
+static inline void kcov_remote_start_common(struct kcov_common_handle_id id) {}
static inline void kcov_remote_start_usb(u64 id) {}
static inline void kcov_remote_start_usb_softirq(u64 id) {}
static inline void kcov_remote_stop_softirq(void) {}
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 2bcf78a4de7b..a3fe418f7ced 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1082,9 +1082,7 @@ struct sk_buff {
__u16 network_header;
__u16 mac_header;
-#ifdef CONFIG_KCOV
- u64 kcov_handle;
-#endif
+ struct kcov_common_handle_id kcov_handle;
); /* end headers group */
@@ -5437,20 +5435,14 @@ static inline void skb_reset_csum_not_inet(struct sk_buff *skb)
}
static inline void skb_set_kcov_handle(struct sk_buff *skb,
- const u64 kcov_handle)
+ struct kcov_common_handle_id kcov_handle)
{
-#ifdef CONFIG_KCOV
skb->kcov_handle = kcov_handle;
-#endif
}
-static inline u64 skb_get_kcov_handle(struct sk_buff *skb)
+static inline struct kcov_common_handle_id skb_get_kcov_handle(struct sk_buff *skb)
{
-#ifdef CONFIG_KCOV
return skb->kcov_handle;
-#else
- return 0;
-#endif
}
static inline void skb_mark_for_recycle(struct sk_buff *skb)
diff --git a/include/linux/types.h b/include/linux/types.h
index 608050dbca6a..93166b0b0617 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -224,6 +224,12 @@ struct ustat {
char f_fpack[6];
};
+struct kcov_common_handle_id {
+#ifdef CONFIG_KCOV
+ u64 val;
+#endif
+};
+
/**
* struct callback_head - callback structure for use with RCU and task_work
* @next: next update requests in a list
diff --git a/kernel/kcov.c b/kernel/kcov.c
index 0b369e88c7c9..a43e33a28adb 100644
--- a/kernel/kcov.c
+++ b/kernel/kcov.c
@@ -1083,11 +1083,11 @@ void kcov_remote_stop(void)
EXPORT_SYMBOL(kcov_remote_stop);
/* See the comment before kcov_remote_start() for usage details. */
-u64 kcov_common_handle(void)
+struct kcov_common_handle_id kcov_common_handle(void)
{
if (!in_task())
- return 0;
- return current->kcov_handle;
+ return (struct kcov_common_handle_id){ .val = 0 };
+ return (struct kcov_common_handle_id){ .val = current->kcov_handle };
}
EXPORT_SYMBOL(kcov_common_handle);
---
base-commit: 57b8e2d666a31fa201432d58f5fe3469a0dd83ba
change-id: 20260430-kcov-refactor-common-handle-25178495b2eb
--
Jann Horn <jannh@google.com>
^ permalink raw reply related
* Re: [GIT PULL] wireless-2026-04-30
From: Jakub Kicinski @ 2026-04-30 14:12 UTC (permalink / raw)
To: Johannes Berg; +Cc: netdev, linux-wireless
In-Reply-To: <20260430111831.219242-6-johannes@sipsolutions.net>
On Thu, 30 Apr 2026 13:17:52 +0200 Johannes Berg wrote:
> So the LLM floodgates are starting to open ;-) But I'm somewhat
> happy that so far we haven't gotten any really critical reports.
> Here's a couple of first fixes though.
>
> Please pull and let us know if there's any problem.
Looks like this breaks kunit:
ok 70 mac80211-tpe
KTAP version 1
# Subtest: mac80211-mlme-chan-mode
# module: mac80211_tests
1..1
KTAP version 1
# Subtest: test_determine_chan_mode
ok 1 Normal case, EHT is working
ok 2 Requiring EHT support is fine
ok 3 Lowering the mode limits us
kunit: required basic rate or BSS membership selectors not supported or disabled, rejecting connection
ok 4 Requesting a basic rate/selector that we do not support
ok 5 As before, but userspace says it is taking care of it
# test_determine_chan_mode: ASSERTION FAILED at net/mac80211/tests/chan-mode.c:258
Expected conn.mode == params->expected_mode, but
conn.mode == 5 (0x5)
params->expected_mode == 1 (0x1)
not ok 6 Masking out a supported rate in HT capabilities
kunit: Missing mandatory rates for 4 Nss, rx 0, tx 2 oper 2, disable VHT
kunit: required MCSes not supported, disabling VHT
ok 7 Masking out a RX rate in VHT capabilities
kunit: Missing mandatory rates for 4 Nss, rx 2, tx 0 oper 2, disable VHT
kunit: required MCSes not supported, disabling VHT
ok 8 Masking out a TX rate in VHT capabilities
kunit: Missing mandatory rates for 5 Nss, rx 0, tx 0 oper 2, disable VHT
kunit: required MCSes not supported, disabling VHT
ok 9 AP has higher VHT requirement than client
ok 10 all zero VHT basic rates are ignored (many APs broken)
kunit: Invalid rates for 3 Nss, rx 3, tx 3 oper 0, disable HE
kunit: required MCSes not supported, disabling HE
ok 11 AP requires 3 HE streams but client only has two
ok 12 all zero HE basic rates are ignored (iPhone workaround)
kunit: required MCSes not supported, disabling EHT
ok 13 AP requires too many RX streams with EHT MCS 7
kunit: required MCSes not supported, disabling EHT
ok 14 AP requires too many TX streams with EHT MCS 7
kunit: required MCSes not supported, disabling EHT
kunit: required basic rate or BSS membership selectors not supported or disabled, rejecting connection
ok 15 AP requires too many RX streams with EHT MCS 7 and EHT is required
kunit: regulatory prevented using AP config, downgraded
kunit: required bandwidth not supported, disabling EHT
ok 16 80 MHz EHT is downgraded to 40 MHz HE due to puncturing
# test_determine_chan_mode: pass:15 fail:1 skip:0 total:16
not ok 1 test_determine_chan_mode
# Totals: pass:15 fail:1 skip:0 total:16
^ permalink raw reply
* Re: [PATCH net 2/2] ovpn: ensure gro_cells_receive() is invoked with BH disabled
From: Eric Dumazet @ 2026-04-30 14:10 UTC (permalink / raw)
To: Antonio Quartulli
Cc: netdev, Jakub Kicinski, ralf, Sabrina Dubroca, Paolo Abeni,
Andrew Lunn, David S. Miller
In-Reply-To: <a643b413-9997-4a28-a0de-919b83b327e9@openvpn.net>
On Thu, Apr 30, 2026 at 7:00 AM Antonio Quartulli <antonio@openvpn.net> wrote:
> Well, the process context was introduced by
>
> 11851cbd60ea ("ovpn: implement TCP transport")
>
> because the TCP code relies on strparser.
>
> Before 11851cbd60ea we had UDP only, therefore everything was happening
> in softirq, which means no bug existed (if I have understood this
> correctly).
>
> Makes sense?
>
> [in any case, both commits were basically merged side by side]
>
OK then, seems good.
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: imx8dxl: Add SolidRun SoM and HummingBoard
From: Andrew Lunn @ 2026-04-30 14:06 UTC (permalink / raw)
To: Josua Mayer
Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Shawn Guo,
Frank Li, Sascha Hauer, Pengutronix Kernel Team, Fabio Estevam,
Vladimir Oltean, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Yazan Shhady, Mikhail Anikin, Alexander Dahl,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
Vladimir Oltean, Conor Dooley, Krzysztof Kozlowski,
netdev@vger.kernel.org
In-Reply-To: <bd2e73c5-2e61-4ea1-ab3b-42a6573b31f8@solid-run.com>
> > Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> >
> > Andrew
>
> Thanks!
>
> I don't know how to keep this partial review for v3, so I will send it without.
You can add my Reviewed-by. It is on record in the archive that it
only applies to a subset.
And in general, nobody can know the whole kernel, all the different
subsystems, and the details for all the DT bindings. So i would allow
some fuzziness for Reviewed-by: for a DT patch.
Interesting, an Acked-by: might actually be more appropriate.
Acked-by: does not necessarily indicate acknowledgement of the
entire patch. For example, if a patch affects multiple subsystems
and has an Acked-by: from one subsystem maintainer then this
usually indicates acknowledgement of just the part which affects
that maintainer’s code. Judgement should be used here.
So how about:
Acked-by: Andrew Lunn <andrew@lunn.ch>
and you can take your pick :-)
Andrew
^ permalink raw reply
* Re: [RFC PATCH] xprtrdma: Move long delayed work on system_dfl_long_wq
From: Chuck Lever @ 2026-04-30 14:05 UTC (permalink / raw)
To: Frederic Weisbecker
Cc: Marco Crivellari, linux-kernel, linux-nfs, netdev, Tejun Heo,
Lai Jiangshan, Sebastian Andrzej Siewior, Michal Hocko,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
In-Reply-To: <afNguCraI6AvmZrR@localhost.localdomain>
On Thu, Apr 30, 2026, at 10:01 AM, Frederic Weisbecker wrote:
> Le Thu, Apr 30, 2026 at 09:35:20AM -0400, Chuck Lever a écrit :
>>
>> On Thu, Apr 30, 2026, at 4:54 AM, Marco Crivellari wrote:
>> > Currently the code enqueue work items using {queue|mod}_delayed_work(),
>> > using system_long_wq. This workqueue should be used when long works are
>> > expected, but it is a per-cpu workqueue.
>> >
>> > This is important because queue_delayed_work() queue the work using:
>> >
>> > queue_delayed_work_on(WORK_CPU_UNBOUND, ...);
>> >
>> > Note that WORK_CPU_UNBOUND = NR_CPUS.
>> >
>> > This would end up calling __queue_delayed_work() that does:
>> >
>> > if (housekeeping_enabled(HK_TYPE_TIMER)) {
>> > // [....]
>> > } else {
>> > if (likely(cpu == WORK_CPU_UNBOUND))
>> > add_timer_global(timer);
>> > else
>> > add_timer_on(timer, cpu);
>> > }
>> >
>> > So when cpu == WORK_CPU_UNBOUND the timer is global and is
>> > not using a specific CPU. Later, when __queue_work() is called:
>> >
>> > if (req_cpu == WORK_CPU_UNBOUND) {
>> > if (wq->flags & WQ_UNBOUND)
>> > cpu = wq_select_unbound_cpu(raw_smp_processor_id());
>> > else
>> > cpu = raw_smp_processor_id();
>> > }
>> >
>> > Because the wq is not unbound, it takes the CPU where the timer
>> > fired and enqueue the work on that CPU.
>> > The consequence of all of this is that the work can run anywhere,
>> > depending on where the timer fired.
>> >
>> > Recently, a new unbound workqueue specific for long running work has
>> > been added:
>> >
>> > c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")
>> >
>> > So change system_long_wq with system_dfl_long_wq so that the work may
>> > benefit from scheduler task placement.
>>
>> The patch description confuses me.
>>
>> The message ends with "the work can run anywhere, depending on where
>> the timer fired." Read literally, "can run anywhere" sounds like a
>> feature, not a bug
>
> A feature, but incomplete :)
>
>> — and the proposed fix (WQ_UNBOUND) also lets it
>> run anywhere, just via a different selection path. Without a sentence
>> saying "and that anywhere includes isolated CPUs, which we don't want,"
>> the reader is left to fill in the gap.
>
> Not quite, global timers don't fire on isolated CPUs. And since it gets enqueued
> on the CPU where it fired, it won't be enqueued on an isolated CPU.
>
>>
>> So, could the commit message lead with the motivation? My guess is that
>> this is about respecting HK_TYPE_TIMER housekeeping on isolated systems,
>> which system_long_wq cannot do because its per-CPU pool ignores the
>> housekeeping mask once the global timer fires. If that is the case,
>> please say so directly and the mechanism trace becomes a supporting
>> argument rather than the whole argument.
>
> The purpose is explained on the last line:
>
> """
> So change system_long_wq with system_dfl_long_wq so that the work may
> benefit from scheduler task placement.
> """
>
> Arguably this could be elaborated. For example we can change that:
>
> """
> The consequence of all of this is that the work can run anywhere,
> depending on where the timer fired.
> """
>
> into that:
>
> """
> The consequence of all of this is that the work can run on any
> housekeeping CPU, irrespective of the scheduler that knows better
> about the best task placement, which would apply if the work were
> to be queued on an unbound workqueue.
> """
>
> Would that help?
It's still not clearing it up for me.
Does the patch address a bug (work isn't getting rescheduled at
all) or is it merely a minor optimization for certain platforms?
What's the user-visible issue that will be improved with this
change?
--
Chuck Lever
^ permalink raw reply
* Re: [RFC PATCH] xprtrdma: Move long delayed work on system_dfl_long_wq
From: Frederic Weisbecker @ 2026-04-30 14:01 UTC (permalink / raw)
To: Chuck Lever
Cc: Marco Crivellari, linux-kernel, linux-nfs, netdev, Tejun Heo,
Lai Jiangshan, Sebastian Andrzej Siewior, Michal Hocko,
Trond Myklebust, Anna Schumaker, Chuck Lever, Jeff Layton,
NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey,
David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman
In-Reply-To: <8d1eff7b-3712-4039-87d6-028a4118e210@app.fastmail.com>
Le Thu, Apr 30, 2026 at 09:35:20AM -0400, Chuck Lever a écrit :
>
> On Thu, Apr 30, 2026, at 4:54 AM, Marco Crivellari wrote:
> > Currently the code enqueue work items using {queue|mod}_delayed_work(),
> > using system_long_wq. This workqueue should be used when long works are
> > expected, but it is a per-cpu workqueue.
> >
> > This is important because queue_delayed_work() queue the work using:
> >
> > queue_delayed_work_on(WORK_CPU_UNBOUND, ...);
> >
> > Note that WORK_CPU_UNBOUND = NR_CPUS.
> >
> > This would end up calling __queue_delayed_work() that does:
> >
> > if (housekeeping_enabled(HK_TYPE_TIMER)) {
> > // [....]
> > } else {
> > if (likely(cpu == WORK_CPU_UNBOUND))
> > add_timer_global(timer);
> > else
> > add_timer_on(timer, cpu);
> > }
> >
> > So when cpu == WORK_CPU_UNBOUND the timer is global and is
> > not using a specific CPU. Later, when __queue_work() is called:
> >
> > if (req_cpu == WORK_CPU_UNBOUND) {
> > if (wq->flags & WQ_UNBOUND)
> > cpu = wq_select_unbound_cpu(raw_smp_processor_id());
> > else
> > cpu = raw_smp_processor_id();
> > }
> >
> > Because the wq is not unbound, it takes the CPU where the timer
> > fired and enqueue the work on that CPU.
> > The consequence of all of this is that the work can run anywhere,
> > depending on where the timer fired.
> >
> > Recently, a new unbound workqueue specific for long running work has
> > been added:
> >
> > c116737e972e ("workqueue: Add system_dfl_long_wq for long unbound works")
> >
> > So change system_long_wq with system_dfl_long_wq so that the work may
> > benefit from scheduler task placement.
>
> The patch description confuses me.
>
> The message ends with "the work can run anywhere, depending on where
> the timer fired." Read literally, "can run anywhere" sounds like a
> feature, not a bug
A feature, but incomplete :)
> — and the proposed fix (WQ_UNBOUND) also lets it
> run anywhere, just via a different selection path. Without a sentence
> saying "and that anywhere includes isolated CPUs, which we don't want,"
> the reader is left to fill in the gap.
Not quite, global timers don't fire on isolated CPUs. And since it gets enqueued
on the CPU where it fired, it won't be enqueued on an isolated CPU.
>
> So, could the commit message lead with the motivation? My guess is that
> this is about respecting HK_TYPE_TIMER housekeeping on isolated systems,
> which system_long_wq cannot do because its per-CPU pool ignores the
> housekeeping mask once the global timer fires. If that is the case,
> please say so directly and the mechanism trace becomes a supporting
> argument rather than the whole argument.
The purpose is explained on the last line:
"""
So change system_long_wq with system_dfl_long_wq so that the work may
benefit from scheduler task placement.
"""
Arguably this could be elaborated. For example we can change that:
"""
The consequence of all of this is that the work can run anywhere,
depending on where the timer fired.
"""
into that:
"""
The consequence of all of this is that the work can run on any
housekeeping CPU, irrespective of the scheduler that knows better
about the best task placement, which would apply if the work were
to be queued on an unbound workqueue.
"""
Would that help?
Thanks.
--
Frederic Weisbecker
SUSE Labs
^ permalink raw reply
* Re: [PATCH net 2/2] ovpn: ensure gro_cells_receive() is invoked with BH disabled
From: Antonio Quartulli @ 2026-04-30 14:00 UTC (permalink / raw)
To: Eric Dumazet
Cc: netdev, Jakub Kicinski, ralf, Sabrina Dubroca, Paolo Abeni,
Andrew Lunn, David S. Miller
In-Reply-To: <CANn89i+5q8D50sEKUwk1OzGt8tZD2ddSK-kHGq6dFm5QRRpaDQ@mail.gmail.com>
On 30/04/2026 15:43, Eric Dumazet wrote:
> On Thu, Apr 30, 2026 at 6:40 AM Antonio Quartulli <antonio@openvpn.net> wrote:
>>
>> Hi Eric,
>>
>> On 30/04/2026 15:37, Eric Dumazet wrote:
>>> On Thu, Apr 30, 2026 at 6:28 AM Antonio Quartulli <antonio@openvpn.net> wrote:
>>>>
>>>> Hi Jakub,
>>>>
>>>> sashiko came back with an interesting review of the per-cpu stats update
>>>> in the surrounding code.
>>>>
>>>> As far as I can tell its explanation makes sense, but I am no per-cpu
>>>> expert.
>>>>
>>>> IIUC it basically says that if gro_cells_receive() is invoked with
>>>> bottom halves disabled, the following dev_dstats_rx_add() should be too
>>>> to avoid deadlocks and corruptions.
>>>>
>>>> See below:
>>>>
>>>> On 29/04/2026 14:01, Antonio Quartulli wrote:
>>>>> diff --git a/drivers/net/ovpn/io.c b/drivers/net/ovpn/io.c
>>>>> index d92bb87be2b2..c0fdb9504241 100644
>>>>> --- a/drivers/net/ovpn/io.c
>>>>> +++ b/drivers/net/ovpn/io.c
>>>>> @@ -91,7 +91,13 @@ static void ovpn_netdev_write(struct ovpn_peer *peer, struct sk_buff *skb)
>>>>>
>>>>> /* cause packet to be "received" by the interface */
>>>>> pkt_len = skb->len;
>>>>> + /* we may get here in process context in case of TCP connections,
>>>>> + * therefore we have to disable BHs to ensure gro_cells_receive()
>>>>> + * doesn't enter deadlock
>>>>> + */
>>>>> + local_bh_disable();
>>>>> ret = gro_cells_receive(&peer->ovpn->gro_cells, skb);
>>>>> + local_bh_enable();
>>>>> if (likely(ret == NET_RX_SUCCESS)) {
>>>>> /* update RX stats with the size of decrypted packet */
>>>>> ovpn_peer_stats_increment_rx(&peer->vpn_stats, pkt_len);
>>>> >> dev_dstats_rx_add(peer->ovpn->dev...) << not visible in the diff,
>>>> but it's here
>>>>
>>>> from sashiko:
>>>>
>>>> Can this lead to seqcount deadlocks and stat corruption since
>>>> dev_dstats_rx_add() is executed with preemption and bottom-halves enabled?
>>>> dev_dstats_rx_add() operates on per-CPU statistics and protects 64-bit
>>>> updates with a sequence counter (u64_stats_update_begin()). When called
>>>> from process context with BH enabled, on 64-bit systems, this_cpu_ptr()
>>>> is evaluated with preemption enabled. If the task is migrated mid-update,
>>>> it risks cross-CPU stat corruption.
>>>> On 32-bit systems, u64_stats_update_begin() disables preemption but not
>>>> bottom-halves. If a softirq (e.g., a concurrent UDP packet reception)
>>>> interrupts the process context and calls dev_dstats_rx_add() for the same
>>>> interface, it will re-enter the seqcount writer lock on the exact same CPU.
>>>> This corrupts the sequence counter, causing readers to see an unlocked
>>>> sequence during active writes, leading to torn reads and corrupted stats.
>>>> Should local_bh_enable() be moved after the statistics updates to ensure
>>>> the entire per-CPU update is atomic with respect to softirqs?
>>>>
>>>>
>>>> Do you have an opinion?
>>>
>>> Sashiko suggestion seems good to me.
>>
>> But am I right saying that this bug existed before and it is not
>> introduced by this patch?
>>
>> A concurrent softirq (UDP RX pkt) could already trigger this problem
>> before we introduced the local_bh_disable/enable() calls, right?
>
> I think we are saying the same thing.
Ok.
>
> Let me rephrase: The bug was introduced in:
>
> Fixes: ab66abbc769b ("ovpn: implement basic RX path (UDP)")
Well, the process context was introduced by
11851cbd60ea ("ovpn: implement TCP transport")
because the TCP code relies on strparser.
Before 11851cbd60ea we had UDP only, therefore everything was happening
in softirq, which means no bug existed (if I have understood this
correctly).
Makes sense?
[in any case, both commits were basically merged side by side]
Regards,
--
Antonio Quartulli
OpenVPN Inc.
^ 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