* [PATCH v8 11/14] net: ipa: Switch to generic PAS TZ APIs
From: Sumit Garg @ 2026-06-26 13:34 UTC (permalink / raw)
To: andersson
Cc: linux-arm-msm, dri-devel, freedreno, linux-media, netdev,
linux-wireless, ath12k, linux-remoteproc, konradybcio, robh,
krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
vikash.garodia, bod, mchehab, elder, andrew+netdev, davem,
edumazet, kuba, pabeni, jjohnson, mathieu.poirier,
trilokkumar.soni, mukesh.ojha, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg,
Alex Elder
In-Reply-To: <20260626133440.692849-1-sumit.garg@kernel.org>
From: Sumit Garg <sumit.garg@oss.qualcomm.com>
Switch ipa client driver over to generic PAS TZ APIs. Generic PAS TZ
service allows to support multiple TZ implementation backends like QTEE
based SCM PAS service, OP-TEE based PAS service and any further future TZ
backend service.
Reviewed-by: Alex Elder <elder@riscstar.com>
Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
drivers/net/ipa/Kconfig | 2 +-
drivers/net/ipa/ipa_main.c | 13 ++++++++-----
2 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ipa/Kconfig b/drivers/net/ipa/Kconfig
index 01d219d3760c..a9aff1b7977d 100644
--- a/drivers/net/ipa/Kconfig
+++ b/drivers/net/ipa/Kconfig
@@ -6,7 +6,7 @@ config QCOM_IPA
depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
select QCOM_MDT_LOADER
- select QCOM_SCM
+ select QCOM_PAS
select QCOM_QMI_HELPERS
help
Choose Y or M here to include support for the Qualcomm
diff --git a/drivers/net/ipa/ipa_main.c b/drivers/net/ipa/ipa_main.c
index 788dd99af2a4..3cd9e44680e9 100644
--- a/drivers/net/ipa/ipa_main.c
+++ b/drivers/net/ipa/ipa_main.c
@@ -14,7 +14,7 @@
#include <linux/pm_runtime.h>
#include <linux/types.h>
-#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_pas.h>
#include <linux/soc/qcom/mdt_loader.h>
#include "ipa.h"
@@ -624,10 +624,13 @@ static int ipa_firmware_load(struct device *dev)
}
ret = qcom_mdt_load(dev, fw, path, IPA_PAS_ID, virt, phys, size, NULL);
- if (ret)
+ if (ret) {
dev_err(dev, "error %d loading \"%s\"\n", ret, path);
- else if ((ret = qcom_scm_pas_auth_and_reset(IPA_PAS_ID)))
- dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);
+ } else {
+ ret = qcom_pas_auth_and_reset(IPA_PAS_ID);
+ if (ret)
+ dev_err(dev, "error %d authenticating \"%s\"\n", ret, path);
+ }
memunmap(virt);
out_release_firmware:
@@ -758,7 +761,7 @@ static enum ipa_firmware_loader ipa_firmware_loader(struct device *dev)
return IPA_LOADER_INVALID;
out_self:
/* We need Trust Zone to load firmware; make sure it's available */
- if (qcom_scm_is_available())
+ if (qcom_pas_is_available())
return IPA_LOADER_SELF;
return IPA_LOADER_DEFER;
--
2.53.0
^ permalink raw reply related
* [PATCH v8 12/14] wifi: ath12k: Switch to generic PAS TZ APIs
From: Sumit Garg @ 2026-06-26 13:34 UTC (permalink / raw)
To: andersson
Cc: linux-arm-msm, dri-devel, freedreno, linux-media, netdev,
linux-wireless, ath12k, linux-remoteproc, konradybcio, robh,
krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
vikash.garodia, bod, mchehab, elder, andrew+netdev, davem,
edumazet, kuba, pabeni, jjohnson, mathieu.poirier,
trilokkumar.soni, mukesh.ojha, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
In-Reply-To: <20260626133440.692849-1-sumit.garg@kernel.org>
From: Sumit Garg <sumit.garg@oss.qualcomm.com>
Switch ath12k client driver over to generic PAS TZ APIs. Generic PAS TZ
service allows to support multiple TZ implementation backends like QTEE
based SCM PAS service, OP-TEE based PAS service and any further future TZ
backend service.
Acked-by: Jeff Johnson <jjohnson@kernel.org>
Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
drivers/net/wireless/ath/ath12k/Kconfig | 2 +-
drivers/net/wireless/ath/ath12k/ahb.c | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath12k/Kconfig b/drivers/net/wireless/ath/ath12k/Kconfig
index 4a2b240f967a..0d5d1c55bfc1 100644
--- a/drivers/net/wireless/ath/ath12k/Kconfig
+++ b/drivers/net/wireless/ath/ath12k/Kconfig
@@ -18,7 +18,7 @@ config ATH12K_AHB
bool "Qualcomm ath12k AHB support"
depends on ATH12K && REMOTEPROC
select QCOM_MDT_LOADER
- select QCOM_SCM
+ select QCOM_PAS
help
Enable support for Ath12k AHB bus chipsets, example IPQ5332.
diff --git a/drivers/net/wireless/ath/ath12k/ahb.c b/drivers/net/wireless/ath/ath12k/ahb.c
index 30733a244454..d9717ea999d7 100644
--- a/drivers/net/wireless/ath/ath12k/ahb.c
+++ b/drivers/net/wireless/ath/ath12k/ahb.c
@@ -5,7 +5,7 @@
*/
#include <linux/dma-mapping.h>
-#include <linux/firmware/qcom/qcom_scm.h>
+#include <linux/firmware/qcom/qcom_pas.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
@@ -420,7 +420,7 @@ static int ath12k_ahb_power_up(struct ath12k_base *ab)
if (ab_ahb->scm_auth_enabled) {
/* Authenticate FW image using peripheral ID */
- ret = qcom_scm_pas_auth_and_reset(pasid);
+ ret = qcom_pas_auth_and_reset(pasid);
if (ret) {
ath12k_err(ab, "failed to boot the remote processor %d\n", ret);
goto err_fw2;
@@ -485,10 +485,10 @@ static void ath12k_ahb_power_down(struct ath12k_base *ab, bool is_suspend)
pasid = (u32_encode_bits(ab_ahb->userpd_id, ATH12K_USERPD_ID_MASK)) |
ATH12K_AHB_UPD_SWID;
/* Release the firmware */
- ret = qcom_scm_pas_shutdown(pasid);
+ ret = qcom_pas_shutdown(pasid);
if (ret)
- ath12k_err(ab, "scm pas shutdown failed for userPD%d\n",
- ab_ahb->userpd_id);
+ ath12k_err(ab, "pas shutdown failed for userPD%d: %d\n",
+ ab_ahb->userpd_id, ret);
}
}
--
2.53.0
^ permalink raw reply related
* [PATCH v8 13/14] firmware: qcom_scm: Remove SCM PAS wrappers
From: Sumit Garg @ 2026-06-26 13:34 UTC (permalink / raw)
To: andersson
Cc: linux-arm-msm, dri-devel, freedreno, linux-media, netdev,
linux-wireless, ath12k, linux-remoteproc, konradybcio, robh,
krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
vikash.garodia, bod, mchehab, elder, andrew+netdev, davem,
edumazet, kuba, pabeni, jjohnson, mathieu.poirier,
trilokkumar.soni, mukesh.ojha, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
In-Reply-To: <20260626133440.692849-1-sumit.garg@kernel.org>
From: Sumit Garg <sumit.garg@oss.qualcomm.com>
Now since all the Qcom SCM client drivers have been migrated over to
generic PAS TZ service, let's drop the exported SCM PAS wrappers.
Reviewed-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com>
Tested-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> # Lemans
Tested-by: Vignesh Viswanathan <vignesh.viswanathan@oss.qualcomm.com> # IPQ9650
Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
drivers/firmware/qcom/qcom_scm.c | 143 +++++--------------------
include/linux/firmware/qcom/qcom_scm.h | 29 -----
2 files changed, 29 insertions(+), 143 deletions(-)
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c
index 7933e55803dc..1deee6aea387 100644
--- a/drivers/firmware/qcom/qcom_scm.c
+++ b/drivers/firmware/qcom/qcom_scm.c
@@ -553,26 +553,6 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
}
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
- u32 pas_id,
- phys_addr_t mem_phys,
- size_t mem_size)
-{
- struct qcom_pas_context *ctx;
-
- ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
- if (!ctx)
- return ERR_PTR(-ENOMEM);
-
- ctx->dev = dev;
- ctx->pas_id = pas_id;
- ctx->mem_phys = mem_phys;
- ctx->mem_size = mem_size;
-
- return (struct qcom_scm_pas_context *)ctx;
-}
-EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc);
-
static int __qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
dma_addr_t mdata_phys,
struct qcom_scm_res *res)
@@ -630,9 +610,9 @@ static int qcom_scm_pas_prep_and_init_image(struct device *dev,
return ret ? : res.result[0];
}
-static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
- const void *metadata, size_t size,
- struct qcom_pas_context *ctx)
+static int qcom_scm_pas_init_image(struct device *dev, u32 pas_id,
+ const void *metadata, size_t size,
+ struct qcom_pas_context *ctx)
{
struct qcom_scm_res res;
dma_addr_t mdata_phys;
@@ -672,16 +652,8 @@ static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id,
return ret ? : res.result[0];
}
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_context *ctx)
-{
- return __qcom_scm_pas_init_image2(__scm->dev, pas_id, metadata, size,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image);
-
-static void __qcom_scm_pas_metadata_release(struct device *dev,
- struct qcom_pas_context *ctx)
+static void qcom_scm_pas_metadata_release(struct device *dev,
+ struct qcom_pas_context *ctx)
{
if (ctx->use_tzmem)
qcom_tzmem_free(ctx->ptr);
@@ -691,15 +663,8 @@ static void __qcom_scm_pas_metadata_release(struct device *dev,
ctx->ptr = NULL;
}
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx)
-{
- __qcom_scm_pas_metadata_release(__scm->dev,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release);
-
-static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
- phys_addr_t addr, phys_addr_t size)
+static int qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
+ phys_addr_t addr, phys_addr_t size)
{
int ret;
struct qcom_scm_desc desc = {
@@ -730,12 +695,6 @@ static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id,
return ret ? : res.result[0];
}
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size)
-{
- return __qcom_scm_pas_mem_setup(__scm->dev, pas_id, addr, size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup);
-
static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id,
void *input_rt_tzm,
size_t input_rt_size,
@@ -789,11 +748,10 @@ static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id,
return ret ? ERR_PTR(ret) : output_rt_tzm;
}
-static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
- struct qcom_pas_context *ctx,
- void *input_rt,
- size_t input_rt_size,
- size_t *output_rt_size)
+static void *qcom_scm_pas_get_rsc_table(struct device *dev,
+ struct qcom_pas_context *ctx,
+ void *input_rt, size_t input_rt_size,
+ size_t *output_rt_size)
{
struct resource_table empty_rsc = {};
size_t size = SZ_16K;
@@ -864,19 +822,7 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev,
return ret ? ERR_PTR(ret) : tbl_ptr;
}
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
- void *input_rt,
- size_t input_rt_size,
- size_t *output_rt_size)
-{
- return __qcom_scm_pas_get_rsc_table2(__scm->dev,
- (struct qcom_pas_context *)ctx,
- input_rt, input_rt_size,
- output_rt_size);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table);
-
-static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
+static int qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -905,14 +851,8 @@ static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id)
return ret ? : res.result[0];
}
-int qcom_scm_pas_auth_and_reset(u32 pas_id)
-{
- return __qcom_scm_pas_auth_and_reset(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset);
-
-static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
- struct qcom_pas_context *ctx)
+static int qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
+ struct qcom_pas_context *ctx)
{
u64 handle;
int ret;
@@ -923,7 +863,7 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
* memory region and then invokes a call to TrustZone to authenticate.
*/
if (!ctx->use_tzmem)
- return __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
+ return qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
/*
* When Linux runs @ EL2 Linux must create the shmbridge itself and then
@@ -933,21 +873,14 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev,
if (ret)
return ret;
- ret = __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
+ ret = qcom_scm_pas_auth_and_reset(dev, ctx->pas_id);
qcom_tzmem_shm_bridge_delete(handle);
return ret;
}
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx)
-{
- return __qcom_scm_pas_prepare_and_auth_reset(__scm->dev,
- (struct qcom_pas_context *)ctx);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset);
-
-static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
- u32 pas_id)
+static int qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
+ u32 pas_id)
{
struct qcom_scm_desc desc = {
.svc = QCOM_SCM_SVC_BOOT,
@@ -965,13 +898,7 @@ static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state,
return ret ? : res.result[0];
}
-int qcom_scm_set_remote_state(u32 state, u32 id)
-{
- return __qcom_scm_pas_set_remote_state(__scm->dev, state, id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state);
-
-static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
+static int qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -1000,13 +927,7 @@ static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id)
return ret ? : res.result[0];
}
-int qcom_scm_pas_shutdown(u32 pas_id)
-{
- return __qcom_scm_pas_shutdown(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown);
-
-static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
+static bool qcom_scm_pas_supported(struct device *dev, u32 pas_id)
{
int ret;
struct qcom_scm_desc desc = {
@@ -1027,23 +948,17 @@ static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id)
return ret ? false : !!res.result[0];
}
-bool qcom_scm_pas_supported(u32 pas_id)
-{
- return __qcom_scm_pas_supported(__scm->dev, pas_id);
-}
-EXPORT_SYMBOL_GPL(qcom_scm_pas_supported);
-
static struct qcom_pas_ops qcom_pas_ops_scm = {
.drv_name = "qcom_scm",
- .supported = __qcom_scm_pas_supported,
- .init_image = __qcom_scm_pas_init_image2,
- .mem_setup = __qcom_scm_pas_mem_setup,
- .get_rsc_table = __qcom_scm_pas_get_rsc_table2,
- .auth_and_reset = __qcom_scm_pas_auth_and_reset,
- .prepare_and_auth_reset = __qcom_scm_pas_prepare_and_auth_reset,
- .set_remote_state = __qcom_scm_pas_set_remote_state,
- .shutdown = __qcom_scm_pas_shutdown,
- .metadata_release = __qcom_scm_pas_metadata_release,
+ .supported = qcom_scm_pas_supported,
+ .init_image = qcom_scm_pas_init_image,
+ .mem_setup = qcom_scm_pas_mem_setup,
+ .get_rsc_table = qcom_scm_pas_get_rsc_table,
+ .auth_and_reset = qcom_scm_pas_auth_and_reset,
+ .prepare_and_auth_reset = qcom_scm_pas_prepare_and_auth_reset,
+ .set_remote_state = qcom_scm_pas_set_remote_state,
+ .shutdown = qcom_scm_pas_shutdown,
+ .metadata_release = qcom_scm_pas_metadata_release,
};
/**
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h
index 5747bd191bf1..a0a6bc0229c4 100644
--- a/include/linux/firmware/qcom/qcom_scm.h
+++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -64,35 +64,6 @@ bool qcom_scm_is_available(void);
int qcom_scm_set_cold_boot_addr(void *entry);
int qcom_scm_set_warm_boot_addr(void *entry);
void qcom_scm_cpu_power_down(u32 flags);
-int qcom_scm_set_remote_state(u32 state, u32 id);
-
-struct qcom_scm_pas_context {
- struct device *dev;
- u32 pas_id;
- phys_addr_t mem_phys;
- size_t mem_size;
- void *ptr;
- dma_addr_t phys;
- ssize_t size;
- bool use_tzmem;
-};
-
-struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev,
- u32 pas_id,
- phys_addr_t mem_phys,
- size_t mem_size);
-int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size,
- struct qcom_scm_pas_context *ctx);
-void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx);
-int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size);
-int qcom_scm_pas_auth_and_reset(u32 pas_id);
-int qcom_scm_pas_shutdown(u32 pas_id);
-bool qcom_scm_pas_supported(u32 pas_id);
-struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx,
- void *input_rt, size_t input_rt_size,
- size_t *output_rt_size);
-
-int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx);
int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
--
2.53.0
^ permalink raw reply related
* [PATCH v8 14/14] MAINTAINERS: Add maintainer entry for Qualcomm PAS TZ service
From: Sumit Garg @ 2026-06-26 13:34 UTC (permalink / raw)
To: andersson
Cc: linux-arm-msm, dri-devel, freedreno, linux-media, netdev,
linux-wireless, ath12k, linux-remoteproc, konradybcio, robh,
krzk+dt, conor+dt, robin.clark, sean, akhilpo, lumag,
abhinav.kumar, jesszhan0024, marijn.suijten, airlied, simona,
vikash.garodia, bod, mchehab, elder, andrew+netdev, davem,
edumazet, kuba, pabeni, jjohnson, mathieu.poirier,
trilokkumar.soni, mukesh.ojha, pavan.kondeti, jorge.ramirez,
tonyh, vignesh.viswanathan, srinivas.kandagatla, amirreza.zarrabi,
jens.wiklander, op-tee, apurupa, skare, linux-kernel, Sumit Garg
In-Reply-To: <20260626133440.692849-1-sumit.garg@kernel.org>
From: Sumit Garg <sumit.garg@oss.qualcomm.com>
Add Sumit Garg as the maintainer for the Qualcomm generic Peripheral
Authentication Service (PAS) as well as the PAS TEE backend driver.
Signed-off-by: Sumit Garg <sumit.garg@oss.qualcomm.com>
---
MAINTAINERS | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 15011f5752a9..7847b2a98f90 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -22315,6 +22315,15 @@ F: Documentation/devicetree/bindings/media/*qcom*
F: drivers/media/platform/qcom
F: include/dt-bindings/media/*qcom*
+QUALCOMM PAS TZ SERVICE
+M: Sumit Garg <sumit.garg@oss.qualcomm.com>
+L: linux-arm-msm@vger.kernel.org
+S: Maintained
+F: drivers/firmware/qcom/qcom_pas.c
+F: drivers/firmware/qcom/qcom_pas.h
+F: drivers/firmware/qcom/qcom_pas_tee.c
+F: include/linux/firmware/qcom/qcom_pas.h
+
QUALCOMM SMB CHARGER DRIVER
M: Casey Connolly <casey.connolly@linaro.org>
L: linux-arm-msm@vger.kernel.org
--
2.53.0
^ permalink raw reply related
* RE: [PATCH net 1/7] xsk: fix buffer leak in xsk_drop_skb() for AF_XDP multi-buffer Tx
From: Fijalkowski, Maciej @ 2026-06-26 13:43 UTC (permalink / raw)
To: Jason Xing, Zaremba, Larysa
Cc: netdev@vger.kernel.org, bpf@vger.kernel.org, Karlsson, Magnus,
stfomichev@gmail.com, kuba@kernel.org, pabeni@redhat.com,
horms@kernel.org, bjorn@kernel.org, Jason Xing
In-Reply-To: <CAL+tcoBCsn+b5bY-XAhbEw6wvceMNQwkyry0_NUun1AcR0b6Ag@mail.gmail.com>
>
> On Fri, Jun 26, 2026 at 7:12 PM Larysa Zaremba <larysa.zaremba@intel.com>
> wrote:
> >
> > On Tue, Jun 23, 2026 at 03:32:34PM +0200, Maciej Fijalkowski wrote:
> > > From: Jason Xing <kernelxing@tencent.com>
> > >
> > > This patch is inspired by the check[1] from sashiko. It says when
> > > overflow happens, the address of cq to be published is invalid.
> > > Actually the severer thing is the whole process of publishing the
> > > address of cq in this particular case is not right: it should truely
> > > publish the address and advance the cached_prod in cq as long as it
> > > reads descriptors from txq.
> > >
> > > The following is the full analysis.
> > > xsk_drop_skb() is called in three places, which all discard a partially
> > > built multi-buffer skb:
> > > 1) xsk_build_skb() -EOVERFLOW error path: packet exceeds
> MAX_SKB_FRAGS
> > > 2) __xsk_generic_xmit() post-loop cleanup: an invalid descriptor in
> > > the TX ring prevents the partial packet from completing
> > > 3) xsk_release(): socket close while xs->skb holds an incomplete packet
> > >
> > > In all three cases, the TX descriptors for the already-processed frags
> > > have been consumed from the TX ring (xskq_cons_release), and CQ slots
> > > have been reserved. However, xsk_drop_skb() calls xsk_consume_skb()
> > > which cancels the CQ reservations via xsk_cq_cancel_locked(). Since
> > > the buffer addresses never appear in the completion queue, userspace
> > > permanently loses track of these buffers.
> > >
> > > Fix this by letting consume_skb() trigger the existing xsk_destruct_skb
> > > destructor, which already submits buffer addresses to the CQ via
> > > xsk_cq_submit_addr_locked().
> > >
> > > Note that cancelling the descriptors back to the TX ring (via
> > > xskq_cons_cancel_n) is not a appropriate option because an oversized
> > > packet that always exceeds MAX_SKB_FRAGS would be retried indefinitely,
> > > which is an obviously deadlock bug in the TX path.
> > >
> > > Also move the desc->addr assignment in xsk_build_skb() above the
> > > overflow check so that the current descriptor's address is recorded
> > > before a potential -EOVERFLOW jump to free_err, consistent with the
> > > zerocopy path in xsk_build_skb_zerocopy().
> > >
> > > [1]:
> https://lore.kernel.org/all/20260425041726.85FB3C2BCB2@smtp.kernel.org/
> >
> > This change looks good, but overflow case with only 1 descriptor worries
> me.
>
> I presume you referred to xsk_build_skb_zerocopy()?
>
> > In such cases, once we get to following code, kfree_skb() has already
> happened:
> >
> > if (err == -EOVERFLOW) {
> > if (xs->skb) {
> > /* Drop the packet */
> > xsk_inc_num_desc(xs->skb);
> > xsk_drop_skb(xs->skb);
> > } else {
> > xsk_cq_cancel_locked(xs->pool, 1);
> > xs->tx->invalid_descs++;
> > }
> > xskq_cons_release(xs->tx);
> > }
> >
> > kfree_skb() should have resulted in submission of the single fat descriptor to
> > xsk_cq_submit_addr_locked() via xsk_destruct_skb(), so far consistent with
> the
>
> At least, in the NO_LINEAR case, xsk_skb_init_misc() is not called
> since the OVERFLOW skips this function, which means kfree_skb()
> doesn't invoke xsk_destruct_skb() to publish it in the CQ. So it's
> safe to cancel the cq reservation (in xsk_cq_cancel_locked(xs->pool,
> 1)).
(responding from outlook so apologies for any broken formatting)
Yes, I have the same understanding here. However, how technically
possible would it be to produce > MAX_SKB_FRAGS from a single
AF_XDP descriptor?
I know Sashiko has pointed this out and you came up with previous
fix, but for valid descriptor it is simply not possible. And invalid
descs wouldn't reach this function.
I wouldn't like to stir up the pot too much so let us keep this
code, but is there any way to give Sashiko additional context?
I mean, for case where we would say *this can't happen*, will
It be able to carry this information onwards?
>
> Thanks,
> Jason
>
> > multi-descriptor bevaior you are proposing here.
> >
> > But what happens when we cancel a submitted CQ slot via
> > xsk_cq_cancel_locked(xs->pool, 1) in the above code?
> >
> > >
> > > Fixes: cf24f5a5feea ("xsk: add support for AF_XDP multi-buffer on Tx
> path")
> > > Signed-off-by: Jason Xing <kernelxing@tencent.com>
> > > ---
> > > net/xdp/xsk.c | 13 ++++++++-----
> > > 1 file changed, 8 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/net/xdp/xsk.c b/net/xdp/xsk.c
> > > index b970f30ea9b9..a7a83dc4546a 100644
> > > --- a/net/xdp/xsk.c
> > > +++ b/net/xdp/xsk.c
> > > @@ -794,8 +794,11 @@ static void xsk_consume_skb(struct sk_buff
> *skb)
> > >
> > > static void xsk_drop_skb(struct sk_buff *skb)
> > > {
> > > - xdp_sk(skb->sk)->tx->invalid_descs += xsk_get_num_desc(skb);
> > > - xsk_consume_skb(skb);
> > > + struct xdp_sock *xs = xdp_sk(skb->sk);
> > > +
> > > + xs->tx->invalid_descs += xsk_get_num_desc(skb);
> > > + consume_skb(skb);
> > > + xs->skb = NULL;
> > > }
> > >
> > > static int xsk_skb_metadata(struct sk_buff *skb, void *buffer,
> > > @@ -877,7 +880,7 @@ static struct sk_buff
> *xsk_build_skb_zerocopy(struct xdp_sock *xs,
> > > return ERR_PTR(-ENOMEM);
> > >
> > > /* in case of -EOVERFLOW that could happen below,
> > > - * xsk_consume_skb() will release this node as whole skb
> > > + * xsk_drop_skb() will release this node as whole skb
> > > * would be dropped, which implies freeing all list elements
> > > */
> > > xsk_addr->addrs[xsk_addr->num_descs] = desc->addr;
> > > @@ -969,6 +972,8 @@ static struct sk_buff *xsk_build_skb(struct
> xdp_sock *xs,
> > > goto free_err;
> > > }
> > >
> > > + xsk_addr->addrs[xsk_addr->num_descs] = desc->addr;
> > > +
> > > if (unlikely(nr_frags == (MAX_SKB_FRAGS - 1) &&
> xp_mb_desc(desc))) {
> > > err = -EOVERFLOW;
> > > goto free_err;
> > > @@ -986,8 +991,6 @@ static struct sk_buff *xsk_build_skb(struct
> xdp_sock *xs,
> > >
> > > skb_add_rx_frag(skb, nr_frags, page, 0, len, PAGE_SIZE);
> > > refcount_add(PAGE_SIZE, &xs->sk.sk_wmem_alloc);
> > > -
> > > - xsk_addr->addrs[xsk_addr->num_descs] = desc->addr;
> > > }
> > > }
> > >
> > > --
> > > 2.43.0
> > >
> > >
^ permalink raw reply
* [PATCH net 0/2] vsock/virtio: collapse receive queue under memory pressure
From: Stefano Garzarella @ 2026-06-26 13:48 UTC (permalink / raw)
To: netdev
Cc: Jason Wang, Jakub Kicinski, Paolo Abeni, Michael S. Tsirkin, kvm,
virtualization, Xuan Zhuo, Eric Dumazet, Simon Horman,
Stefano Garzarella, linux-kernel, Stefan Hajnoczi,
David S. Miller, Eugenio Pérez
This series contains a patch (the first one) that is part of work I'm
doing to improve the tracking of memory used by AF_VSOCK sockets.
The second patch is a test for our suite that highlights the issue.
Since Brien reported an issue with his environment (based on Linux 6.12.y)
related to the work I’m doing, I extracted this patch and tried to make it
as easy as possible to backport. Brien tested it by backporting it to
6.12.y, which now contains the backport of the 059b7dbd20a6
("vsock/virtio: fix potential unbounded skb queue").
This patch primarily fixes STREAM sockets, but also partially fixes
SEQPACKET (with the exception of EOMs, which are kept in separate skbs to
avoid overcomplicating the code).
The rest of the work, I feel, is more net-next material and still needs
some work to be completed.
Thanks,
Stefano
Stefano Garzarella (2):
vsock/virtio: collapse receive queue under memory pressure
vsock/test: add test for small packets under pressure
net/vmw_vsock/virtio_transport_common.c | 148 +++++++++++++++++++++++-
tools/testing/vsock/vsock_test.c | 87 ++++++++++++++
2 files changed, 233 insertions(+), 2 deletions(-)
--
2.54.0
^ permalink raw reply
* [PATCH net 1/2] vsock/virtio: collapse receive queue under memory pressure
From: Stefano Garzarella @ 2026-06-26 13:48 UTC (permalink / raw)
To: netdev
Cc: Jason Wang, Jakub Kicinski, Paolo Abeni, Michael S. Tsirkin, kvm,
virtualization, Xuan Zhuo, Eric Dumazet, Simon Horman,
Stefano Garzarella, linux-kernel, Stefan Hajnoczi,
David S. Miller, Eugenio Pérez, stable, Brien Oberstein
In-Reply-To: <20260626134823.206676-1-sgarzare@redhat.com>
From: Stefano Garzarella <sgarzare@redhat.com>
When many small packets accumulate in the receive queue, the skb overhead
can exceed buf_alloc even while the payload is within bounds. This causes
virtio_transport_inc_rx_pkt() to reject packets, leading to connection
resets during large transfers under backpressure.
The issue was reported by Brien, who has a reproducer, but it is also
easily reproducible with iperf-vsock [1] using a small packet size:
iperf3 --vsock -c $CID -l 129
which fails immediately without this patch but with commit 059b7dbd20a6
("vsock/virtio: fix potential unbounded skb queue").
Inspired by TCP's tcp_collapse() which solves a similar problem, add
virtio_transport_collapse_rx_queue() that walks the receive queue and
re-copies data into compact linear skbs to reduce the overhead.
The collapse is triggered from virtio_transport_recv_enqueue() when
virtio_transport_inc_rx_pkt() fails. A pre-scan counts the eligible bytes
to size each allocation precisely, avoiding waste for isolated small
packets. Partially consumed skbs are kept as-is to preserve
buf_used/fwd_cnt accounting, EOM-marked skbs to maintain SEQPACKET
message boundaries, and skbs already larger than the collapse target
because they already have a good data-to-overhead ratio.
[1] https://github.com/stefano-garzarella/iperf-vsock
Fixes: 059b7dbd20a6 ("vsock/virtio: fix potential unbounded skb queue")
Cc: stable@vger.kernel.org
Reported-by: Brien Oberstein <brienpub@gmail.com>
Closes: https://lore.kernel.org/netdev/618701dd023e$063de350$12b9a9f0$@gmail.com/
Tested-by: Brien Oberstein <brienpub@gmail.com>
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
net/vmw_vsock/virtio_transport_common.c | 148 +++++++++++++++++++++++-
1 file changed, 146 insertions(+), 2 deletions(-)
diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
index 09475007165b..304ea424995d 100644
--- a/net/vmw_vsock/virtio_transport_common.c
+++ b/net/vmw_vsock/virtio_transport_common.c
@@ -420,6 +420,137 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
return ret;
}
+static bool virtio_transport_can_collapse(struct sk_buff *skb,
+ unsigned int size)
+{
+ /* skbs that are partially consumed, mark a SEQPACKET message boundary,
+ * or are already large enough should not be collapsed: they either
+ * need special accounting, carry protocol state, or already have a
+ * good data-to-overhead ratio.
+ */
+ if (VIRTIO_VSOCK_SKB_CB(skb)->offset)
+ return false;
+ if (le32_to_cpu(virtio_vsock_hdr(skb)->flags) & VIRTIO_VSOCK_SEQ_EOM)
+ return false;
+ if (skb->len >= size)
+ return false;
+ return true;
+}
+
+/* Iterate through the packets in the queue starting from the current skb to
+ * count the number of bytes we can collapse.
+ */
+static unsigned int
+virtio_transport_collapse_size(struct sk_buff *skb,
+ struct sk_buff_head *queue,
+ unsigned int max_size)
+{
+ unsigned int target = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
+
+ while ((skb = skb_peek_next(skb, queue)) &&
+ virtio_transport_can_collapse(skb, max_size)) {
+ unsigned int len = skb->len - VIRTIO_VSOCK_SKB_CB(skb)->offset;
+
+ if (len > max_size - target)
+ return target;
+
+ target += len;
+ }
+
+ return target;
+}
+
+/* Called under lock_sock when skb overhead exceeds the budget. */
+static void virtio_transport_collapse_rx_queue(struct virtio_vsock_sock *vvs)
+{
+ /* Use the same linear allocation threshold as virtio_vsock_alloc_skb()
+ * to avoid adding pressure on the page allocator.
+ */
+ unsigned int collapse_max = SKB_MAX_ORDER(VIRTIO_VSOCK_SKB_HEADROOM,
+ PAGE_ALLOC_COSTLY_ORDER);
+ struct sk_buff *skb, *next_skb, *new_skb = NULL;
+ struct sk_buff_head new_queue;
+
+ __skb_queue_head_init(&new_queue);
+
+ skb_queue_walk_safe(&vvs->rx_queue, skb, next_skb) {
+ struct virtio_vsock_hdr *hdr = virtio_vsock_hdr(skb);
+ u32 src_off = VIRTIO_VSOCK_SKB_CB(skb)->offset;
+ u32 src_len = skb->len - src_off;
+ bool keep = false;
+
+ if (!virtio_transport_can_collapse(skb, collapse_max)) {
+ /* Finalize pending collapsed skb to preserve packet
+ * ordering.
+ */
+ if (new_skb) {
+ __skb_queue_tail(&new_queue, new_skb);
+ new_skb = NULL;
+ }
+ keep = true;
+ goto next;
+ }
+
+ /* Finalize if this packet won't fit in the remaining tailroom,
+ * so we can allocate a right-sized new_skb.
+ */
+ if (new_skb && src_len > skb_tailroom(new_skb)) {
+ __skb_queue_tail(&new_queue, new_skb);
+ new_skb = NULL;
+ }
+
+ if (!new_skb) {
+ unsigned int alloc_size;
+
+ alloc_size = virtio_transport_collapse_size(skb, &vvs->rx_queue,
+ collapse_max);
+
+ /* Only this skb's data is eligible, nothing to merge
+ * with. Keep as-is.
+ */
+ if (alloc_size <= src_len) {
+ keep = true;
+ goto next;
+ }
+
+ new_skb = virtio_vsock_alloc_linear_skb(alloc_size +
+ VIRTIO_VSOCK_SKB_HEADROOM, GFP_KERNEL);
+ if (!new_skb)
+ goto out;
+
+ memcpy(virtio_vsock_hdr(new_skb), hdr,
+ sizeof(struct virtio_vsock_hdr));
+ virtio_vsock_hdr(new_skb)->len = 0;
+ }
+
+ /* Cannot fail since src_off/src_len are within bounds, but if
+ * it does, discard new_skb to avoid queuing corrupted data.
+ */
+ if (WARN_ON_ONCE(skb_copy_bits(skb, src_off,
+ skb_put(new_skb, src_len),
+ src_len))) {
+ kfree_skb(new_skb);
+ new_skb = NULL;
+ goto out;
+ }
+
+ le32_add_cpu(&virtio_vsock_hdr(new_skb)->len, src_len);
+ virtio_vsock_hdr(new_skb)->flags |= hdr->flags;
+
+next:
+ __skb_unlink(skb, &vvs->rx_queue);
+ if (keep)
+ __skb_queue_tail(&new_queue, skb);
+ else
+ consume_skb(skb);
+ }
+out:
+ if (new_skb)
+ __skb_queue_tail(&new_queue, new_skb);
+
+ skb_queue_splice(&new_queue, &vvs->rx_queue);
+}
+
static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
u32 len)
{
@@ -1363,8 +1494,21 @@ virtio_transport_recv_enqueue(struct vsock_sock *vsk,
spin_lock_bh(&vvs->rx_lock);
can_enqueue = virtio_transport_inc_rx_pkt(vvs, len);
- if (!can_enqueue)
- goto out;
+ if (!can_enqueue) {
+ /* Try to collapse the receive queue to reduce skb overhead and
+ * make room for this packet.
+ * Unlock rx_lock since the collapse may sleep or, in any case,
+ * take some time to collapse the skbs, but this is safe, since
+ * sk_lock is held by caller so no one else can enqueue or
+ * dequeue.
+ */
+ spin_unlock_bh(&vvs->rx_lock);
+ virtio_transport_collapse_rx_queue(vvs);
+ spin_lock_bh(&vvs->rx_lock);
+ can_enqueue = virtio_transport_inc_rx_pkt(vvs, len);
+ if (!can_enqueue)
+ goto out;
+ }
if (le32_to_cpu(hdr->flags) & VIRTIO_VSOCK_SEQ_EOM)
vvs->msg_count++;
--
2.54.0
^ permalink raw reply related
* [PATCH net 2/2] vsock/test: add test for small packets under pressure
From: Stefano Garzarella @ 2026-06-26 13:48 UTC (permalink / raw)
To: netdev
Cc: Jason Wang, Jakub Kicinski, Paolo Abeni, Michael S. Tsirkin, kvm,
virtualization, Xuan Zhuo, Eric Dumazet, Simon Horman,
Stefano Garzarella, linux-kernel, Stefan Hajnoczi,
David S. Miller, Eugenio Pérez
In-Reply-To: <20260626134823.206676-1-sgarzare@redhat.com>
From: Stefano Garzarella <sgarzare@redhat.com>
Add a test that sends 2 MB of data using randomly sized small packets
(129-512 bytes) over a SOCK_STREAM connection. Packets above
GOOD_COPY_LEN (128) bypass the in-place coalescing in recv_enqueue(),
forcing each one into its own skb.
Without receive queue collapsing, the per-skb overhead eventually
exceeds buf_alloc and the connection is reset. The test verifies
that all data arrives and that content integrity is preserved.
Signed-off-by: Stefano Garzarella <sgarzare@redhat.com>
---
tools/testing/vsock/vsock_test.c | 87 ++++++++++++++++++++++++++++++++
1 file changed, 87 insertions(+)
diff --git a/tools/testing/vsock/vsock_test.c b/tools/testing/vsock/vsock_test.c
index 76be0e4a7f0e..b4ff9f946565 100644
--- a/tools/testing/vsock/vsock_test.c
+++ b/tools/testing/vsock/vsock_test.c
@@ -2347,6 +2347,88 @@ static void test_stream_tx_credit_bounds_server(const struct test_opts *opts)
close(fd);
}
+/* Test that many small packets don't cause a connection reset under pressure
+ * and that data integrity is preserved. Packet sizes vary randomly between
+ * 129 and 512 bytes, above GOOD_COPY_LEN (128) to bypass in-place coalescing
+ * in recv_enqueue, forcing each one into its own skb. Without receive queue
+ * collapsing, the per-skb overhead eventually exceeds buf_alloc and the
+ * connection is reset.
+ */
+#define COLLAPSE_PKT_MIN 129
+#define COLLAPSE_PKT_MAX 512
+#define COLLAPSE_TOTAL (2 * 1024 * 1024)
+
+static void test_stream_collapse_client(const struct test_opts *opts)
+{
+ unsigned char *data;
+ unsigned long hash;
+ size_t offset = 0;
+ int i, fd;
+
+ data = malloc(COLLAPSE_TOTAL);
+ if (!data) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ for (i = 0; i < COLLAPSE_TOTAL; i++)
+ data[i] = rand() & 0xff;
+
+ fd = vsock_stream_connect(opts->peer_cid, opts->peer_port);
+ if (fd < 0) {
+ perror("connect");
+ exit(EXIT_FAILURE);
+ }
+
+ while (offset < COLLAPSE_TOTAL) {
+ size_t pkt_size = COLLAPSE_PKT_MIN +
+ rand() % (COLLAPSE_PKT_MAX - COLLAPSE_PKT_MIN + 1);
+
+ pkt_size = min(pkt_size, COLLAPSE_TOTAL - offset);
+
+ send_buf(fd, data + offset, pkt_size, 0, pkt_size);
+ offset += pkt_size;
+ }
+
+ hash = hash_djb2(data, COLLAPSE_TOTAL);
+ control_writeulong(hash);
+
+ free(data);
+ close(fd);
+}
+
+static void test_stream_collapse_server(const struct test_opts *opts)
+{
+ unsigned long hash, remote_hash;
+ unsigned char *data;
+ int fd;
+
+ data = malloc(COLLAPSE_TOTAL);
+ if (!data) {
+ perror("malloc");
+ exit(EXIT_FAILURE);
+ }
+
+ fd = vsock_stream_accept(VMADDR_CID_ANY, opts->peer_port, NULL);
+ if (fd < 0) {
+ perror("accept");
+ exit(EXIT_FAILURE);
+ }
+
+ recv_buf(fd, data, COLLAPSE_TOTAL, 0, COLLAPSE_TOTAL);
+
+ hash = hash_djb2(data, COLLAPSE_TOTAL);
+ remote_hash = control_readulong();
+ if (hash != remote_hash) {
+ fprintf(stderr, "hash mismatch: local %lu remote %lu\n",
+ hash, remote_hash);
+ exit(EXIT_FAILURE);
+ }
+
+ free(data);
+ close(fd);
+}
+
static struct test_case test_cases[] = {
{
.name = "SOCK_STREAM connection reset",
@@ -2546,6 +2628,11 @@ static struct test_case test_cases[] = {
.run_client = test_stream_msg_peek_client,
.run_server = test_stream_peek_after_recv_server,
},
+ {
+ .name = "SOCK_STREAM small packets backpressure",
+ .run_client = test_stream_collapse_client,
+ .run_server = test_stream_collapse_server,
+ },
{},
};
--
2.54.0
^ permalink raw reply related
* Re: [Bug ?] Packet with End.X segment not correctly forwarded to nexthop
From: Anthony Doeraene @ 2026-06-26 13:54 UTC (permalink / raw)
To: Andrea Mayer; +Cc: netdev, Nicolas Dichtel, stefano.salsano, Paolo Lungaroni
In-Reply-To: <20260624191850.55dd7be54ccc935743f5bc8a@uniroma2.it>
On 24/06/2026 19:18, Andrea Mayer wrote:
> On Fri, 19 Jun 2026 15:25:09 +0200
> Anthony Doeraene <anthony.doeraene@uclouvain.be> wrote:
>
>> Hello,
> Hi Anthony,
> thanks for the description and the reproducer.
Hello Andrea, thank you for the reply.
>
>> I am currently experimenting with SRv6 and VRFs, and I found some weird
>> interactions between the two.
>>
>> For the context, I need routers to have multiple VRFs, with each VRF
>> having different routes to reach destinations.
>> Our routers not only send packets to a specific nexthop, but also
>> specify the VRF that the nexthop
>> should use to forward these packets.
>> To achieve this goal, routes in these VRFs push two segments: a local
>> End.X segment, and a End.DT46 segment.
>> Due to some implementation constraints, I want to have a single End.DT46
>> segment shared by
>> all routers in the network.
>>
>> Once packets are encapsulated by the VRF, the packet is sent in the main
>> table to do a lookup for the nexthop.
>> As the End.DT46 segment is shared between routers and can not be used to
>> learn the nexthop, I decided to
>> use an End.X segment to specify it.
>>
>> However, what I observe in this scenario is that End.X segment
>> processing function is never called, resulting
>> in the packet not being sent to the correct nexthop.
> As I understand it, you are encapsulating a packet on r1 and you want to
> decapsulate it on r2.
>
> The first segment you want to apply on r1 is a local adjacency SID, bound to
> the End.X behavior. When applied, it would force the encapsulated packet
> onto the r1-r2 link toward your neighbour r2, and advance the segment list to
> your next segment, the shared SID bound to End.DT46.
>
> Anyway, as you have noticed, this is not what happens. The reason is that
> the packet is generated locally on r1, so it is on the transmit path. An
> SRv6 endpoint behavior is triggered by a SID in a packet the node receives,
> not in one it originates and transmits. So the End.X behavior is never
> triggered: the packet is just encapsulated and routed using the first
> segment as its destination address, and not steered.
>
> To steer the packet, you need to control the table in which the post-encap
> lookup resolves the first segment. This need already came up for another
> use case, originally introduced by Nicolas Dichtel. We referred to it as
> 'route leaking': the lookup must be done in the underlay table, so the
> encapsulated traffic 'leaks' from the VRF to the underlay.
>
> We worked on a patch for the seg6 encap that lets you choose the FIB table
> for the post-encap lookup. I will post it when net-next reopens. You then
> push only the shared SID and, in a table of your choice, add a route for it
> via your next hop. The post-encap lookup resolves it there, and your next
> hop receives that SID as the active SID and handles it:
>
> # next hop for the shared decap SID, in the table you pick
> ip -6 route add fc00:ffff:: via fc00::1:2 dev r1-r2 table 100
>
> # encap route: segment list is only the shared SID, resolved in table 100
> ip -6 route add fc00::2 encap seg6 mode encap segs fc00:ffff:: \
> lookup 100 table 10 dev X
>
> - X is used just to determine the IPv6 SA of the encapsulated packet;
> - table 10 is the encap route's table; if a VRF is bound to it, you can pass
> vrf <name> instead.
>
> The lookup table can also be your VRF table, so the next-hop route sits next
> to the encap route.
This seems like a very nice approach to solve my problem ! I'm looking
forward to
seeing it being merged in the kernel !
Thank you also for the detailed description about how the kernel treats SRv6
segments, it seems much clearer to me.
>
>> I am wondering if this is an expected behavior (i.e. a node should never
>> push a local segment), or if it is a real bug ?
> It is expected, not a bug. A node may push a local segment. The point is
> that an SRv6 endpoint behavior is not triggered on traffic the node
> originates, as these behaviors run on the receive path.
>
>> I am not well versed into the implementation details of SRv6 in the
>> kernel, but I'm suspecting that this "bug" comes
>> from the fact that seg6_output_core calls dst_output, which does not
>> allow an SRv6 segment function to be called.
> You understood the mechanism correctly. As explained above, seg6_output_core
> ends with dst_output on the output path, so the seg6_local endpoint function
> is not called there and this is by design.
>
>> A minimal example is given below, which creates two namespaces (r1, r2)
>> and allows to reproduce this behavior.
>> (tested on a kernel compiled on virtme-ng from commit
>> e771677c937da5808f7b6c1f0e4a97ec1a84f8a8)
>>
>> Thank you in advance for the help and thanks for the SRv6 support on Linux,
>> Doeraene Anthony
>>
>> File setup.sh
>> ```
>> # Topology under test:
>> #
>> # fc00::1:1 fc00::1:2
>> # fc00::1 [ r1 ] ------------------------- [ r2 ] fc00::2
>> #
>> # Description:
>> # ============
>> #
>> # Each node has an additional VRF, which it can use to provide different
>> # routing decisions based on arbitrary rules (e.g. QoS aware forwarding)
>> # Routes in this VRF will encapsulate the packets and push segments to
>> # specify the nexthop (End.X) and the VRF the nexthop should use
>> # (End.DT46). The same End.DT46 segment is shared by all nodes
>> #
>> # Problem:
>> # ========
>> #
>> # Once segments are pushed, the End.X segment is never applied. As a
>> # result, the segment is not popped from the SL, and the packet is sent
>> # on an incorrect interface.
>> #
>> # Forwarding steps:
>> # =================
>> #
>> # - R1 sends the packet to fc00::2 in its VRF `myvrf`
>> # - This VRF encapsulates the packet and add two segments:
>> # 1) End.X segment to force the transmission of the packet on r1-r2
>> # 2) End.DT46 segment allowing r2 to know which VRF it should use
>> # to forward the packet.
>> # - After encapsulation, r1 does a lookup in its main table for the
>> # End.X segment, but does not pop the segment. The packet is thus
>> # sent incorrectly on the dummy interface
>> #
>> [snip]
>>
>> ```
>>
> Ciao,
> Andrea
Best Regards,
Doeraene Anthony
^ permalink raw reply
* the confusing 10000base_CR. Shouldn't it be 10000_SFI_DA?
From: D H, Siddaraju @ 2026-06-26 14:15 UTC (permalink / raw)
To: netdev@vger.kernel.org
Cc: Das, Shubham, Chintalapalle, Balaji, Srinivasan, Vijay
Hi Linux Ethernet Team,
We explored Ethtool's "10000base_CR" PMD PHY type
and we think it might be just a wrong name.
Why we called 10000Base_CR, a confusing name?
Because it fails all below 4 major highlights of a "typical base-CR"
1. Every other Base-CR is an IEEE defined PMD specs
2. All Base-CR have AN LT (Auto-Negotiation & Link Training)
3. Almost all CR have FEC mandatory
4. IEEE CR is a very close sibling of IEEE KR, the complex ones
There is NO IEEE 802.3 or ANY other standard spec to
support 10000base-CR and the industry fully adopted
SFF-8431 Appendix-E Direct Attach cable as 10G-SFI-DA.
We feel 10000Base_CR must be renamed to 10000_SFI_DA.
SFI: SFP+ high speed serial electrical interface
DA: Direct Attach cable media
Need your inputs for the next step here. Should we,
(a) Submit a patch to rename all instance of 10000baseCR
OR
(b) Create a new enum for SFI_DA and map it to 10000baseCR?
We prefer option-(a) since it completely resolves the confusion
and gives a technically correct name.
- Thank you,
Siddaraju D H
^ permalink raw reply
* Re: [PATCH net v2 1/1] net/sched: sch_teql: Introduce slaves_lock to avoid race condition and UAF
From: Simon Horman @ 2026-06-26 14:15 UTC (permalink / raw)
To: Jamal Hadi Salim
Cc: netdev, davem, edumazet, kuba, pabeni, jiri, victor, security,
zdi-disclosures, stable, kernel test robot
In-Reply-To: <CAM0EoMmJZxAbOsyW7bBp0DbTTiQKZeGaaBHPEw45D5b6DKDEvg@mail.gmail.com>
On Fri, Jun 26, 2026 at 06:16:43AM -0400, Jamal Hadi Salim wrote:
> "
>
> On Wed, Jun 24, 2026 at 6:40 PM Jamal Hadi Salim <jhs@mojatatu.com> wrote:
> >
> > The teql master->slaves singly linked list is not protected against
> > multiple writes. It can be mod'ed concurently from teql_master_xmit(),
> > teql_dequeue(), teql_init() and teql_destroy() without holding any list
> > lock or RCU protection.
> >
> > zdi-disclosures@trendmicro.com has demonstrated that the qdisc is freed
> > after an RCU grace period, but teql_master_xmit() running on another
> > CPU can still hold a stale pointer into the list, resulting in a
> > slab-use-after-free:
> >
> > BUG: KASAN: slab-use-after-free in teql_destroy+0x3ca/0x440 linux/net/sched/sch_teql.c:142
> > Read of size 8 at addr ffff88802923aa80 by task ip/10024
> >
> > The zdi-disclosures@trendmicro.com repro created concurrent AF_PACKET
> > senders on a teql device against a thread that repeatedly adds/deletes the
> > slave qdisc, together with a SLUB spray that reclaims the freed slot; the
> > resulting UAF is controllable enough to be turned into a read/write
> > primitive against the freed qdisc object.
> >
> > The fix?
> > Add a per-master slaves_lock spinlock that serializes all mutations of
> > master->slaves and the NEXT_SLAVE() links in teql_destroy() and
> > teql_qdisc_init(). teql_master_xmit() also takes the same slaves_lock
> > around those updates.
> > Annotate master->slaves and the per-slave ->next pointer with __rcu and
> > use the appropriate RCU accessors everywhere they are touched:
> > rcu_assign_pointer() on the writer side (under slaves_lock),
> > rcu_dereference_protected() for the writer-side loads (also under
> > slaves_lock), rcu_dereference_bh() for the loads in teql_master_xmit() and
> > rtnl_dereference() for the loads in teql_master_open()/teql_master_mtu(),
> > which run under RTNL.
> > Pair this with rcu_read_lock_bh()/rcu_read_unlock_bh() around the list
> > traversal in teql_master_xmit(), so that readers either observe a fully
> > linked list or are deferred until the in-flight mutation completes. The two
> > early-return paths in teql_master_xmit() are updated to release the RCU-bh
> > read-side critical section before returning, since leaving it held would
> > disable BH on that CPU for good.
> >
>
> sashiko-gemini's complaints:
> https://sashiko.dev/#/patchset/20260624224016.24018-1-jhs%40mojatatu.com
> seem bogus to me (someone correct me if i am wrong). I am only going
> to address the first claim of "TOCTOU / "resurrection" race in
> teql_master_xmit()"
> teql_master_xmit() holds rcu_read_lock_bh() across the entire
> traversal. teql_destroy() freeing can only proceed once the qdisc's
> RCU grace period has elapsed - so where is this TOCTOU? Let's say this
> were true: both calls hold the slaves_lock.
> The other issues are of similar nature.
Hi Jamal,
I think the central question here is about the protection offered by RCU
in these code paths. And while I agree it protects the use of elements
of the list, I think the problem flagged relates to the management of
the list itself.
The example AI gave me when I asked is like this:
Assume a TEQL master has one slave, `q`.
The list is circular: `q->next == q`.
1. CPU A (Transmitting): Enters `teql_master_xmit()`.
It reads `master->sla ves` and gets a local pointer to `q`.
2. CPU B (Destroying): Calls `teql_destroy(q)`.
It takes the lock, unlinks `q`, and sets `master->slaves = NULL`.
The list is now logically empty.
3. CPU A: Finishes its work and prepares to rotate the list head
to the next slave.
It takes the lock.
4. CPU A (The "Use" / The Resurrection):
It executes: `rcu_assign_pointer(master->slaves, NEXT_SLAVE(q));`
Because `q` was circular, `NEXT_SLAVE(q)` is still `q`.
5. CPU A: Releases the lock.
**The global `master->slaves` is now `q` again.**
6. The System: The RCU grace period expires. CPU B finishes
`teql_destroy()` and the memory for `q` is freed.
The global `master->slaves` pointer is now a **dangling pointer**
pointing to freed memory.
> OTOH, sashiko-claude
> (https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260624224016.24018-1-jhs%40mojatatu.com)
> does make some valid claims which are low value, so not sure a resend
> is worth it.
> For example in claim 1 it says "Should the changelog mention this
> teql_dequeue() site too?" Sure I can - but just because I provided
> extra information in the commit log, which I could have omitted, now I
> have to add more info? ;->
FWIIW, I think there is a value in tightening up the commit message.
E.g. so it's accurate when we look at again in two years time.
But I also lean towards it not being necessary to post an update
only to address this.
> The second claim is "rcu_dereference_bh()
> should be rcu_dereference_protected() on writer side". Sparse didnt
> complain and i dont see this as breakage rather a consistency measure.
I think it would be good to address in the long run. But as per my comment
immediately above, I also lean towards it not being necessary to post an
update only to address this.
> Unless I am missing something ..
>
> cheers,
> jamal
^ permalink raw reply
* Re: the confusing 10000base_CR. Shouldn't it be 10000_SFI_DA?
From: Andrew Lunn @ 2026-06-26 14:32 UTC (permalink / raw)
To: D H, Siddaraju
Cc: netdev@vger.kernel.org, Das, Shubham, Chintalapalle, Balaji,
Srinivasan, Vijay
In-Reply-To: <MW4PR11MB6912A234CAAAFD25EAC7C8909AEB2@MW4PR11MB6912.namprd11.prod.outlook.com>
On Fri, Jun 26, 2026 at 02:15:27PM +0000, D H, Siddaraju wrote:
> Hi Linux Ethernet Team,
>
> We explored Ethtool's "10000base_CR" PMD PHY type
> and we think it might be just a wrong name.
~/linux$ grep -r 10000Base_CR
~/linux$
~/ethtool$ grep -r 10000Base_CR
~/ethtool$
What exactly do you mean by 10000Base_CR?
Andrew
^ permalink raw reply
* Re: the confusing 10000base_CR. Shouldn't it be 10000_SFI_DA?
From: Maxime Chevallier @ 2026-06-26 14:33 UTC (permalink / raw)
To: D H, Siddaraju, netdev@vger.kernel.org
Cc: Das, Shubham, Chintalapalle, Balaji, Srinivasan, Vijay
In-Reply-To: <MW4PR11MB6912A234CAAAFD25EAC7C8909AEB2@MW4PR11MB6912.namprd11.prod.outlook.com>
Hi,
On 6/26/26 16:15, D H, Siddaraju wrote:
> Hi Linux Ethernet Team,
>
> We explored Ethtool's "10000base_CR" PMD PHY type
> and we think it might be just a wrong name.
>
> Why we called 10000Base_CR, a confusing name?
> Because it fails all below 4 major highlights of a "typical base-CR"
> 1. Every other Base-CR is an IEEE defined PMD specs
> 2. All Base-CR have AN LT (Auto-Negotiation & Link Training)
> 3. Almost all CR have FEC mandatory
> 4. IEEE CR is a very close sibling of IEEE KR, the complex ones
>
> There is NO IEEE 802.3 or ANY other standard spec to
> support 10000base-CR and the industry fully adopted
> SFF-8431 Appendix-E Direct Attach cable as 10G-SFI-DA.
>
> We feel 10000Base_CR must be renamed to 10000_SFI_DA.
> SFI: SFP+ high speed serial electrical interface
> DA: Direct Attach cable media
Well it's too late for a rename, this is part of the userspace API
so this name is here to stay :
https://elixir.bootlin.com/linux/v7.1.1/source/include/uapi/linux/ethtool.h#L2013
This was introduced in 2016, I think we won't gain much by adding
another linkmode that's equivalent. Even if this isn't strictly
speaking the correct mode, even some vendors sell their DA cable
as 10GBaseCR cables now :/
Maxime
^ permalink raw reply
* [PATCH net v1] cxgb4: flower: fix 802.1ad VLAN TPID matching in tc flower filters
From: Harsha M @ 2026-06-26 13:48 UTC (permalink / raw)
To: netdev; +Cc: davem, kuba, edumazet, pabeni, andrew+netdev, bharat, Harsha M
The cxgb4 driver does not correctly handle tc flower filters that
match on an 802.1ad (Q-in-Q) outer VLAN tag. While the VLAN VID is
processed, the specified 802.1ad TPID is not programmed into the
adapter's outer VLAN matching configuration, resulting in incorrect
filter matches.
Fix this by configuring the port-specific OVLAN register with the
requested TPID value and mask, enabling OVLAN matching through the RX
control register, and populating the filter specification with the
outer VLAN VID and valid-bit match fields when an 802.1ad TPID is
requested.This restores correct matching for tc flower filters that
specify an 802.1ad outer VLAN tag
Signed-off-by: Harsha M <h.mahadeva@chelsio.com>
Signed-off-by: Potnuri Bharat Teja <bharat@chelsio.com>
---
.../ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 62 +++++++++++++------
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 3 +
2 files changed, 47 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index 3307e5042681..41a2998ee2a0 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -40,6 +40,7 @@
#include "cxgb4.h"
#include "cxgb4_filter.h"
#include "cxgb4_tc_flower.h"
+#include "t4_regs.h"
#define STATS_CHECK_PERIOD (HZ / 2)
@@ -266,24 +267,49 @@ static void cxgb4_process_flow_match(struct net_device *dev,
VLAN_PRIO_SHIFT);
vlan_tci_mask = match.mask->vlan_id | (match.mask->vlan_priority <<
VLAN_PRIO_SHIFT);
- fs->val.ivlan = vlan_tci;
- fs->mask.ivlan = vlan_tci_mask;
-
- fs->val.ivlan_vld = 1;
- fs->mask.ivlan_vld = 1;
-
- /* Chelsio adapters use ivlan_vld bit to match vlan packets
- * as 802.1Q. Also, when vlan tag is present in packets,
- * ethtype match is used then to match on ethtype of inner
- * header ie. the header following the vlan header.
- * So, set the ivlan_vld based on ethtype info supplied by
- * TC for vlan packets if its 802.1Q. And then reset the
- * ethtype value else, hw will try to match the supplied
- * ethtype value with ethtype of inner header.
- */
- if (fs->val.ethtype == ETH_P_8021Q) {
- fs->val.ethtype = 0;
- fs->mask.ethtype = 0;
+
+ if (be16_to_cpu(match.key->vlan_tpid) == ETH_P_8021AD) {
+ struct adapter *adap = netdev2adap(dev);
+ u32 ovlan_reg, ctl_reg, val, port_id;
+
+ if (!adap) {
+ netdev_err(dev, "%s: adap not found\n", __func__);
+ return;
+ }
+
+ val = (be16_to_cpu(match.mask->vlan_tpid) << 16) |
+ be16_to_cpu(match.key->vlan_tpid);
+ port_id = netdev2pinfo(dev)->port_id;
+ fs->val.ovlan = vlan_tci;
+ fs->mask.ovlan = vlan_tci_mask;
+ fs->val.ovlan_vld = 1;
+ fs->mask.ovlan_vld = 1;
+ ovlan_reg = PORT_REG(port_id, MPS_PORT_RX_OVLAN0_A);
+ ctl_reg = PORT_REG(port_id, MPS_PORT_RX_CTL_A);
+ t4_write_reg(adap, ovlan_reg, val);
+ val = t4_read_reg(adap, ctl_reg);
+ t4_write_reg(adap, ctl_reg, val | 1);
+ t4_tp_wr_bits_indirect(adap, TP_INGRESS_CONFIG_A, 1U << 9, 0);
+ } else {
+ fs->val.ivlan = vlan_tci;
+ fs->mask.ivlan = vlan_tci_mask;
+ fs->val.ivlan_vld = 1;
+ fs->mask.ivlan_vld = 1;
+
+ /* Chelsio adapters use ivlan_vld bit to match vlan packets
+ * as 802.1Q. Also, when vlan tag is present in packets,
+ * ethtype match is used then to match on ethtype of inner
+ * header ie. the header following the vlan header.
+ * So, set the ivlan_vld based on ethtype info supplied by
+ * TC for vlan packets if its 802.1Q. And then reset the
+ * ethtype value else, hw will try to match the supplied
+ * ethtype value with ethtype of inner header.
+ */
+
+ if (fs->val.ethtype == ETH_P_8021Q) {
+ fs->val.ethtype = 0;
+ fs->mask.ethtype = 0;
+ }
}
}
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index 695916ba0405..38c585f3b1ad 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -1921,6 +1921,9 @@
#define MAC_PORT_PTP_SUM_LO_A 0x990
#define MAC_PORT_PTP_SUM_HI_A 0x994
+#define MPS_PORT_RX_OVLAN0_A 0x120
+#define MPS_PORT_RX_CTL_A 0X100
+
#define MPS_CMN_CTL_A 0x9000
#define COUNTPAUSEMCRX_S 5
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v6 07/10] rust: configfs: use `LocalModule` for `THIS_MODULE`
From: Gary Guo @ 2026-06-26 14:41 UTC (permalink / raw)
To: Alvin Sun, Gary Guo, Miguel Ojeda, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Luis Chamberlain, Petr Pavlu,
Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
Jens Axboe, Dave Ertman, Leon Romanovsky, Igor Korotin,
FUJITA Tomonori, Bjorn Helgaas, Krzysztof Wilczyński,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas
Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
linux-kselftest, kunit-dev, linux-block, linux-kernel, netdev,
linux-pci
In-Reply-To: <34a009d9-a1f3-4347-9e92-866ec05ddb60@linux.dev>
On Fri Jun 26, 2026 at 3:35 AM BST, Alvin Sun wrote:
>
> On 6/25/26 22:40, Gary Guo wrote:
>> On Wed Jun 24, 2026 at 4:00 PM BST, Alvin Sun wrote:
>>> Replace the `THIS_MODULE` static reference in the `configfs_attrs!`
>>> macro with `this_module::<LocalModule>()`, and update
>>> rnull to import `LocalModule` instead of `THIS_MODULE`, consistent
>>> with the move of `THIS_MODULE` into the `ModuleMetadata` trait.
>>>
>>> Assisted-by: opencode:glm-5.2
>>> Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
>>> Acked-by: Danilo Krummrich <dakr@kernel.org>
>>> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
>>> ---
>>> drivers/block/rnull/configfs.rs | 6 ++----
>>> rust/kernel/configfs.rs | 8 +++++---
>>> 2 files changed, 7 insertions(+), 7 deletions(-)
>>>
>>> diff --git a/drivers/block/rnull/configfs.rs b/drivers/block/rnull/configfs.rs
>>> index c10a55fc58948..b2547ad1e5ddd 100644
>>> --- a/drivers/block/rnull/configfs.rs
>>> +++ b/drivers/block/rnull/configfs.rs
>>> @@ -1,9 +1,7 @@
>>> // SPDX-License-Identifier: GPL-2.0
>>>
>>> -use super::{
>>> - NullBlkDevice,
>>> - THIS_MODULE, //
>>> -};
>>> +use super::NullBlkDevice;
>>> +use crate::LocalModule;
>>> use kernel::{
>>> block::mq::gen_disk::{
>>> GenDisk,
>>> diff --git a/rust/kernel/configfs.rs b/rust/kernel/configfs.rs
>>> index 2339c6467325d..c31d7882e216d 100644
>>> --- a/rust/kernel/configfs.rs
>>> +++ b/rust/kernel/configfs.rs
>>> @@ -875,7 +875,7 @@ fn as_ptr(&self) -> *const bindings::config_item_type {
>>> /// configfs::Subsystem<Configuration>,
>>> /// Configuration
>>> /// >::new_with_child_ctor::<N,Child>(
>>> -/// &THIS_MODULE,
>>> +/// ::kernel::module::this_module::<crate::LocalModule>(),
>>> /// &CONFIGURATION_ATTRS
>>> /// );
>>> ///
>>> @@ -1021,7 +1021,8 @@ macro_rules! configfs_attrs {
>>>
>>> static [< $data:upper _TPE >] : $crate::configfs::ItemType<$container, $data> =
>>> $crate::configfs::ItemType::<$container, $data>::new::<N>(
>>> - &THIS_MODULE, &[<$ data:upper _ATTRS >]
>>> + $crate::module::this_module::<LocalModule>(),
>> ^ You only changed one single place. This is still plain `LocalModule`.
>
> Initially I wrote it as `crate::LocalModule`, but clippy warned about it. So
> instead of putting the crate path in the macro body, I added `use
> crate::LocalModule` in the calling file.
>
> ```
> warning: `crate` references the macro call's crate
> --> rust/kernel/configfs.rs:1024:59
> |
> 1024 | ... $crate::module::this_module::<crate::LocalModule>(),
> | ^^^^^ help:
> to reference the macro definition's crate, use: `$crate`
> |
> = help: for further information visit
> https://rust-lang.github.io/rust-clippy/rust-1.94.0/index.html#crate_in_macro_def
> = note: `-W clippy::crate-in-macro-def` implied by `-W clippy::all`
> = help: to override `-W clippy::all` add
> `#[allow(clippy::crate_in_macro_def)]`
>
> warning: 1 warning emitted
> ```
Clippy has a point about `crate::` being usually wrong in macros, but it is what
we actually want here, so obviously you should allow the warning.
It is the exact same case in `vtable` macro, just that Clippy is unable to check
proc macros!
Best,
Gary
>
> Alternatively, `#[allow(clippy::crate_in_macro_def)]` could be added on
> the macro
> definition. Would you suggest that approach?
^ permalink raw reply
* Re: [PATCH v6 10/10] rust: module: update MAINTAINERS to cover module.rs
From: Gary Guo @ 2026-06-26 14:41 UTC (permalink / raw)
To: Alvin Sun, Gary Guo, Miguel Ojeda, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Luis Chamberlain, Petr Pavlu,
Daniel Gomez, Sami Tolvanen, Aaron Tomlin, Greg Kroah-Hartman,
Rafael J. Wysocki, David Airlie, Simona Vetter, Daniel Almeida,
Arnd Bergmann, Brendan Higgins, David Gow, Rae Moar, Breno Leitao,
Jens Axboe, Dave Ertman, Leon Romanovsky, Igor Korotin,
FUJITA Tomonori, Bjorn Helgaas, Krzysztof Wilczyński,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas
Cc: rust-for-linux, linux-modules, driver-core, dri-devel, nova-gpu,
linux-kselftest, kunit-dev, linux-block, linux-kernel, netdev,
linux-pci
In-Reply-To: <6d2b7611-41ec-45f0-a155-3b5c90c5d883@linux.dev>
On Fri Jun 26, 2026 at 4:01 AM BST, Alvin Sun wrote:
>
> On 6/25/26 22:39, Gary Guo wrote:
>> On Wed Jun 24, 2026 at 4:00 PM BST, Alvin Sun wrote:
>>> Module types now live in `rust/kernel/module.rs` alongside
>>> `rust/kernel/module_param.rs`. Update the MODULE SUPPORT file pattern
>>> from `rust/kernel/module_param.rs` to `rust/kernel/module*.rs` so both
>>> files are covered.
>>>
>>> Assisted-by: opencode:glm-5.2
>> Did you actually use a LLM for this patch even? :)
>
> Yes, I've created a skill that generates commit messages for the code I
> modify
> manually.
>
>>
>>> Link: https://lore.kernel.org/rust-for-linux/8ea21b29-9baf-4926-a16f-7d21c5a1a1b8@suse.com
>>> Signed-off-by: Alvin Sun <alvin.sun@linux.dev>
>> This patch should probably be squashed into the actual move, i.e. patch 1.
>
> Sure. Looking at the change history of the `MAINTAINERS` file, the
> modifications
> are always in standalone commits, so I followed the same convention.
Right, you can keep this as is then.
Best,
Gary
^ permalink raw reply
* [PATCH net] selftests: net: make busywait timeout clock portable
From: Nirmoy Das @ 2026-06-26 14:49 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Shuah Khan
Cc: netdev, linux-kselftest, stable
loopy_wait() expects millisecond timestamps. However, Ubuntu Resolute
can use uutils date, where `date -u +%s%3N` returns seconds plus full
nanoseconds instead of a 3-digit millisecond field. This makes
busywait expire too early and can make vlan_bridge_binding.sh read a
stale operstate.
Fixes: 25ae948b4478 ("selftests/net: add lib.sh")
Cc: stable@vger.kernel.org # 6.8+
Link: https://github.com/uutils/coreutils/issues/11658
Signed-off-by: Nirmoy Das <nirmoyd@nvidia.com>
---
tools/testing/selftests/net/lib.sh | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/net/lib.sh b/tools/testing/selftests/net/lib.sh
index b40694573f4c7..fcaec058be6d0 100644
--- a/tools/testing/selftests/net/lib.sh
+++ b/tools/testing/selftests/net/lib.sh
@@ -70,12 +70,27 @@ ksft_exit_status_merge()
$ksft_xfail $ksft_pass $ksft_skip $ksft_fail
}
+timestamp_ms()
+{
+ local now=$(date -u +%s:%N)
+ local seconds=${now%:*}
+ local nanoseconds=${now#*:}
+
+ if [[ $nanoseconds =~ ^[0-9]+$ ]]; then
+ nanoseconds=${nanoseconds:0:9}
+ else
+ nanoseconds=0
+ fi
+
+ echo $((seconds * 1000 + 10#$nanoseconds / 1000000))
+}
+
loopy_wait()
{
local sleep_cmd=$1; shift
local timeout_ms=$1; shift
- local start_time="$(date -u +%s%3N)"
+ local start_time=$(timestamp_ms)
while true
do
local out
@@ -84,7 +99,7 @@ loopy_wait()
return 0
fi
- local current_time="$(date -u +%s%3N)"
+ local current_time=$(timestamp_ms)
if ((current_time - start_time > timeout_ms)); then
echo -n "$out"
return 1
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net v2 1/2] net: mana: Sync page pool RX frags for CPU
From: Simon Horman @ 2026-06-26 14:50 UTC (permalink / raw)
To: Dexuan Cui
Cc: kys, haiyangz, wei.liu, longli, andrew+netdev, davem, edumazet,
kuba, pabeni, kotaranov, ernis, dipayanroy, kees, jacob.e.keller,
ssengar, linux-hyperv, netdev, linux-kernel, linux-rdma, stable
In-Reply-To: <20260624222605.1794719-2-decui@microsoft.com>
On Wed, Jun 24, 2026 at 03:26:04PM -0700, Dexuan Cui wrote:
> MANA allocates RX buffers from page pool fragments when frag_count is
> greater than 1. In that case the buffers remain DMA mapped by page pool
> and the RX completion path does not call dma_unmap_single(). As a result,
> the implicit sync-for-CPU normally performed by dma_unmap_single() is
> missing before the packet data is passed to the networking stack.
>
> This breaks RX on configurations which require explicit DMA syncing, for
> example when booted with swiotlb=force.
>
> Fix this by recording the page pool page and DMA sync offset when the RX
> buffer is allocated, and syncing the received packet range for CPU access
> before handing the RX buffer to the stack.
>
> Fixes: 730ff06d3f5c ("net: mana: Use page pool fragments for RX buffers instead of full pages to improve memory efficiency.")
> Cc: stable@vger.kernel.org
> Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
> Signed-off-by: Dexuan Cui <decui@microsoft.com>
> ---
>
> Changes since v1:
> v1 is split into two patches in the v2.
> Add Haiyang's Reviewed-by.
>
> drivers/net/ethernet/microsoft/mana/mana_en.c | 39 +++++++++++++++----
> include/net/mana/mana.h | 8 ++++
> 2 files changed, 40 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
> index c9b1df1ed109..1875bffd82b7 100644
> --- a/drivers/net/ethernet/microsoft/mana/mana_en.c
> +++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
> @@ -2044,12 +2044,16 @@ static void mana_rx_skb(void *buf_va, bool from_pool,
> }
>
> static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
> - dma_addr_t *da, bool *from_pool)
> + dma_addr_t *da, bool *from_pool,
> + struct page **pp_page, u32 *dma_sync_offset)
> {
> struct page *page;
> u32 offset;
> void *va;
> +
> *from_pool = false;
> + *pp_page = NULL;
> + *dma_sync_offset = 0;
>
> /* Don't use fragments for jumbo frames or XDP where it's 1 fragment
> * per page.
> @@ -2087,31 +2091,47 @@ static void *mana_get_rxfrag(struct mana_rxq *rxq, struct device *dev,
> va = page_to_virt(page) + offset;
> *da = page_pool_get_dma_addr(page) + offset + rxq->headroom;
> *from_pool = true;
> + *pp_page = page;
> + *dma_sync_offset = offset + rxq->headroom;
>
> return va;
> }
>
> /* Allocate frag for rx buffer, and save the old buf */
> static void mana_refill_rx_oob(struct device *dev, struct mana_rxq *rxq,
> - struct mana_recv_buf_oob *rxoob, void **old_buf,
> - bool *old_fp)
> + struct mana_recv_buf_oob *rxoob, u32 pktlen,
> + void **old_buf, bool *old_fp)
> {
> + struct page *pp_page;
> + u32 dma_sync_offset;
> bool from_pool;
> dma_addr_t da;
> void *va;
>
> - va = mana_get_rxfrag(rxq, dev, &da, &from_pool);
> + va = mana_get_rxfrag(rxq, dev, &da, &from_pool, &pp_page,
> + &dma_sync_offset);
> if (!va)
> return;
> - if (!rxoob->from_pool || rxq->frag_count == 1)
> + if (!rxoob->from_pool || rxq->frag_count == 1) {
> dma_unmap_single(dev, rxoob->sgl[0].address, rxq->datasize,
> DMA_FROM_DEVICE);
> + } else {
> + /* The page pool maps the whole page and only syncs for device
> + * automatically (PP_FLAG_DMA_SYNC_DEV). Sync the received bytes
> + * for the CPU before they are read: this is required if DMA
> + * is incoherent or bounce buffers are used.
> + */
> + page_pool_dma_sync_for_cpu(rxq->page_pool, rxoob->pp_page,
> + rxoob->dma_sync_offset, pktlen);
> + }
Hi,
I'm sorry to be bothersome but I think that the order of the two patches
that comprise this series should be reversed. Or if that is not possible,
go back to a single patch.
Because, as flagged by https://netdev-ai.bots.linux.dev/sashiko/
Is pktlen here bounded before it reaches page_pool_dma_sync_for_cpu()?
The value originates from oob->ppi[i].pkt_len in mana_process_rx_cqe()
and is forwarded straight into this call with no comparison against
rxq->datasize or (rxq->alloc_size - rxoob->dma_sync_offset).
When SWIOTLB is in use (the swiotlb=force case explicitly called out in
the commit message), page_pool_dma_sync_for_cpu() reaches
dma_sync_single_range_for_cpu() and copies dma_sync_size bytes from the
bounce buffer back into the original page.
Since alloc_size can be smaller than PAGE_SIZE and multiple fragments
share a single page_pool page, can a pktlen larger than the fragment
extent here cause the copy-back to spill past this fragment into
neighbouring fragments that belong to other rxoobs still in flight?
If so, those neighbours may already have been or may shortly be passed
up via napi_gro_receive() in mana_rx_skb(), so the over-sync would
silently overwrite their payloads before the eventual skb_put() in
mana_build_skb() trips skb_over_panic() on this oversized packet.
Would it make sense to validate pktlen against rxq->datasize before
calling mana_refill_rx_oob()? The follow-up patch in this series,
"net: mana: Validate the packet length reported by the NIC" (commit
6c707fe658d6), adds exactly that check:
if (unlikely(pktlen > rxq->datasize))
...
Could that validation be folded into this patch so that the sync-for-CPU
introduced here cannot be steered with an attacker-controlled length,
particularly given that the motivating scenario (swiotlb=force) is the
Confidential VM case where the hypervisor-supplied CQE is untrusted?
^ permalink raw reply
* detection and reporting of replacement and aftermarket parts
From: David Heidelberg @ 2026-06-26 15:01 UTC (permalink / raw)
To: linux-input, netdev, Dmitry Torokhov, LKML; +Cc: Petr Hodina
Hello.
As we port Linux phones to the mainline kernel, we often encounter devices with
replaced screens (and touchscreens).
Many these devices are replaced with original parts, but mostly in Asia markets,
very often replacement parts are not original, but knockoffs.
I would see value in providing information via tools and/or GUI [1] to the
users, that parts of their phone has been replaced.
There is multiple reasons, including user awareness when buying the device, or
developer debugging user problem being aware that device been serviced.
Right now, I'm not aware any vendor (outside of Apple, which is unsupported by
Linux) shipping list of serial number of the components in the phone inside some
memory region or EEPROM.
When we **can** do with information currently available, is to detect:
1. different chip used, than what manufacturer declared (e.g. matching the
model device-tree compatible property), thus implying replacement part
2. the chip not being fully compliant with the vendor specification, thus
implying non-original part
This doesn't cover all cases, but could already give user and developer valuable
information why:
1. component isn't fully supported (let say driver doesn't have support for this
variant)
2. component misbehave, if non-original part doesn't follow specification properly
I think the display/touchscreen part is most often affected, so thus why I would
like to start discussion here, but I think this issue apply to many other
components (I recall some FTDI discussions long time ago)
In the end, would be nice to have devlink-info-like [2] reporting in the input
subsystem extended by not only reporting on-device / in-memory firmware, but
also the driver reporting non-complaint non-original replacements (Cc: netdev).
I'm very interested in feedback or/and ideas how this situations can be handled.
Thank you
David
[1] https://support.apple.com/en-us/102658
[2] https://docs.kernel.org/networking/devlink/devlink-info.html
^ permalink raw reply
* RE: [Intel-wired-lan] [PATCH net v7 3/4] iavf: send MAC change request synchronously
From: Kwapulinski, Piotr @ 2026-06-26 15:04 UTC (permalink / raw)
To: Jose Ignacio Tornos Martinez, netdev@vger.kernel.org
Cc: intel-wired-lan@lists.osuosl.org, Kitszel, Przemyslaw,
Loktionov, Aleksandr, Keller, Jacob E, horms@kernel.org,
Nguyen, Anthony L, davem@davemloft.net, edumazet@google.com,
kuba@kernel.org, pabeni@redhat.com, stable@vger.kernel.org
In-Reply-To: <20260623101800.991293-4-jtornosm@redhat.com>
>-----Original Message-----
>From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf Of Jose Ignacio Tornos Martinez
>Sent: Tuesday, June 23, 2026 12:18 PM
>To: netdev@vger.kernel.org
>Cc: intel-wired-lan@lists.osuosl.org; Kitszel, Przemyslaw <przemyslaw.kitszel@intel.com>; Loktionov, Aleksandr <aleksandr.loktionov@intel.com>; Keller, Jacob E <jacob.e.keller@intel.com>; horms@kernel.org; Nguyen, Anthony L <anthony.l.nguyen@intel.com>; davem@davemloft.net; edumazet@google.com; kuba@kernel.org; pabeni@redhat.com; Jose Ignacio Tornos Martinez <jtornosm@redhat.com>; stable@vger.kernel.org
>Subject: [Intel-wired-lan] [PATCH net v7 3/4] iavf: send MAC change request synchronously
>
>After commit ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations"), iavf_set_mac() is called with the netdev instance lock already held.
>
>The function queues a MAC address change request via
>iavf_replace_primary_mac() and then waits for completion. However, in the current flow, the actual virtchnl message is sent by the watchdog task, which also needs to acquire the netdev lock to run. Additionally, the adminq_task which processes virtchnl responses also needs the netdev lock.
>
>This creates a deadlock scenario:
>1. iavf_set_mac() holds netdev lock and waits for MAC change 2. Watchdog needs netdev lock to send the request -> blocked 3. Even if request is sent, adminq_task needs netdev lock to process
> PF response -> blocked
>4. MAC change times out after 2.5 seconds 5. iavf_set_mac() returns -EAGAIN
>
>This particularly affects VFs during bonding setup when multiple VFs are enslaved in quick succession.
>
>Fix by implementing a synchronous MAC change operation similar to the approach used in commit fdadbf6e84c4 ("iavf: fix incorrect reset handling in callbacks").
>
>The solution:
>1. Send the virtchnl ADD_ETH_ADDR message directly (not via watchdog) 2. Poll the admin queue hardware directly for responses 3. Process all received messages (including non-MAC messages) 4. Return when MAC change completes or times out
>
>A new generic function iavf_poll_virtchnl_response() is introduced that can be reused for any future synchronous virtchnl operations. It takes a callback to check completion, allowing flexible condition checking.
>
>This allows the operation to complete synchronously while holding netdev_lock, without relying on watchdog or adminq_task. The function can sleep for up to 2.5 seconds polling hardware, but this is acceptable since netdev_lock is per-device and only serializes operations on the same interface.
>
>To support this, change iavf_add_ether_addrs() to return an error code instead of void, allowing callers to detect failures. Additionally, export iavf_mac_add_reject() to enable proper rollback on local failures (timeouts, send errors) - PF rejections are already handled automatically by iavf_virtchnl_completion().
>
>Remove vc_waitqueue entirely because iavf_set_mac was the only waiter on this waitqueue and after the changes it is not needed.
>
>Fixes: ad7c7b2172c3 ("net: hold netdev instance lock during sysfs operations")
>cc: stable@vger.kernel.org
>Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
>---
>v7: Rebase on current net tree
> Remove the multi-batch processing loop from version 6 according to Przemek
> Kitszel review: the loop cannot work without polling between iterations
> since the second call would fail the current_op check. Multi-batch scenario
> is extremely rare; send first batch and let watchdog handle remainder as v5
> did
>v6: https://lore.kernel.org/all/20260619061321.8554-4-jtornosm@redhat.com/
>
> drivers/net/ethernet/intel/iavf/iavf.h | 11 ++-
> drivers/net/ethernet/intel/iavf/iavf_main.c | 85 ++++++++++++----
> .../net/ethernet/intel/iavf/iavf_virtchnl.c | 99 +++++++++++++++++--
> 3 files changed, 165 insertions(+), 30 deletions(-)
>
>diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h
>index 050f8241ef5e..5fcbfa0ca855 100644
>--- a/drivers/net/ethernet/intel/iavf/iavf.h
>+++ b/drivers/net/ethernet/intel/iavf/iavf.h
>@@ -259,7 +259,6 @@ struct iavf_adapter {
> struct work_struct adminq_task;
> struct work_struct finish_config;
> wait_queue_head_t down_waitqueue;
>- wait_queue_head_t vc_waitqueue;
> struct iavf_q_vector *q_vectors;
> struct list_head vlan_filter_list;
> int num_vlan_filters;
>@@ -588,8 +587,9 @@ void iavf_configure_queues(struct iavf_adapter *adapter); void iavf_enable_queues(struct iavf_adapter *adapter); void iavf_disable_queues(struct iavf_adapter *adapter); void iavf_map_queues(struct iavf_adapter *adapter); -void iavf_add_ether_addrs(struct iavf_adapter *adapter);
>+int iavf_add_ether_addrs(struct iavf_adapter *adapter);
> void iavf_del_ether_addrs(struct iavf_adapter *adapter);
>+void iavf_mac_add_reject(struct iavf_adapter *adapter);
> void iavf_add_vlans(struct iavf_adapter *adapter); void iavf_del_vlans(struct iavf_adapter *adapter); void iavf_set_promiscuous(struct iavf_adapter *adapter); @@ -606,6 +606,13 @@ void iavf_disable_vlan_stripping(struct iavf_adapter *adapter); void iavf_virtchnl_completion(struct iavf_adapter *adapter,
> enum virtchnl_ops v_opcode,
> enum iavf_status v_retval, u8 *msg, u16 msglen);
>+int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
>+ struct iavf_arq_event_info *event,
>+ bool (*condition)(struct iavf_adapter *adapter,
>+ const void *data,
>+ enum virtchnl_ops v_op),
>+ const void *cond_data,
>+ unsigned int timeout_ms);
> int iavf_config_rss(struct iavf_adapter *adapter); void iavf_cfg_queues_bw(struct iavf_adapter *adapter); void iavf_cfg_queues_quanta_size(struct iavf_adapter *adapter); diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
>index 630388e9d28c..3fa288e3798a 100644
>--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
>+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
>@@ -1029,6 +1029,60 @@ static bool iavf_is_mac_set_handled(struct net_device *netdev,
> return ret;
> }
>
>+/**
>+ * iavf_mac_change_done - Check if MAC change completed
>+ * @adapter: board private structure
>+ * @data: MAC address being checked (as const void *)
>+ * @v_op: virtchnl opcode from processed message
>+ *
>+ * Callback for iavf_poll_virtchnl_response() to check if MAC change completed.
>+ *
>+ * Return: true if MAC change completed, false otherwise */ static
>+bool iavf_mac_change_done(struct iavf_adapter *adapter,
>+ const void *data, enum virtchnl_ops v_op) {
>+ const u8 *addr = data;
>+
>+ return iavf_is_mac_set_handled(adapter->netdev, addr); }
>+
>+/**
>+ * iavf_set_mac_sync - Synchronously change MAC address
>+ * @adapter: board private structure
>+ * @addr: MAC address to set
>+ *
>+ * Send MAC change request to PF and poll admin queue for response.
>+ * Caller must hold netdev_lock. This can sleep for up to 2.5 seconds.
>+ * Event buffer is allocated before sending to avoid state mismatch if
>+ * allocation fails after message is sent to PF.
>+ *
>+ * Return: 0 on success, negative on failure */ static int
>+iavf_set_mac_sync(struct iavf_adapter *adapter, const u8 *addr) {
>+ struct iavf_arq_event_info event;
>+ int ret;
>+
>+ netdev_assert_locked(adapter->netdev);
>+
>+ event.buf_len = IAVF_MAX_AQ_BUF_SIZE;
>+ event.msg_buf = kzalloc(event.buf_len, GFP_KERNEL);
>+ if (!event.msg_buf)
>+ return -ENOMEM;
>+
>+ ret = iavf_add_ether_addrs(adapter);
>+ if (ret)
>+ goto out;
>+
>+ ret = iavf_poll_virtchnl_response(adapter, &event,
>+ iavf_mac_change_done, addr, 2500);
>+
>+out:
>+ kfree(event.msg_buf);
>+ return ret;
>+}
>+
> /**
> * iavf_set_mac - NDO callback to set port MAC address
> * @netdev: network interface device structure @@ -1049,25 +1103,23 @@ static int iavf_set_mac(struct net_device *netdev, void *p)
> return -EADDRNOTAVAIL;
>
> ret = iavf_replace_primary_mac(adapter, addr->sa_data);
>-
> if (ret)
> return ret;
>
>- ret = wait_event_interruptible_timeout(adapter->vc_waitqueue,
>- iavf_is_mac_set_handled(netdev, addr->sa_data),
>- msecs_to_jiffies(2500));
>-
>- /* If ret < 0 then it means wait was interrupted.
>- * If ret == 0 then it means we got a timeout.
>- * else it means we got response for set MAC from PF,
>- * check if netdev MAC was updated to requested MAC,
>- * if yes then set MAC succeeded otherwise it failed return -EACCES
>- */
>- if (ret < 0)
>+ ret = iavf_set_mac_sync(adapter, addr->sa_data);
>+ if (ret) {
>+ /* Rollback only if send failed (message never reached PF).
>+ * Don't rollback on timeout (-EAGAIN) because the message was
>+ * sent and PF will eventually respond. When the response arrives,
>+ * iavf_virtchnl_completion() will handle rollback (on PF error)
>+ * or acceptance (on PF success) automatically.
>+ */
>+ if (ret != -EAGAIN) {
>+ iavf_mac_add_reject(adapter);
>+ ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
>+ }
> return ret;
>-
>- if (!ret)
>- return -EAGAIN;
>+ }
>
> if (!ether_addr_equal(netdev->dev_addr, addr->sa_data))
> return -EACCES;
>@@ -5397,9 +5449,6 @@ static int iavf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> /* Setup the wait queue for indicating transition to down status */
> init_waitqueue_head(&adapter->down_waitqueue);
>
>- /* Setup the wait queue for indicating virtchannel events */
>- init_waitqueue_head(&adapter->vc_waitqueue);
>-
> INIT_LIST_HEAD(&adapter->ptp.aq_cmds);
> init_waitqueue_head(&adapter->ptp.phc_time_waitqueue);
> mutex_init(&adapter->ptp.aq_cmd_lock);
>diff --git a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
>index ec234cc8bd9d..e6b7e8f82c7c 100644
>--- a/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
>+++ b/drivers/net/ethernet/intel/iavf/iavf_virtchnl.c
>@@ -2,6 +2,7 @@
> /* Copyright(c) 2013 - 2018 Intel Corporation. */
>
> #include <linux/net/intel/libie/rx.h>
>+#include <net/netdev_lock.h>
>
> #include "iavf.h"
> #include "iavf_ptp.h"
>@@ -555,20 +556,23 @@ iavf_set_mac_addr_type(struct virtchnl_ether_addr *virtchnl_ether_addr,
> * @adapter: adapter structure
> *
> * Request that the PF add one or more addresses to our filters.
>- **/
>-void iavf_add_ether_addrs(struct iavf_adapter *adapter)
>+ *
>+ * Return: 0 on success, negative on failure */ int
>+iavf_add_ether_addrs(struct iavf_adapter *adapter)
> {
> struct virtchnl_ether_addr_list *veal;
> struct iavf_mac_filter *f;
> int i = 0, count = 0;
> bool more = false;
> size_t len;
>+ int ret;
The patch looks good. Minor suggestion:
- int i = 0, count = 0;
+ int i = 0, count = 0, ret;
Please retain RCT.
Thank you.
Piotr
>
> if (adapter->current_op != VIRTCHNL_OP_UNKNOWN) {
> /* bail because we already have a command pending */
> dev_err(&adapter->pdev->dev, "Cannot add filters, command %d pending\n",
> adapter->current_op);
>- return;
>+ return -EBUSY;
> }
>
> spin_lock_bh(&adapter->mac_vlan_list_lock);
>@@ -580,7 +584,7 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
> if (!count) {
> adapter->aq_required &= ~IAVF_FLAG_AQ_ADD_MAC_FILTER;
> spin_unlock_bh(&adapter->mac_vlan_list_lock);
>- return;
>+ return 0;
> }
> adapter->current_op = VIRTCHNL_OP_ADD_ETH_ADDR;
>
>@@ -594,8 +598,9 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
>
> veal = kzalloc(len, GFP_ATOMIC);
> if (!veal) {
>+ adapter->current_op = VIRTCHNL_OP_UNKNOWN;
> spin_unlock_bh(&adapter->mac_vlan_list_lock);
>- return;
>+ return -ENOMEM;
> }
>
> veal->vsi_id = adapter->vsi_res->vsi_id; @@ -615,8 +620,15 @@ void iavf_add_ether_addrs(struct iavf_adapter *adapter)
>
> spin_unlock_bh(&adapter->mac_vlan_list_lock);
>
>- iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal, len);
>+ ret = iavf_send_pf_msg(adapter, VIRTCHNL_OP_ADD_ETH_ADDR, (u8 *)veal,
>+len);
> kfree(veal);
>+ if (ret) {
>+ dev_err(&adapter->pdev->dev,
>+ "Unable to send ADD_ETH_ADDR message to PF, error %d\n", ret);
>+ adapter->current_op = VIRTCHNL_OP_UNKNOWN;
>+ }
>+
>+ return ret;
> }
>
> /**
>@@ -712,8 +724,8 @@ static void iavf_mac_add_ok(struct iavf_adapter *adapter)
> * @adapter: adapter structure
> *
> * Remove filters from list based on PF response.
>- **/
>-static void iavf_mac_add_reject(struct iavf_adapter *adapter)
>+ */
>+void iavf_mac_add_reject(struct iavf_adapter *adapter)
> {
> struct net_device *netdev = adapter->netdev;
> struct iavf_mac_filter *f, *ftmp;
>@@ -2364,7 +2376,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
> iavf_mac_add_reject(adapter);
> /* restore administratively set MAC address */
> ether_addr_copy(adapter->hw.mac.addr, netdev->dev_addr);
>- wake_up(&adapter->vc_waitqueue);
> break;
> case VIRTCHNL_OP_DEL_ETH_ADDR:
> dev_err(&adapter->pdev->dev, "Failed to delete MAC filter, error %s\n", @@ -2555,7 +2566,6 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
> eth_hw_addr_set(netdev, adapter->hw.mac.addr);
> netif_addr_unlock_bh(netdev);
> }
>- wake_up(&adapter->vc_waitqueue);
> break;
> case VIRTCHNL_OP_GET_STATS: {
> struct iavf_eth_stats *stats =
>@@ -2950,3 +2960,72 @@ void iavf_virtchnl_completion(struct iavf_adapter *adapter,
> } /* switch v_opcode */
> adapter->current_op = VIRTCHNL_OP_UNKNOWN; }
>+
>+/**
>+ * iavf_poll_virtchnl_response - Poll admin queue for virtchnl response
>+ * @adapter: adapter structure
>+ * @event: pre-allocated event buffer to use for polling
>+ * @condition: callback to check if desired response received
>+ * @cond_data: context data passed to condition callback
>+ * @timeout_ms: maximum time to wait in milliseconds
>+ *
>+ * Polls the admin queue and processes all incoming virtchnl messages.
>+ * After processing each valid message, calls the condition callback to
>+check
>+ * if the expected response has been received. The callback receives
>+the opcode
>+ * of the processed message to identify which response was received.
>+Continues
>+ * polling until the callback returns true or timeout expires.
>+ *
>+ * Caller must allocate event buffer before sending any messages to PF
>+to avoid
>+ * state mismatch if allocation fails after message is sent.
>+ *
>+ * Caller must hold netdev_lock. This can sleep for up to timeout_ms
>+while
>+ * polling hardware.
>+ *
>+ * Return: 0 on success (condition met), -EAGAIN on timeout, or error
>+code */ int iavf_poll_virtchnl_response(struct iavf_adapter *adapter,
>+ struct iavf_arq_event_info *event,
>+ bool (*condition)(struct iavf_adapter *adapter,
>+ const void *data,
>+ enum virtchnl_ops v_op),
>+ const void *cond_data,
>+ unsigned int timeout_ms)
>+{
>+ struct iavf_hw *hw = &adapter->hw;
>+ enum virtchnl_ops received_op;
>+ unsigned long timeout;
>+ int ret = -EAGAIN;
>+ u16 pending = 0;
>+ u32 v_retval;
Most of these variables may be declared inside the below statements.
Reviewed-by Piotr Kwapulinski <piotr.kwapulinski@intel.com>
Piotr
>+
>+ netdev_assert_locked(adapter->netdev);
>+
>+ timeout = jiffies + msecs_to_jiffies(timeout_ms);
>+ do {
>+ if (!pending)
>+ usleep_range(50, 75);
>+
>+ if (iavf_clean_arq_element(hw, event, &pending) == IAVF_SUCCESS) {
>+ received_op = (enum virtchnl_ops)le32_to_cpu(event->desc.cookie_high);
>+ if (received_op != VIRTCHNL_OP_UNKNOWN) {
>+ v_retval = le32_to_cpu(event->desc.cookie_low);
>+
>+ iavf_virtchnl_completion(adapter, received_op,
>+ (enum iavf_status)v_retval,
>+ event->msg_buf, event->msg_len);
>+
>+ if (condition(adapter, cond_data, received_op)) {
>+ ret = 0;
>+ break;
>+ }
>+ }
>+
>+ memset(event->msg_buf, 0, IAVF_MAX_AQ_BUF_SIZE);
>+
>+ if (pending)
>+ continue;
>+ }
>+ } while (time_before(jiffies, timeout));
>+
>+ return ret;
>+}
>--
>2.54.0
>
>
^ permalink raw reply
* Re: [PATCH net v4 2/2] net: phy: mdio-i2c: defer RollBall bridge probe to PHY discovery
From: Maxime Chevallier @ 2026-06-26 15:10 UTC (permalink / raw)
To: Petr Wozniak, Russell King, Andrew Lunn, Heiner Kallweit
Cc: Jakub Kicinski, David S . Miller, Eric Dumazet, Paolo Abeni,
netdev, linux-kernel, linux-phy, Bjorn Mork, Aleksander Bajkowski,
Marek Behun
In-Reply-To: <20260624084814.20972-3-petr.wozniak@gmail.com>
Hi Petr,
On 6/24/26 10:48, Petr Wozniak wrote:
> commit 8fe125892f40 ("net: phy: sfp: probe for RollBall I2C-to-MDIO
> bridge in mdio-i2c") introduced a regression: the RollBall I2C-to-MDIO
> bridge is not yet ready to respond to CMD_READ/CMD_DONE cycles when
> sfp_sm_add_mdio_bus() runs in SFP_S_INIT. The 200 ms probe times out,
> i2c_mii_probe_rollball() returns -ENODEV, and sfp_sm_add_mdio_bus()
> sets mdio_protocol = MDIO_I2C_NONE. By the time sfp_sm_probe_for_phy()
> runs (up to ~17 s later on affected hardware), the bridge is fully
> initialized but PHY probing is skipped because the protocol has already
> been changed to NONE.
>
> This affects both modules inserted before boot and hotplugged modules on
> hardware where bridge initialization exceeds the 200 ms probe window
> (confirmed: FLYPRO SFP-10GT-CS-30M with Aquantia AQR113C, hotplugged).
>
> Move the probe from i2c_mii_init_rollball(), called at bus-creation time,
> to sfp_sm_probe_for_phy() in sfp.c, where it runs after the SFP state
> machine module initialization delays. Export the probe function as
> mdio_i2c_probe_rollball() so sfp.c can call it.
>
> For RTL8261BE-based modules the probe correctly returns -ENODEV at PHY
> discovery time, causing sfp_sm_probe_for_phy() to destroy the MDIO bus
> and set MDIO_I2C_NONE, eliminating the 5+ minute PHY probe retry loop.
>
> For genuine RollBall modules (e.g. FLYPRO SFP-10GT-CS-30M with Aquantia
> AQR113C) the probe now runs after initialization is complete and
> correctly returns 0, so PHY detection proceeds normally.
>
> Reported-by: Aleksander Bajkowski <olek2@wp.pl>
> Fixes: 8fe125892f40 ("net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c")
> Signed-off-by: Petr Wozniak <petr.wozniak@gmail.com>
I finally got time to test this with a RollBall module, and I
confirm what Aleksander says, the RollBall module's PHY doesn't
get detected even with this patch.
It does work on v7.0 though, so before the bridge probing was
introduced.
Maxime
^ permalink raw reply
* [PATCH] fix: net: cadence: macb_mii_init: fix double of_node_put on mdio_np after macb_mdiobus_register
From: WenTao Liang @ 2026-06-26 15:14 UTC (permalink / raw)
To: Nicolas Ferre, netdev
Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
stable, linux-kernel, WenTao Liang
After macb_mdiobus_register succeeds, the mdio_np reference ownership is
transferred to the mii_bus device (stored in mii_bus->dev.of_node). When
the subsequent macb_mii_probe fails, the error path jumps to
err_out_unregister_bus which calls mdiobus_free (releasing the node via
fwnode_handle_put) and then falls through to err_out which calls
of_node_put(mdio_np) again, causing a double put.
Move the of_node_put to only execute on paths where the reference was not
transferred (i.e., before successful macb_mdiobus_register).
Cc: stable@vger.kernel.org
Fixes: ef8a2e27289e ("net: macb: fix probing of PHY not described in the dt")
Signed-off-by: WenTao Liang <vulab@iscas.ac.cn>
---
drivers/net/ethernet/cadence/macb_main.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index a12aa21244e8..c58e089e5888 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1170,6 +1170,9 @@ static int macb_mii_init(struct macb *bp)
mdiobus_unregister(bp->mii_bus);
err_out_free_mdiobus:
mdiobus_free(bp->mii_bus);
+ of_node_put(mdio_np);
+ return err;
+
err_out:
of_node_put(mdio_np);
--
2.39.5 (Apple Git-154)
^ permalink raw reply related
* Re: [PATCH v4] virtio_net: disable cb when NAPI is busy-polled
From: Simon Horman @ 2026-06-26 15:15 UTC (permalink / raw)
To: lange_tang
Cc: Simon Horman, mst, xuanzhuo, jasowang, edumazet, virtualization,
netdev, tanglongjun
In-Reply-To: <20260625013733.29300-1-lange_tang@163.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
Full review at: https://sashiko.dev
---
virtio_net: disable cb when NAPI is busy-polled
This commit disables the virtqueue callback at the entry of virtnet_poll().
It aims to prevent a large number of spurious interrupts when busy-poll is
active by keeping the callback off while polling.
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 26afa6341d161..c1e252400c0fc 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -3011,6 +3011,8 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
> unsigned int xdp_xmit = 0;
> bool napi_complete;
>
> + virtqueue_disable_cb(rq->vq);
> +
[Severity: High]
Can this unconditionally disable the RX callback and cause a permanent network
stall when polled by netpoll?
If the netpoll subsystem (e.g., used by netconsole) calls the NAPI poll
function directly with a budget of 0, virtqueue_disable_cb() is called
immediately. virtnet_receive() will then process 0 packets and return 0.
Later in virtnet_poll(), the completion condition is checked:
if (received < budget) {
napi_complete = virtqueue_napi_complete(napi, rq->vq, received);
...
}
When both received and budget are 0, this condition evaluates to false. This
skips virtqueue_napi_complete(), leaving the RX callback permanently disabled
and preventing the device from raising further RX interrupts.
> virtnet_poll_cleantx(rq, budget);
>
> received = virtnet_receive(rq, budget, &xdp_xmit);
^ permalink raw reply
* Re: iproute2: trailing whitespace in man pages
From: Stephen Hemminger @ 2026-06-26 15:15 UTC (permalink / raw)
To: Bjarni Ingi Gislason; +Cc: netdev, Debian Bug Tracking System
In-Reply-To: <178243847243.6540.10252433987238870483.reportbug@kassi.invalid.is>
On Fri, 26 Jun 2026 01:54:52 +0000
Bjarni Ingi Gislason <bjarniig@simnet.is> wrote:
> Package: iproute2 (in Debian)
> Version: 7.1.0-1
> Severity: minor
>
> Additional remarks.
>
> Mails from me to "submit@bugs.debian.org" are no longer acknowledged. A
> Debian maintainer told me, that he would contact the mail administrator
> about me not wanting to send bugs upstream.
>
> -.-
>
> Dear Maintainer,
>
> * What led up to the situation?
>
> Checking for defects with a new version
>
> test-[g|n]roff -mandoc -t -K utf8 -rF0 -rHY=0 -rCHECKSTYLE=0 -ww -z < "man page"
>
> [Use
>
> grep -n -e ' $' -e '\\~$' -e ' \\f.$' -e ' \\"' <file>
>
> to find (most) trailing spaces.]
>
> ["test-groff" is a script in the repository for "groff"; is not shipped]
> (local copy and "troff" slightly changed by me).
>
> [The fate of "test-nroff" was decided in groff bug #55941.]
>
> * What was the outcome of this action?
>
> troff:/tmp/gz.roff.tw9zTq:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:38: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:43: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:45: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:47: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:49: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:50: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:55: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tw9zTq:57: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/bridge.8.gz
>
> troff:/tmp/gz.roff.m7ah0F:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-app.8.gz
>
> troff:/tmp/gz.roff.lEZOzh:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.lEZOzh:32: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-apptrust.8.gz
>
> troff:/tmp/gz.roff.WIScEl:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-buffer.8.gz
>
> troff:/tmp/gz.roff.lQyzHW:11: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-dcbx.8.gz
>
> troff:/tmp/gz.roff.i604Vp:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.i604Vp:43: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-ets.8.gz
>
> troff:/tmp/gz.roff.21mI9Z:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.21mI9Z:37: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-maxrate.8.gz
>
> troff:/tmp/gz.roff.tNIhrB:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.tNIhrB:38: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-pfc.8.gz
>
> troff:/tmp/gz.roff.rSgJgv:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb-rewr.8.gz
>
> troff:/tmp/gz.roff.Q8vb3N:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Q8vb3N:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Q8vb3N:24: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dcb.8.gz
>
> troff:/tmp/gz.roff.IodjFN:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:54: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:123: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:133: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:149: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.IodjFN:175: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-dev.8.gz
>
> troff:/tmp/gz.roff.Nx3P7S:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Nx3P7S:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Nx3P7S:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Nx3P7S:32: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-dpipe.8.gz
>
> troff:/tmp/gz.roff.f7fvNK:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:66: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:68: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:184: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:188: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:193: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.f7fvNK:197: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-health.8.gz
>
> troff:/tmp/gz.roff.hTtjSy:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:50: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:54: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:55: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hTtjSy:68: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-lc.8.gz
>
> troff:/tmp/gz.roff.soeA6o:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:50: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:66: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:68: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:69: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:71: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:74: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:77: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:80: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:83: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:86: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:91: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:101: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:127: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.soeA6o:167: warning: treating total indentation -72u as zero [-w range]
> /usr/share/man/man8/devlink-port.8.gz
>
> troff:/tmp/gz.roff.kYqBeN:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.kYqBeN:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.kYqBeN:26: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-rate.8.gz
>
> troff:/tmp/gz.roff.9tHyhr:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9tHyhr:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9tHyhr:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9tHyhr:48: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-region.8.gz
>
> troff:/tmp/gz.roff.9MYeZd:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9MYeZd:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-resource.8.gz
>
> troff:/tmp/gz.roff.ZhPBEk:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:23: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:43: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:49: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:61: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:63: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:66: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:69: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZhPBEk:71: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-sb.8.gz
>
> troff:/tmp/gz.roff.cbJFkk:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.cbJFkk:79: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.cbJFkk:114: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.cbJFkk:139: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.cbJFkk:143: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink-trap.8.gz
>
> troff:/tmp/gz.roff.QOaboD:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.QOaboD:16: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/devlink.8.gz
>
> troff:/tmp/gz.roff.m0E9ov:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.m0E9ov:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.m0E9ov:29: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/dpll.8.gz
>
> troff:/tmp/gz.roff.hhba1k:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hhba1k:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hhba1k:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hhba1k:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.hhba1k:31: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/genl.8.gz
>
> troff:/tmp/gz.roff.UspeXf:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:33: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:43: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:45: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:47: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:49: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:63: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:65: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:69: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:71: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:76: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.UspeXf:77: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-address.8.gz
>
> troff:/tmp/gz.roff.ACnG5f:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ACnG5f:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ACnG5f:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ACnG5f:56: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-addrlabel.8.gz
>
> troff:/tmp/gz.roff.5eqgIA:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:52: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5eqgIA:60: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-fou.8.gz
>
> troff:/tmp/gz.roff.muormS:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.muormS:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.muormS:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.muormS:49: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-ioam.8.gz
>
> troff:/tmp/gz.roff.YZqY4h:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.YZqY4h:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.YZqY4h:85: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.YZqY4h:232: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-l2tp.8.gz
>
> troff:/tmp/gz.roff.x9nPAk:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:159: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:164: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:186: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:195: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:197: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:223: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:224: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:226: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:227: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:228: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:229: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:230: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:236: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:237: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:248: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:249: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.x9nPAk:256: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-link.8.gz
>
> troff:/tmp/gz.roff.r9LukD:5: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:64: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:65: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:75: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:77: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:80: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:83: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.r9LukD:85: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-macsec.8.gz
>
> troff:/tmp/gz.roff.fk7Uej:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-maddress.8.gz
>
> troff:/tmp/gz.roff.OtuwHM:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.OtuwHM:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.OtuwHM:45: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.OtuwHM:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.OtuwHM:57: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.OtuwHM:58: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-monitor.8.gz
>
> troff:/tmp/gz.roff.DLgQwy:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:30: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:37: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:45: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:52: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:88: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:89: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DLgQwy:92: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-mptcp.8.gz
>
> troff:/tmp/gz.roff.Bf2muc:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Bf2muc:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Bf2muc:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Bf2muc:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Bf2muc:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Bf2muc:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-mroute.8.gz
>
> troff:/tmp/gz.roff.aIjjMP:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:26: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:30: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:37: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.aIjjMP:39: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-neighbour.8.gz
>
> troff:/tmp/gz.roff.sjvvc4:9: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-netconf.8.gz
>
> troff:/tmp/gz.roff.bAu8qy:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bAu8qy:46: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-netns.8.gz
>
> troff:/tmp/gz.roff.nM3cIw:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:23: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:49: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:53: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:60: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:62: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:64: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:65: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:68: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.nM3cIw:70: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-nexthop.8.gz
>
> troff:/tmp/gz.roff.Kn3w81:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Kn3w81:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Kn3w81:57: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Kn3w81:59: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-ntable.8.gz
>
> troff:/tmp/gz.roff.gv3LBB:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:33: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:38: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:60: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:62: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:64: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:66: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:68: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:70: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:72: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:74: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gv3LBB:84: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-route.8.gz
>
> troff:/tmp/gz.roff.6owsuu:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:38: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:49: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:53: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:54: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:55: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:57: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:58: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.6owsuu:61: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-rule.8.gz
>
> troff:/tmp/gz.roff.6yXkbF:10: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-sr.8.gz
>
> troff:/tmp/gz.roff.glO7gb:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.glO7gb:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.glO7gb:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.glO7gb:28: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-stats.8.gz
>
> troff:/tmp/gz.roff.XiAasB:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.XiAasB:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.XiAasB:26: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-tcp_metrics.8.gz
>
> troff:/tmp/gz.roff.XtavYp:10: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-token.8.gz
>
> troff:/tmp/gz.roff.TS3gWw:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:76: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TS3gWw:81: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-tunnel.8.gz
>
> troff:/tmp/gz.roff.5llFkR:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.5llFkR:28: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-vrf.8.gz
>
> troff:/tmp/gz.roff.91zMPC:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:103: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:158: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:171: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:175: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:183: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:198: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:240: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:274: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:325: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:327: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:345: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:363: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:367: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:371: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:427: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:448: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.91zMPC:564: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip-xfrm.8.gz
>
> troff:/tmp/gz.roff.gY3yJ3:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:169: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gY3yJ3:175: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ip.8.gz
>
> troff:/tmp/gz.roff.j0dcO5:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j0dcO5:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j0dcO5:111: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j0dcO5:112: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j0dcO5:203: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j0dcO5:204: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/netshaper.8.gz
>
> troff:/tmp/gz.roff.EOKA9l:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EOKA9l:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-dev.8.gz
>
> troff:/tmp/gz.roff.j9CeKZ:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.j9CeKZ:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-link.8.gz
>
> troff:/tmp/gz.roff.NBliDx:16: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-monitor.8.gz
>
> troff:/tmp/gz.roff.n7n6Ij:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.n7n6Ij:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.n7n6Ij:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.n7n6Ij:21: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-resource.8.gz
>
> troff:/tmp/gz.roff.zNQGc9:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.zNQGc9:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.zNQGc9:85: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.zNQGc9:89: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.zNQGc9:93: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.zNQGc9:97: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-statistic.8.gz
>
> troff:/tmp/gz.roff.w2n0Tg:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.w2n0Tg:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma-system.8.gz
>
> troff:/tmp/gz.roff.G452XU:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.G452XU:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.G452XU:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.G452XU:26: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rdma.8.gz
>
> troff:/tmp/gz.roff.8E9eVD:10: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/rtmon.8.gz
>
> troff:/tmp/gz.roff.cESP7P:447: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.cESP7P:607: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/ss.8.gz
>
> troff:/tmp/gz.roff.ux4fN1:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ux4fN1:11: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-basic.8.gz
>
> troff:/tmp/gz.roff.E5yQLK:9: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-cgroup.8.gz
>
> troff:/tmp/gz.roff.xDoFMo:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.xDoFMo:49: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-connmark.8.gz
>
> troff:/tmp/gz.roff.EPr6TY:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EPr6TY:26: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-csum.8.gz
>
> troff:/tmp/gz.roff.ozliFK:7: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ozliFK:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ozliFK:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ozliFK:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ozliFK:18: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-ct.8.gz
>
> troff:/tmp/gz.roff.NlhG4f:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.NlhG4f:39: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.NlhG4f:51: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-dualpi2.8.gz
>
> troff:/tmp/gz.roff.AXC30K:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.AXC30K:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.AXC30K:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.AXC30K:33: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.AXC30K:73: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-ematch.8.gz
>
> troff:/tmp/gz.roff.Xqn4yW:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:38: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:47: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:54: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:55: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.Xqn4yW:57: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-flow.8.gz
>
> troff:/tmp/gz.roff.SN8HX6:8: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:26: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:30: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:38: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.SN8HX6:45: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-flower.8.gz
>
> troff:/tmp/gz.roff.75BF9d:69: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-fq_codel.8.gz
>
> troff:/tmp/gz.roff.ATqeiC:9: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-fw.8.gz
>
> troff:/tmp/gz.roff.0gJmYD:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0gJmYD:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0gJmYD:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0gJmYD:24: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-gact.8.gz
>
> troff:/tmp/gz.roff.1ht4Bu:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:26: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:36: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.1ht4Bu:67: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-ife.8.gz
>
> troff:/tmp/gz.roff.eEZB5X:8: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.eEZB5X:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.eEZB5X:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-matchall.8.gz
>
> troff:/tmp/gz.roff.BCTuKt:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.BCTuKt:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.BCTuKt:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.BCTuKt:26: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.BCTuKt:30: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-mirred.8.gz
>
> troff:/tmp/gz.roff.KuFNwq:8: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:10: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:23: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:37: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:40: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:57: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:80: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.KuFNwq:81: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-mpls.8.gz
>
> troff:/tmp/gz.roff.9RiFlD:235: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9RiFlD:237: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9RiFlD:254: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9RiFlD:274: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9RiFlD:282: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.9RiFlD:284: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-mqprio.8.gz
>
> troff:/tmp/gz.roff.t0JWAM:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.t0JWAM:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.t0JWAM:23: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-nat.8.gz
>
> troff:/tmp/gz.roff.ZHcyYL:6: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:26: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:34: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:35: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:37: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:41: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:45: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:47: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:55: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:56: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:59: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:60: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:63: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:383: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZHcyYL:387: warning [page 1, line 269]: cannot adjust line in b adjust mode; overset by 4n [-w break]
> /usr/share/man/man8/tc-netem.8.gz
>
> troff:/tmp/gz.roff.DJ46bB:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:22: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:48: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:53: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:57: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:62: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:63: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:67: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:71: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:77: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:79: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.DJ46bB:80: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-pedit.8.gz
>
> troff:/tmp/gz.roff.HpJEdr:34: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-police.8.gz
>
> troff:/tmp/gz.roff.JYFwIE:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.JYFwIE:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.JYFwIE:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.JYFwIE:15: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-route.8.gz
>
> troff:/tmp/gz.roff.TQDw2w:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TQDw2w:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.TQDw2w:19: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-sample.8.gz
>
> troff:/tmp/gz.roff.LzdwcT:69: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-skbedit.8.gz
>
> troff:/tmp/gz.roff.EeoYee:8: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:23: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.EeoYee:26: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-skbmod.8.gz
>
> troff:/tmp/gz.roff.LaXqMO:8: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.LaXqMO:12: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-tunnel_key.8.gz
>
> troff:/tmp/gz.roff.0SnZpw:9: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:13: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:17: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:21: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:23: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:25: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:29: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:31: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:33: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:37: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:44: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:46: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:51: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:52: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.0SnZpw:53: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-u32.8.gz
>
> troff:/tmp/gz.roff.ZLTTLY:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:16: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:20: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:24: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:30: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.ZLTTLY:33: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc-vlan.8.gz
>
> troff:/tmp/gz.roff.bkv7BO:128: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bkv7BO:129: warning: ignoring escape character before ']' [-w escape]
> troff:/tmp/gz.roff.bkv7BO:717: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bkv7BO:723: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tc.8.gz
>
> troff:/tmp/gz.roff.My0dwn:57: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tipc-bearer.8.gz
>
> troff:/tmp/gz.roff.bYd25b:18: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:27: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:28: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:30: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:32: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:42: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:53: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:62: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.bYd25b:66: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tipc-link.8.gz
>
> troff:/tmp/gz.roff.rs4kL6:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tipc-media.8.gz
>
> troff:/tmp/gz.roff.z8m3fR:15: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.z8m3fR:19: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.z8m3fR:23: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tipc-node.8.gz
>
> an.tmac:/tmp/gz.roff.9VgwLV:30: warning: cannot call .SS while an input trap is pending
> an.tmac:/tmp/gz.roff.9VgwLV:34: warning: cannot call .SS while an input trap is pending
> /usr/share/man/man8/tipc-socket.8.gz
>
> troff:/tmp/gz.roff.rBSHKg:14: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.rBSHKg:19: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/tipc.8.gz
>
> troff:/tmp/gz.roff.gPfIxK:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gPfIxK:12: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.gPfIxK:17: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/vdpa-dev.8.gz
>
> troff:/tmp/gz.roff.wHzGiy:11: warning: trailing whitespace [-w trail]
> troff:/tmp/gz.roff.wHzGiy:16: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/vdpa-mgmtdev.8.gz
>
> troff:/tmp/gz.roff.qSwXBM:10: warning: trailing whitespace [-w trail]
> /usr/share/man/man8/vdpa.8.gz
>
> * What outcome did you expect instead?
>
> No output (no warnings).
>
> -.-
>
> General remarks and further material, if a diff-file exist, are in the
> attachments.
>
>
> -- System Information:
> Debian Release: forky/sid
> APT prefers testing
> APT policy: (500, 'testing')
> Architecture: amd64 (x86_64)
>
> Kernel: Linux 7.0.12+deb14.1-amd64 (SMP w/2 CPU threads; PREEMPT)
> Locale: LANG=is_IS.iso88591, LC_CTYPE=is_IS.iso88591 (charmap=ISO-8859-1), LANGUAGE not set
> Shell: /bin/sh linked to /usr/bin/dash
> Init: sysvinit (via /sbin/init)
>
> Versions of packages iproute2 depends on:
> ii debconf [debconf-2.0] 1.5.92
> ii libbpf1 1:1.7.0-1
> ii libc6 2.42-17
> ii libcap2 1:2.78-1
> ii libcap2-bin 1:2.78-1
> ii libdb5.3t64 5.3.28+dfsg2-11+b1
> ii libelf1t64 0.195-1
> ii libmnl0 1.0.5-3+b2
> ii libselinux1 3.10-1
> ii libtirpc3t64 1.3.7+ds-1
> ii libxtables12 1.8.13-1
>
> iproute2 recommends no packages.
>
> Versions of packages iproute2 suggests:
> ii python3 3.13.9-3+b1
>
> -- debconf information excluded
Please send a patch as described in iproute2
The only place I found trailing whitespace on a man page source was
diff --git a/man/man8/tc-fq_codel.8 b/man/man8/tc-fq_codel.8
index 78590636..6ed523c7 100644
--- a/man/man8/tc-fq_codel.8
+++ b/man/man8/tc-fq_codel.8
@@ -66,7 +66,7 @@ the local minimum queue delay that packets experience. Default value is 5ms.
has the same semantics as
.B codel
and is used to ensure that the measured minimum delay does not become too stale.
-The minimum delay must be experienced in the last epoch of length
+The minimum delay must be experienced in the last epoch of length
.BR interval .
It should be set on the order of the worst-case RTT through the bottleneck to
give endpoints sufficient time to react. Default value is 100ms.
^ permalink raw reply related
* Re: [patch 09/24] timekeeping: Add CLOCK_AUX support for ktime_get_snapshot_id()
From: Thomas Gleixner @ 2026-06-26 15:17 UTC (permalink / raw)
To: Thomas Weißschuh
Cc: LKML, David Woodhouse, Miroslav Lichvar, John Stultz,
Stephen Boyd, Anna-Maria Behnsen, Frederic Weisbecker,
Arthur Kiyanovski, Rodolfo Giometti, Vincent Donnefort,
Marc Zyngier, Oliver Upton, kvmarm, Oliver Upton, Richard Cochran,
netdev, Takashi Iwai, Miri Korenblit, Johannes Berg, Jacob Keller,
Tony Nguyen, Saeed Mahameed, Peter Hilber, Michael S. Tsirkin,
virtualization, linux-wireless, linux-sound
In-Reply-To: <20260626125819-d8b197fc-7671-4d12-a578-9025affc52d9@linutronix.de>
On Fri, Jun 26 2026 at 13:03, Thomas Weißschuh wrote:
> On Fri, Jun 26, 2026 at 12:49:41PM +0200, Thomas Gleixner wrote:
>> On Fri, Jun 26 2026 at 10:48, Thomas Weißschuh wrote:
>> > On Tue, May 26, 2026 at 07:14:13PM +0200, Thomas Gleixner wrote:
>> > (...)
>> >
>> >> static inline void tk_update_aux_offs(struct timekeeper *tk, ktime_t offs)
>> >> @@ -1218,6 +1223,12 @@ bool ktime_get_snapshot_id(struct system
>> >> tkd = &tk_core;
>> >> offs = &tk_core.timekeeper.offs_boot;
>> >> break;
>> >> + case CLOCK_AUX ... CLOCK_AUX_LAST:
>> >> + tkd = aux_get_tk_data(clock_id);
>> >> + if (!tkd)
>> >> + return false;
>> >> + offs = &tkd->timekeeper.offs_aux;
>> >> + break;
>> >
>> > 'tkd' is also used to compute 'monoraw'. However 'tkr_raw' and 'tkr_mono'
>> > are the same for auxilary clocks, so this will compute a wrong 'monoraw'.
>>
>> AUX clocks are independent in the first place and the MONORAW part is
>> the "MONORAW" related to the AUX clock itself.
>>
>> > Instead 'monoraw' should be computed based on 'tk_core'.
>> > Which then also requires the sequence locking of 'tk_core'.
>>
>> No. From a PTP and steering point of view you want the "raw" value which
>> is related to the AUX clock itself and not the global one.
>
> Ack.
>
> However the kdocs call it 'CLOCK_MONOTONIC_RAW'. Can we clean this up?
Yes. Something like the below?
Thanks,
tglx
---
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1202,10 +1202,21 @@ static inline u64 tk_clock_read_snapshot
/**
* ktime_get_snapshot_id - Simultaneously snapshot a given clock ID with
- * CLOCK_MONOTONIC_RAW and the underlying
+ * the corresponding monotonic raw the underlying
* clocksource counter value.
* @clock_id: The clock ID to snapshot
* @systime_snapshot: Pointer to struct receiving the system time snapshot
+ *
+ * For the system time keeping clocks (REALTIME, MONOTONIC and BOOTTIME) the
+ * monotonic raw clock is CLOCK_MONOTONIC_RAW. For AUX clocks this is the
+ * monotonic raw clock related to the AUX clock. These AUX clock related
+ * monotonic raw clocks have a strict linear offset to the system time
+ * CLOCK_MONOTONIC_RAW:
+ *
+ * MONOTONIC_RAW(AUX$N) = CLOCK_MONOTONIC_RAW(system) + offset(AUX$N)
+ *
+ * The offset is established when a AUX clock is initialized, but it is
+ * currently not accessible.
*/
void ktime_get_snapshot_id(clockid_t clock_id, struct system_time_snapshot *systime_snapshot)
{
@@ -1512,6 +1523,9 @@ EXPORT_SYMBOL_GPL(ktime_real_to_base_clo
* @xtstamp: Receives simultaneously captured system and device time
*
* Reads a timestamp from a device and correlates it to system time
+ *
+ * See documentation for ktime_get_snapshot_id() for information about the raw
+ * monotonic time stamp which is used here.
*/
int get_device_system_crosststamp(int (*get_time_fn)
(ktime_t *device_time,
^ 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