* [PATCH net 1/6] can: raw: add locking for raw flags bitfield
From: Marc Kleine-Budde @ 2026-05-07 8:22 UTC (permalink / raw)
To: netdev
Cc: davem, kuba, linux-can, kernel, Oliver Hartkopp, Eulgyu Kim,
Vincent Mailhol, Marc Kleine-Budde
In-Reply-To: <20260507112321.439968-1-mkl@pengutronix.de>
From: Oliver Hartkopp <socketcan@hartkopp.net>
With commit 890e5198a6e5 ("can: raw: use bitfields to store flags in
struct raw_sock") the formerly separate integer values have been integrated
into a single bitfield. This led to a read-modify-write operation when
changing a flag in raw_setsockopt() which now needs a locking to prevent
concurrent access.
Instead of adding a lock/unlock hell in each of the flag manipulations this
patch introduces a wrapper for a new raw_setsockopt_locked() function
analogue to the isotp_setsockopt[_locked]() approach in net/can/isotp.c
Fixes: 890e5198a6e5 ("can: raw: use bitfields to store flags in struct raw_sock")
Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
Closes: https://lore.kernel.org/linux-can/20260503112200.22727-1-eulgyukim@snu.ac.kr/
Tested-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Reviewed-by: Vincent Mailhol <mailhol@kernel.org>
Tested-by: Vincent Mailhol <mailhol@kernel.org>
Link: https://patch.msgid.link/20260504111928.41856-1-socketcan@hartkopp.net
[mkl: use Closes tag instead of Link]
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
net/can/raw.c | 66 +++++++++++++++++++++++----------------------------
1 file changed, 30 insertions(+), 36 deletions(-)
diff --git a/net/can/raw.c b/net/can/raw.c
index a26942e78e68..82d9c0499c95 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -562,8 +562,8 @@ static int raw_getname(struct socket *sock, struct sockaddr *uaddr,
return RAW_MIN_NAMELEN;
}
-static int raw_setsockopt(struct socket *sock, int level, int optname,
- sockptr_t optval, unsigned int optlen)
+static int raw_setsockopt_locked(struct socket *sock, int optname,
+ sockptr_t optval, unsigned int optlen)
{
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
@@ -575,9 +575,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
int flag;
int err = 0;
- if (level != SOL_CAN_RAW)
- return -EINVAL;
-
switch (optname) {
case CAN_RAW_FILTER:
if (optlen % sizeof(struct can_filter) != 0)
@@ -598,17 +595,11 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
return -EFAULT;
}
- rtnl_lock();
- lock_sock(sk);
-
dev = ro->dev;
- if (ro->bound && dev) {
- if (dev->reg_state != NETREG_REGISTERED) {
- if (count > 1)
- kfree(filter);
- err = -ENODEV;
- goto out_fil;
- }
+ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED) {
+ if (count > 1)
+ kfree(filter);
+ return -ENODEV;
}
if (ro->bound) {
@@ -622,7 +613,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
if (err) {
if (count > 1)
kfree(filter);
- goto out_fil;
+ return err;
}
/* remove old filter registrations */
@@ -642,11 +633,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
}
ro->filter = filter;
ro->count = count;
-
- out_fil:
- release_sock(sk);
- rtnl_unlock();
-
break;
case CAN_RAW_ERR_FILTER:
@@ -658,16 +644,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
err_mask &= CAN_ERR_MASK;
- rtnl_lock();
- lock_sock(sk);
-
dev = ro->dev;
- if (ro->bound && dev) {
- if (dev->reg_state != NETREG_REGISTERED) {
- err = -ENODEV;
- goto out_err;
- }
- }
+ if (ro->bound && dev && dev->reg_state != NETREG_REGISTERED)
+ return -ENODEV;
/* remove current error mask */
if (ro->bound) {
@@ -676,7 +655,7 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
err_mask);
if (err)
- goto out_err;
+ return err;
/* remove old err_mask registration */
raw_disable_errfilter(sock_net(sk), dev, sk,
@@ -685,11 +664,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
/* link new err_mask to the socket */
ro->err_mask = err_mask;
-
- out_err:
- release_sock(sk);
- rtnl_unlock();
-
break;
case CAN_RAW_LOOPBACK:
@@ -769,6 +743,26 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
return err;
}
+static int raw_setsockopt(struct socket *sock, int level, int optname,
+ sockptr_t optval, unsigned int optlen)
+{
+ struct sock *sk = sock->sk;
+ int err;
+
+ if (level != SOL_CAN_RAW)
+ return -EINVAL;
+
+ rtnl_lock();
+ lock_sock(sk);
+
+ err = raw_setsockopt_locked(sock, optname, optval, optlen);
+
+ release_sock(sk);
+ rtnl_unlock();
+
+ return err;
+}
+
static int raw_getsockopt(struct socket *sock, int level, int optname,
sockopt_t *opt)
{
base-commit: b266bacba796ff5c4dcd2ae2fc08aacf7ab39153
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v1 net] tcp: Fix out-of-bounds access for twsk in tcp_ao_established_key().
From: Eric Dumazet @ 2026-05-07 11:23 UTC (permalink / raw)
To: Kuniyuki Iwashima, Paul E. McKenney
Cc: Neal Cardwell, David S. Miller, Jakub Kicinski, Paolo Abeni,
Dmitry Safonov, Simon Horman, Kuniyuki Iwashima, netdev,
Damiano Melotti
In-Reply-To: <20260506172830.2237574-1-kuniyu@google.com>
On Wed, May 6, 2026 at 10:28 AM Kuniyuki Iwashima <kuniyu@google.com> wrote:
>
> lockdep_sock_is_held() was added in tcp_ao_established_key()
> by the cited commit.
>
> It can be called from tcp_v[46]_timewait_ack() with twsk.
>
> Since it does not have sk->sk_lock, the lockdep annotation
> results in out-of-bound access.
>
> $ pahole -C tcp_timewait_sock vmlinux | grep size
> /* size: 288, cachelines: 5, members: 8 */
> $ pahole -C sock vmlinux | grep sk_lock
> socket_lock_t sk_lock; /* 440 192 */
>
> Let's not use lockdep_sock_is_held() for TCP_TIME_WAIT.
>
> Fixes: 6b2d11e2d8fc ("net/tcp: Add missing lockdep annotations for TCP-AO hlist traversals")
> Reported-by: Damiano Melotti <melotti@google.com>
> Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
> ---
> net/ipv4/tcp_ao.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
> index a97cdf3e6af4..e2720233e36b 100644
> --- a/net/ipv4/tcp_ao.c
> +++ b/net/ipv4/tcp_ao.c
> @@ -116,7 +116,9 @@ struct tcp_ao_key *tcp_ao_established_key(const struct sock *sk,
> {
> struct tcp_ao_key *key;
>
> - hlist_for_each_entry_rcu(key, &ao->head, node, lockdep_sock_is_held(sk)) {
> + hlist_for_each_entry_rcu(key, &ao->head, node,
> + sk->sk_state == TCP_TIME_WAIT ||
> + lockdep_sock_is_held(sk)) {
> if ((sndid >= 0 && key->sndid != sndid) ||
> (rcvid >= 0 && key->rcvid != rcvid))
> continue;
I wonder if a better fix would be to change __list_check_rcu() evaluation order.
Otherwise, this would mean that a TIME_WAIT socket would evade RCU
LOCKDEP checks.
If a fix in tcp_ao.c is te way to go, I would suggest the opposite of
what you did.
diff --git a/net/ipv4/tcp_ao.c b/net/ipv4/tcp_ao.c
index a97cdf3e6af4cf1ee1cd8c6361944536056543e6..0a4b38b315fed40899901ea5f66fbdffd776df38
100644
--- a/net/ipv4/tcp_ao.c
+++ b/net/ipv4/tcp_ao.c
@@ -116,7 +116,8 @@ struct tcp_ao_key *tcp_ao_established_key(const
struct sock *sk,
{
struct tcp_ao_key *key;
- hlist_for_each_entry_rcu(key, &ao->head, node,
lockdep_sock_is_held(sk)) {
+ hlist_for_each_entry_rcu(key, &ao->head, node,
+ sk_fullsock(sk) && lockdep_sock_is_held(sk)) {
if ((sndid >= 0 && key->sndid != sndid) ||
(rcvid >= 0 && key->rcvid != rcvid))
continue;
^ permalink raw reply
* Re: [PATCH net v1] net/mlx5e: CT: Fix NAT miss rule cleanup on init failure
From: Tariq Toukan @ 2026-05-07 11:23 UTC (permalink / raw)
To: Prathamesh Deshpande, Saeed Mahameed, Leon Romanovsky
Cc: Tariq Toukan, Chris Mi, netdev, linux-rdma, linux-kernel
In-Reply-To: <20260505235029.51045-1-prathameshdeshpande7@gmail.com>
On 06/05/2026 2:48, Prathamesh Deshpande wrote:
> mlx5_tc_ct_init() creates the CT-NAT miss rule before initializing the
> conntrack hash tables, workqueue and flow-steering state.
>
> If one of those later initialization steps fails, the error path destroys
> the CT-NAT table but does not delete the miss rule and flow group created
> in that table.
>
> Add a dedicated unwind step to delete the CT-NAT miss rule before
> destroying the CT-NAT table.
>
> Fixes: 49d37d05f216 ("net/mlx5: CT: Separate CT and CT-NAT tuple entries")
> Signed-off-by: Prathamesh Deshpande <prathameshdeshpande7@gmail.com>
> ---
> drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
> index 6c87a1c7db09..15e406d29004 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_ct.c
> @@ -2349,7 +2349,7 @@ mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
> &ct_priv->ct_nat_miss_group,
> &ct_priv->ct_nat_miss_rule);
> if (err)
> - goto err_ct_zone_ht;
> + goto err_ct_nat_miss_rule;
>
> ct_priv->post_act = post_act;
> mutex_init(&ct_priv->control_lock);
> @@ -2382,6 +2382,9 @@ mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains,
> err_ct_tuples_ht:
> rhashtable_destroy(&ct_priv->zone_ht);
> err_ct_zone_ht:
> + tc_ct_del_ct_table_miss_rule(ct_priv->ct_nat_miss_group,
> + ct_priv->ct_nat_miss_rule);
> +err_ct_nat_miss_rule:
> mlx5_chains_destroy_global_table(chains, ct_priv->ct_nat);
> err_ct_nat_tbl:
> mlx5_chains_destroy_global_table(chains, ct_priv->ct);
Reviewed-by: Tariq Toukan <tariqt@nvidia.com>
Thanks.
^ permalink raw reply
* Re: [PATCH net-next v3 2/2] net: openvswitch: decouple flow_table from ovs_mutex
From: Paolo Abeni @ 2026-05-07 11:31 UTC (permalink / raw)
To: Adrian Moreno, netdev
Cc: aconole, Eelco Chaudron, Ilya Maximets, David S. Miller,
Eric Dumazet, Jakub Kicinski, Simon Horman, open list:OPENVSWITCH,
open list
In-Reply-To: <20260505084253.998548-3-amorenoz@redhat.com>
On 5/5/26 10:42 AM, Adrian Moreno wrote:
> In order to protect flow operations from RTNL contention, this patch
> decouples flow_table modifications from ovs_mutex by means of the
> following:
>
> 1 - Create a new mutex inside the flow_table that protects it from
> concurrent modifications.
> Putting the mutex inside flow_table makes it easier to consume for
> functions inside flow_table.c that do not currently take pointers to the
> datapath.
> Some function signatures need to be changed to accept flow_table so that
> lockdep checks can be performed.
>
> 2 - Create a reference count to temporarily extend rcu protection from
> the datapath to the flow_table.
> One reference is held by the datapath, the other is temporarily
> increased during flow modifications.
>
> Signed-off-by: Adrian Moreno <amorenoz@redhat.com>
> ---
> net/openvswitch/datapath.c | 230 ++++++++++++++++++++++-------------
> net/openvswitch/flow.c | 13 +-
> net/openvswitch/flow.h | 9 +-
> net/openvswitch/flow_table.c | 173 ++++++++++++++++----------
> net/openvswitch/flow_table.h | 53 +++++++-
> 5 files changed, 318 insertions(+), 160 deletions(-)
This is still considerably big. I'm wondering if introducing the
lockdep_ovs_tbl_is_held/rcu_dereference_ovs_tbl annotations with a
separate earlier patch would make it more palatable? Just a very wild
guess; if the result is ugly (or you have string feeling that would be)
please ignore.
> @@ -1112,7 +1132,8 @@ static int ovs_flow_cmd_new(struct sk_buff *skb, struct genl_info *info)
> ufid_flags);
> BUG_ON(error < 0);
> }
> - ovs_unlock();
> + mutex_unlock(&table->lock);
> + ovs_flow_tbl_put(table);
Minot nit: you can consolidate 2 ovs_flow_tbl_put() calls after the
if/than/else statement.
@@ -524,9 +540,22 @@ void ovs_flow_tbl_destroy_rcu(struct rcu_head *rcu)
> call_rcu(&mc->rcu, mask_cache_rcu_cb);
> call_rcu(&ma->rcu, mask_array_rcu_cb);
> table_instance_destroy(ti, ufid_ti);
> + mutex_destroy(&table->lock);
> kfree(table);
> }
>
> +void ovs_flow_tbl_put(struct flow_table *table)
> +{
> + if (refcount_dec_and_test(&table->refcnt)) {
> + mutex_lock(&table->lock);
> + table_instance_flow_flush(table,
> + ovs_tbl_dereference(table->ti, table),
> + ovs_tbl_dereference(table->ufid_ti, table));
> + mutex_unlock(&table->lock);
As mentioned in the previous patch you can follow-up moving here the
call_rcu(&mc->rcu, mask_cache_rcu_cb);
call_rcu(&ma->rcu, mask_array_rcu_cb);
currently in ovs_flow_tbl_destroy_rcu.
> +/* Must be called with flow_table->lock held. */
> int ovs_flow_tbl_flush(struct flow_table *flow_table)
> {
> struct table_instance *old_ti, *new_ti;
> struct table_instance *old_ufid_ti, *new_ufid_ti;
>
> + ASSERT_OVS_TBL(flow_table);
Minor nit: adding the assert and the comment is redundant. I think the
assert alone would be better. There are other similar later occurrences.
/P
^ permalink raw reply
* Re: [PATCH v3 net-next 1/3] ipv4: Provide a FIB flushing signal from nexthop removal functions
From: Ido Schimmel @ 2026-05-07 11:40 UTC (permalink / raw)
To: Cosmin Ratiu
Cc: netdev, David Ahern, Kuniyuki Iwashima, David S . Miller,
Eric Dumazet, Jakub Kicinski, Simon Horman, Paolo Abeni
In-Reply-To: <20260507075606.322405-2-cratiu@nvidia.com>
On Thu, May 07, 2026 at 10:56:04AM +0300, Cosmin Ratiu wrote:
> Plumb a bool value throughout the various nexthop removal functions,
> determined in the innermost __remove_nexthop_fib() (which still does the
> FIB flushing) and propagated up all callers.
>
> The next patch will make use of this signal to optimize the removal of
> multiple nexthops by moving the FIB flushing up the call hierarchy.
>
> Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
^ permalink raw reply
* Re: [PATCH] dt-bindings: net: lan966x: Accept standard ethernet prefixes
From: Herve Codina @ 2026-05-07 11:40 UTC (permalink / raw)
To: Linus Walleij
Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Horatiu Vultur, netdev, devicetree
In-Reply-To: <20260507-lan966-binding-v1-1-e99293d2a4ec@kernel.org>
Hi Linus,
On Thu, 07 May 2026 11:26:01 +0200
Linus Walleij <linusw@kernel.org> wrote:
> The dsa.yaml and ethernet-switch.yaml bindings recommend
> prefixing ethernet switches and ports with "ethernet-" so
> make the LAN966x do the same.
>
> Reported-by: Herve Codina <herve.codina@bootlin.com>
> Signed-off-by: Linus Walleij <linusw@kernel.org>
> ---
> .../devicetree/bindings/net/microchip,lan966x-switch.yaml | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> index 306ef9ecf2b9..0f0f35865ef4 100644
> --- a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> +++ b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> @@ -17,7 +17,7 @@ description: |
>
> properties:
> $nodename:
> - pattern: "^switch@[0-9a-f]+$"
> + pattern: "^(ethernet-)?switch@[0-9a-f]+$"
>
> compatible:
> const: microchip,lan966x-switch
> @@ -70,7 +70,7 @@ properties:
> additionalProperties: false
>
> patternProperties:
> - "^port@[0-9a-f]+$":
> + "^(ethernet-)?port@[0-9a-f]+$":
> type: object
>
> $ref: /schemas/net/ethernet-controller.yaml#
> @@ -138,7 +138,7 @@ additionalProperties: false
> examples:
> - |
> #include <dt-bindings/interrupt-controller/arm-gic.h>
> - switch: switch@e0000000 {
> + switch: ethernet-switch@e0000000 {
> compatible = "microchip,lan966x-switch";
> reg = <0xe0000000 0x0100000>,
> <0xe2000000 0x0800000>;
> @@ -151,14 +151,14 @@ examples:
> #address-cells = <1>;
> #size-cells = <0>;
>
> - port0: port@0 {
> + port0: ethernet-port@0 {
> reg = <0>;
> phy-handle = <&phy0>;
> phys = <&serdes 0 0>;
> phy-mode = "gmii";
> };
>
> - port1: port@1 {
> + port1: ethernet-port@1 {
> reg = <1>;
> sfp = <&sfp_eth1>;
> managed = "in-band-status";
>
> ---
> base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
> change-id: 20260507-lan966-binding-0df62a018509
>
> Best regards,
> --
> Linus Walleij <linusw@kernel.org>
>
With those changes, dtb_check will not be happy when following dtsi/dts are
involved:
- arch/arm/boot/dts/microchip/lan966x.dtsi
- arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt.dtsi
- arch/arm/boot/dts/microchip/lan966x-pcb8290.dts
- arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt-6g-2gs.dts
- arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt-8g.dts
IMHO they should be updated as part of the series.
Best regards,
Hervé
^ permalink raw reply
* Re: [PATCH v3 net-next 2/3] ipv4: Flush the FIB once on multiple nexthop removal
From: Ido Schimmel @ 2026-05-07 11:40 UTC (permalink / raw)
To: Cosmin Ratiu
Cc: netdev, David Ahern, Kuniyuki Iwashima, David S . Miller,
Eric Dumazet, Jakub Kicinski, Simon Horman, Paolo Abeni
In-Reply-To: <20260507075606.322405-3-cratiu@nvidia.com>
On Thu, May 07, 2026 at 10:56:05AM +0300, Cosmin Ratiu wrote:
> When a device is going down or when a net namespace is deleted, all
> nexthops on it are removed, and for each nexthop being removed the FIB
> table is flushed, which does a full trie traversal looking for entries
> marked RTNH_F_DEAD and removing them. This is O(N x R), with N being
> number of dev nexthops and R being number of IPv4 routes.
>
> The RTNL is held the entire time.
>
> When there are many nexthops to be removed and many routing entries,
> this can result in the RTNL being held for multiple minutes, which
> causes unhappiness in other processes trying to acquire the RTNL (e.g.
> systemd-networkd for DHCP renewals).
>
> In a complicated deployment with multiple vxlan devices, each having
> 16K nexthops and a total of 128K ipv4 routes, this is exactly what
> happens:
>
> nexthop_flush_dev() # loops over 16K nexthops
> -> remove_nexthop()
> -> __remove_nexthop()
> -> __remove_nexthop_fib() # marks fi->fib_flags |= RTNH_F_DEAD
> -> fib_flush() # for EACH nexthop!
> -> fib_table_flush() # walks the ENTIRE FIB, 128K entries
>
> This patch makes use of the previously added FIB flushing signal to only
> do a single FIB flush after all nexthops to be removed are marked as
> RTNH_F_DEAD:
> - __remove_nexthop_fib() no longer flushes the FIB.
> - nexthop_flush_dev() and flush_all_nexthops() now keep track whether
> any nexthop was removed and trigger a FIB flush at the end.
> - a new wrapper is defined, remove_one_nexthop() which calls
> remove_nexthop() and flushes if necessary. This is intended for places
> which must remove a single nexthop and shouldn't worry about the need
> to trigger a FIB flush. For now, the only caller is rtm_del_nexthop().
> - The two direct callers of __remove_nexthop() get a WARN_ON_ONCE, since
> the nh about to be removed should not have any FIB entries referencing
> it when replacing or inserting a new one.
>
> This dramatically improves performance from O(N x R) to O(N + R).
>
> Releasing a nexthop reference in remove_nexthop() now no longer frees
> it. Instead, it is deleted when the last fib_info pointing to it gets
> freed via free_fib_info_rcu(). All routing code is already careful not
> to take into consideration routes marked with RTNH_F_DEAD.
>
> Tested with:
> DEV=eth2
> ip link set up dev $DEV
> ip link add testnh0 link $DEV type macvlan mode bridge
> ip addr add 198.51.100.1/24 dev testnh0
> ip link set testnh0 up
>
> seq 1 65536 | \
> sed 's/.*/nexthop add id & via 198.51.100.2 dev testnh0/' | \
> ip -batch -
>
> i=1
> for a in $(seq 0 255); do
> for b in $(seq 0 255); do
> echo "route add 10.${a}.${b}.0/32 nhid $i"
> i=$((i + 1))
> done
> done | ip -batch -
>
> time ip link set testnh0 down
> ip link del testnh0
>
> Without this patch:
> real 0m32.601s
> user 0m0.000s
> sys 0m32.511s
>
> With this patch:
> real 0m0.209s
> user 0m0.000s
> sys 0m0.153s
>
> Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
^ permalink raw reply
* Re: [PATCH v3 net-next 3/3] ipv4: Add __must_check to nexthop removal functions
From: Ido Schimmel @ 2026-05-07 11:41 UTC (permalink / raw)
To: Cosmin Ratiu
Cc: netdev, David Ahern, Kuniyuki Iwashima, David S . Miller,
Eric Dumazet, Jakub Kicinski, Simon Horman, Paolo Abeni
In-Reply-To: <20260507075606.322405-4-cratiu@nvidia.com>
On Thu, May 07, 2026 at 10:56:06AM +0300, Cosmin Ratiu wrote:
> These functions return a signal whether FIB flushing is required which
> must not be ignored. Use the compiler to help with enforcing this
> requirement in the future.
>
> Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
^ permalink raw reply
* Re: [PATCH net-next 12/13] dpaa2-switch: add support for imprecise source port
From: Ioana Ciornei @ 2026-05-07 11:42 UTC (permalink / raw)
To: andrew+netdev, davem, edumazet, kuba, pabeni, netdev; +Cc: linux-kernel
In-Reply-To: <20260506151540.1242997-13-ioana.ciornei@nxp.com>
On Wed, May 06, 2026 at 06:15:39PM +0300, Ioana Ciornei wrote:
> Switch ports configured as part of a LAG group are not able to provide
> a precise source port for all packets which reach the control interface.
>
> The only frames which will have a precise source port are those that are
> explicitly trapped, for example STP and LCAP frames. For any other
> frames (for example, those which are flooded) we can only know the
> ingress LAG group.
>
> Take into account the DPAA2_ETHSW_FLC_IMPRECISE_IF_ID bit and based on
> its value target the bond device or the specific source netdevice.
>
> Signed-off-by: Ioana Ciornei <ioana.ciornei@nxp.com>
> ---
> drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 10 ++++++++--
> drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h | 3 +++
> 2 files changed, 11 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c
> index 59ed06ed7ef6..8353d2230c72 100644
(...)
> --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
> +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h
> @@ -87,6 +87,9 @@
>
> #define DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE 256
>
> +#define DPAA2_ETHSW_FLC_IF_ID(flc) (((flc) >> 32) & GENMASK(15, 0))
> +#define DPAA2_ETHSW_FLC_IMPRECISE_IF_ID(flc) ((flc) & BIT(63))
I saw the patchwork test - this breaks the build_32bit test.
I will use BIT_ULL in the next version.
Ioana
^ permalink raw reply
* Re: [PATCH net] vsock/virtio: fix potential unbounded skb queue
From: Michael S. Tsirkin @ 2026-05-07 11:45 UTC (permalink / raw)
To: Stefano Garzarella
Cc: Eric Dumazet, Arseniy Krasnov, Bobby Eshleman, Stefan Hajnoczi,
David S . Miller, Jakub Kicinski, Paolo Abeni, Simon Horman,
netdev, eric.dumazet, Arseniy Krasnov, Jason Wang, Xuan Zhuo,
Eugenio Pérez, kvm, virtualization
In-Reply-To: <afxVH2So9BbZ3Gta@sgarzare-redhat>
On Thu, May 07, 2026 at 11:09:47AM +0200, Stefano Garzarella wrote:
> On Wed, May 06, 2026 at 11:37:45AM -0400, Michael S. Tsirkin wrote:
> > On Tue, May 05, 2026 at 06:11:13PM +0200, Stefano Garzarella wrote:
> > > On Tue, May 05, 2026 at 07:14:36AM -0700, Eric Dumazet wrote:
> > > > On Tue, May 5, 2026 at 6:52 AM Stefano Garzarella <sgarzare@redhat.com> wrote:
> > > > >
> > > > > On Thu, Apr 30, 2026 at 12:26:52PM +0000, Eric Dumazet wrote:
> > > > > >virtio_transport_inc_rx_pkt() checks vvs->rx_bytes + len > vvs->buf_alloc.
> > > > > >
> > > > > >virtio_transport_recv_enqueue() skips coalescing for packets
> > > > > >with VIRTIO_VSOCK_SEQ_EOM.
> > > > > >
> > > > > >If fed with packets with len == 0 and VIRTIO_VSOCK_SEQ_EOM,
> > > > > >a very large number of packets can be queued
> > > > > >because vvs->rx_bytes stays at 0.
> > > > > >
> > > > > >Fix this by estimating the skb metadata size:
> > > > > >
> > > > > > (Number of skbs in the queue) * SKB_TRUESIZE(0)
> > > > > >
> > > > > >Fixes: 077706165717 ("virtio/vsock: don't use skbuff state to account credit")
> > > > > >Signed-off-by: Eric Dumazet <edumazet@google.com>
> > > > > >Cc: Arseniy Krasnov <AVKrasnov@sberdevices.ru>
> > > > > >Cc: Stefan Hajnoczi <stefanha@redhat.com>
> > > > > >Cc: Stefano Garzarella <sgarzare@redhat.com>
> > > > > >Cc: "Michael S. Tsirkin" <mst@redhat.com>
> > > > > >Cc: Jason Wang <jasowang@redhat.com>
> > > > > >Cc: Xuan Zhuo <xuanzhuo@linux.alibaba.com>
> > > > > >Cc: "Eugenio Pérez" <eperezma@redhat.com>
> > > > > >Cc: kvm@vger.kernel.org
> > > > > >Cc: virtualization@lists.linux.dev
> > > > > >---
> > > > > > net/vmw_vsock/virtio_transport_common.c | 4 +++-
> > > > > > 1 file changed, 3 insertions(+), 1 deletion(-)
> > > > > >
> > > > > >diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
> > > > > >index 416d533f493d7b07e9c77c43f741d28cfcd0953e..9b8014516f4fb1130ae184635fbba4dfee58bd64 100644
> > > > > >--- a/net/vmw_vsock/virtio_transport_common.c
> > > > > >+++ b/net/vmw_vsock/virtio_transport_common.c
> > > > > >@@ -447,7 +447,9 @@ static int virtio_transport_send_pkt_info(struct vsock_sock *vsk,
> > > > > > static bool virtio_transport_inc_rx_pkt(struct virtio_vsock_sock *vvs,
> > > > > > u32 len)
> > > > > > {
> > > > > >- if (vvs->buf_used + len > vvs->buf_alloc)
> > > > > >+ u64 skb_overhead = (skb_queue_len(&vvs->rx_queue) + 1) * SKB_TRUESIZE(0);
> > > > > >+
> > > > > >+ if (skb_overhead + vvs->buf_used + len > vvs->buf_alloc)
> > > > > > return false;
> > > > >
> > > > > I'm not sure about this fix, I mean that maybe this is incomplete.
> > > > > In virtio-vsock, there is a credit mechanism between the two peers:
> > > > > https://docs.oasis-open.org/virtio/virtio/v1.3/csd01/virtio-v1.3-csd01.html#x1-4850003
> > > > >
> > > > > This takes only the payload into account, so it’s true that this problem
> > > > > exists; however, perhaps we should also inform the other peer of a lower
> > > > > credit balance, otherwise the other peer will believe it has much more
> > > > > credit than it actually does, send a large payload, and then the packet
> > > > > will be discarded and the data lost (there are no retransmissions,
> > > > > etc.).
> > > >
> > > > I dunno, perhaps revert 077706165717 ("virtio/vsock: don't use skbuff
> > > > state to account credit")
> > > > and find a better fix then?
> > >
> > > IIRC the same issue was there before the commit fixed by that one (commit
> > > 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff")), so
> > > not sure about reverting it TBH.
> > >
> > > CCing Arseniy and Bobby.
> > >
> > > >
> > > > There is always a discrepancy between skb->len and skb->truesize.
> > > > You will not be able to announce a 1MB window, and accept one milliion
> > > > skb of 1-byte each.
> > > >
> > > > This kind of contract is broken.
> > > >
> > >
> > > Yep, I agree, but before we start discarding data (and losing it), IMHO we
> > > should at least inform the other peer that we're out of space.
> > >
> > > @Stefan, @Michael, do you think we can do something in the spec to avoid
> > > this issue and in some way take into account also the metadata in the
> > > credit. I mean to avoid the 1-byte packets flooding.
> > >
> > > Thanks,
> > > Stefano
> >
> > Why do we need the metadata? Just don't keep it around if you begin
> > running low on memory.
>
> I don't think removing the skuffs will be easy; we added them for ebpf,
> zero-copy, and seqpacket as well.
You do not need to remove them completely.
> For now, we're already doing something:
> merging the skuffs if they don't have EOM set.
Right that's good. You could go further and merge with EOM too
if you stick the info about message boundaries somewhere else.
> As a quick fix, I'm thinking of reducing the `buf_alloc` value to account
> for the overhead and notifying the other peer, at least until we find a
> better solution.
>
> Stefano
well if you want to support pathological cases such as 1 byte messages
that would mean like 100x reduction no?
^ permalink raw reply
* Re: [PATCH net-next v2] declance: Remove IRQF_ONESHOT
From: Maciej W. Rozycki @ 2026-05-07 11:45 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: netdev, linux-mips, Jakub Kicinski, Andrew Lunn, David S. Miller,
Eric Dumazet, Paolo Abeni
In-Reply-To: <20260507073427.atoJ5zsY@linutronix.de>
On Thu, 7 May 2026, Sebastian Andrzej Siewior wrote:
> > The interrupt is exceedingly rare, I've only seen it actually fire maybe
> > a dozen times across all my systems in 25+ years. It happens when there
> > is a memory read error on DMA, such as an uncorrected ECC or parity error
> > (depending on the system variant), or a bus timeout.
>
> I assumed you have other interrupts on that hw, cascaded/ operating the
> same way. But otherwise…
Hardware does have such stuff, but we don't make use of any other sources
right now.
We don't use DMA with the SCC serial ports -- I've had plans to wire that
even for asynchronous operation, because with the 3-entry only input FIFO
it's quite easy for characters to get lost at higher baud rates; we have
no driver support for the synchronous modes with these systems although
hardware has all the necessary circuitry and external port connections.
And the driver for the ESP SCSI interface was sadly lost in a conversion
many years ago when I got stuck due to a peculiarity with the hardware and
never completed it, which is a shame, but there you go -- I still hope to
do that one day, and that I consider much higher priority than DMA for the
SCC.
Another system model, the Personal DECstation, also has ISDN and sound
interfaces wired for DMA, but no driver was ever written/ported for either
and no one running Linux seems to have a specimen available anymore. I
think NetBSD guys have full support for that system.
So yeah, right now it's only LANCE that makes use of any of the DMA IRQs,
and it's actually the least complext arrangement of all the devices: LANCE
makes use of 1 DMA IRQ, ESP makes use of 3 and the SCC ports make use of 4
each. Each has one IRQ dedicated to memory read errors, and ESP and SCC
also have one each for overrun errors. The remaining IRQs are for regular
DMA operation, i.e. buffer flipping, which LANCE does not do as it makes
use of the usual DMA descriptor ring arrangement instead.
Maciej
^ permalink raw reply
* Re: [PATCH iwl-next v2 3/5] ice: add correct handling of SMA/u.FL states
From: Simon Horman @ 2026-05-07 11:45 UTC (permalink / raw)
To: aleksandr.loktionov
Cc: 'Simon Horman', intel-wired-lan, anthony.l.nguyen, netdev
In-Reply-To: <20260504142451.4161845-4-aleksandr.loktionov@intel.com>
From: 'Simon Horman' <horms@kernel.org>
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
Simon says:
I would also like to add that as a fix the patch description should
describe the user-visible effects of the bug, and how the fix addresses
them.
Thanks!
---
ice: add correct handling of SMA/u.FL states
This commit renames ICE_SMA2_UFL2_RX_DIS to ICE_SMA2_UFL2_RX_EN, stating that
the hardware bit is actually active high for enabling RX. It updates the uses
of the macro in ice_dpll.c to reflect the new name.
> The ICE_SMA2_UFL2_RX_DIS bit name is wrong: the bit is active high
> (setting it *enables* RX for u.FL2 / SMA2), not active low. Rename
> it to ICE_SMA2_UFL2_RX_EN and invert the use sites in ice_dpll.c so
> that enabling the u.FL2 pin clears the bit (as it used to do) and
> disabling sets it.
The commit message claims that setting the bit enables RX (active high), but
then states that enabling the pin clears the bit (active low). Could this
description be clarified to explain exactly whether the hardware uses active
high or active low logic?
> diff --git a/drivers/net/ethernet/intel/ice/ice_dpll.c b/drivers/net/ethernet/intel/ice/ice_dpll.c
> index 62f75701d6520..7e8bb63b262a0 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dpll.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dpll.c
> @@ -672,7 +672,7 @@ ice_dpll_sw_pins_update(struct ice_pf *pf)
> p->active = false;
>
> p = &d->ufl[ICE_DPLL_PIN_SW_2_IDX];
> - p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_DIS);
> + p->active = (data & ICE_SMA2_DIR_EN) && !(data & ICE_SMA2_UFL2_RX_EN);
If the bit is renamed to an _EN suffix and is active high, should the logic be
inverted here? This code still treats the bit as active low by checking for it
being cleared (!(data & ICE_SMA2_UFL2_RX_EN)).
[ ... ]
> @@ -1264,10 +1264,10 @@ ice_dpll_ufl_pin_state_set(const struct dpll_pin *pin, void *pin_priv,
> case ICE_DPLL_PIN_SW_2_IDX:
> if (state == DPLL_PIN_STATE_SELECTABLE) {
> data |= ICE_SMA2_DIR_EN;
> - data &= ~ICE_SMA2_UFL2_RX_DIS;
> + data &= ~ICE_SMA2_UFL2_RX_EN;
> enable = true;
> } else if (state == DPLL_PIN_STATE_DISCONNECTED) {
> - data |= ICE_SMA2_UFL2_RX_DIS;
> + data |= ICE_SMA2_UFL2_RX_EN;
> enable = false;
> } else {
Similarly, does this code still apply active low logic by clearing the _EN bit
when enable is true, and setting it when enable is false?
If the bit is truly active high as the commit message suggests ("setting it
enables RX"), shouldn't the bitwise operations be inverted to match?
^ permalink raw reply
* Re: [PATCH iwl-next v2 5/5] ice: use element-by-element comparison for DCB config changes
From: Simon Horman @ 2026-05-07 11:46 UTC (permalink / raw)
To: aleksandr.loktionov
Cc: 'Simon Horman', intel-wired-lan, anthony.l.nguyen, netdev
In-Reply-To: <20260504142451.4161845-6-aleksandr.loktionov@intel.com>
From: 'Simon Horman' <horms@kernel.org>
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
---
Subject: ice: use element-by-element comparison for DCB config changes
This commit replaces the use of memcmp() for DCB configurations with an
element-by-element comparison using ice_dcb_need_recfg(). It exports this
function and applies it to the SW DCB netlink setters to prevent issues
with uninitialized padding bytes.
> diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_nl.c b/drivers/net/ethernet/intel/ice/ice_dcb_nl.c
> index a10c1c8d86977..13a52c1a4da3e 100644
> --- a/drivers/net/ethernet/intel/ice/ice_dcb_nl.c
> +++ b/drivers/net/ethernet/intel/ice/ice_dcb_nl.c
> @@ -108,11 +108,17 @@ static int ice_dcbnl_setets(struct net_device *netdev, struct ieee_ets *ets)
> if (!bwrec)
> new_cfg->etsrec.tcbwtable[0] = 100;
>
> + if (!ice_dcb_need_recfg(pf, &pf->hw.port_info->qos_cfg.local_dcbx_cfg,
> + new_cfg)) {
> + err = ICE_DCB_NO_HW_CHG;
> + goto ets_out;
> + }
Does ice_dcb_need_recfg() correctly detect bandwidth changes?
Looking at the implementation of ice_dcb_need_recfg(), it only logs a debug
message but doesn't set need_reconfig to true when only the ETS Bandwidth
Table or TSA Table changes:
drivers/net/ethernet/intel/ice/ice_dcb_lib.c:ice_dcb_need_recfg() {
...
if (memcmp(&new_cfg->etscfg.tcbwtable,
&old_cfg->etscfg.tcbwtable,
sizeof(new_cfg->etscfg.tcbwtable)))
dev_dbg(dev, "ETS TC BW Table changed.\n");
...
}
Since the function returns false, will this cause ice_dcbnl_setets() to
abort early and silently drop user-requested bandwidth modifications?
Also, since new_cfg points to the shared desired_dcbx_cfg state, does this
early return leave uncommitted modifications in the software state?
If a subsequent unrelated operation (like setting PFC) correctly returns
true from ice_dcb_need_recfg(), it appears it could unintentionally push
these abandoned ETS bandwidth changes to the hardware.
> err = ice_pf_dcb_cfg(pf, new_cfg, true);
> /* return of zero indicates new cfg applied */
> - if (err == ICE_DCB_HW_CHG_RST)
> + if (!err)
> ice_dcbnl_devreset(netdev);
This isn't a bug introduced by this patch, but can ice_dcbnl_devreset()
cause a deadlock against hardware reset tasks?
The ice_dcbnl_devreset() function spins in a usleep_range() loop while
ice_is_reset_in_progress() is true.
Since DCBNL callbacks like ice_dcbnl_setets() run with the global
rtnl_lock held, and a concurrent hardware or PCIe reset worker likely
requires rtnl_lock to complete the reset, will the reset task block
forever while this thread waits for it?
> - if (err == ICE_DCB_NO_HW_CHG)
> + else if (err == ICE_DCB_NO_HW_CHG)
> err = ICE_DCB_HW_CHG_RST;
>
> ets_out:
Does this change cause the function to return a positive error code to
userspace when applying an identical configuration?
By bypassing the translation from ICE_DCB_NO_HW_CHG (which is 1) to
ICE_DCB_HW_CHG_RST (which evaluates to 0) in the early goto added
above, err remains 1 at the ets_out label.
The DCBNL core evaluates any non-zero return value as an error:
net/dcb/dcbnl.c:dcbnl_ieee_set() {
...
err = netdev->dcbnl_ops->ieee_setets(netdev, ets);
if (err)
goto err;
...
}
Will this cause tools like lldptool to fail when configuring an
existing setup?
[ ... ]
> @@ -845,6 +858,12 @@ static int ice_dcbnl_setapp(struct net_device *netdev, struct dcb_app *app)
> new_cfg->dscp_map[app->protocol] = app->priority;
> new_cfg->app[new_cfg->numapps++] = new_app;
This isn't a bug introduced by this patch, but does this array append
lack bounds checking against ICE_DCBX_MAX_APPS?
The app array has a capacity of 64. The function restricts duplicate
DSCP protocols using the dscp_mapped bitmap, but since DSCP_MAX is also
64, a user could map all 64 unique values.
If numapps starts greater than 0 due to existing EtherType applications,
adding 64 valid DSCP mappings would cause numapps to exceed 64, leading
to an out-of-bounds write that overwrites the adjacent dscp_mapped
bitmap.
^ permalink raw reply
* Re: [PATCH net 09/13] ice: fix setting RSS VSI hash for E830
From: Marcin Szycik @ 2026-05-07 11:47 UTC (permalink / raw)
To: Jacob Keller, Przemek Kitszel, Andrew Lunn, David S. Miller,
Eric Dumazet, Jakub Kicinski, Paolo Abeni, Piotr Kwapulinski,
Aleksandr Loktionov, Arkadiusz Kubalewski, Maciej Fijalkowski,
Joshua Hay, Madhu Chittim, Willem de Bruijn, Dave Ertman,
Ivan Vecera, Grzegorz Nitka
Cc: netdev, stable
In-Reply-To: <068a5266-4721-4496-b027-3b32da3e02ea@intel.com>
On 06.05.2026 23:06, Jacob Keller wrote:
> On 5/4/2026 10:14 PM, Jacob Keller wrote:
>> From: Marcin Szycik <marcin.szycik@linux.intel.com>
>>
>> ice_set_rss_hfunc() performs a VSI update, in which it sets hashing
>> function, leaving other VSI options unchanged. However, ::q_opt_flags is
>> mistakenly set to the value of another field, instead of its original
>> value, probably due to a typo. What happens next is hardware-dependent:
>>
>> On E810, only the first bit is meaningful (see
>> ICE_AQ_VSI_Q_OPT_PE_FLTR_EN) and can potentially end up in a different
>> state than before VSI update.
>>
>> On E830, some of the remaining bits are not reserved. Setting them
>> to some unrelated values can cause the firmware to reject the update
>> because of invalid settings, or worse - succeed.
>>
>> Reproducer:
>> sudo ethtool -X $PF1 equal 8
>>
>> Output in dmesg:
>> Failed to configure RSS hash for VSI 6, error -5
>>
>> Fixes: 352e9bf23813 ("ice: enable symmetric-xor RSS for Toeplitz hash function")
>> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
>> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
>> Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
>> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
>> ---
>> drivers/net/ethernet/intel/ice/ice_main.c | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_main.c b/drivers/net/ethernet/intel/ice/ice_main.c
>> index 1d1947a7fe11..c52c465280f7 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_main.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_main.c
>> @@ -8046,7 +8046,7 @@ int ice_set_rss_hfunc(struct ice_vsi *vsi, u8 hfunc)
>> ctx->info.q_opt_rss |=
>> FIELD_PREP(ICE_AQ_VSI_Q_OPT_RSS_HASH_M, hfunc);
>> ctx->info.q_opt_tc = vsi->info.q_opt_tc;
>> - ctx->info.q_opt_flags = vsi->info.q_opt_rss;
>> + ctx->info.q_opt_flags = vsi->info.q_opt_flags;
>>
>> err = ice_update_vsi(hw, vsi->idx, ctx, NULL);
>> if (err) {
>>
>
> Sashiko complains about ice_set_rss_hfunc() but it is unrelated to this fix:
>
>> While looking at this function, I noticed a pre-existing issue regarding the
>> hardware cache. Does calling ice_update_vsi() with a local context leave the
>> global hw->vsi_ctx[vsi->idx] out of sync?
>> If ice_update_vsi() succeeds, vsi->info.q_opt_rss is updated, but
>> hw->vsi_ctx[vsi->idx]->info.q_opt_rss is not.
>> When an unrelated feature such as RDMA filtering is subsequently toggled via
>> ice_cfg_rdma_fltr(), could it retrieve this stale cached context via
>> ice_get_vsi_ctx() and copy the stale q_opt_rss value back into its command
>> buffer?
Yes.
>> Could this cause the firmware to silently revert the RSS hash function to its
>> previous configuration during the next ice_update_vsi() call?
No, because the context object passed to ice_update_vsi() only sets
ctx->info.valid_sections for the sections it wants to update, so unrelated
values are not updated in HW.
Looking at other ice_update_vsi() calls, most of the times the context object is
being allocated, not taken from cache. It's not immediately clear to me what
purpose does hw->vsi_ctx[] serve - it only appears to be used in
ice_cfg_rdma_fltr() (correct me if I'm wrong), where options from the cached
context are being read to fill the unchanged fields in the updated section.
This seems to be the equivalent of keeping track of context values in vsi->info,
which is what almost all ice_update_vsi() callers do.
If I had to guess, I'd say hw->vsi_ctx[] could probably be removed and vsi->info
used instead, but maybe I'm missing something.
TLDR I think this is just old, inconsistent code that could be improved, but it
needs some investigation. Until we don't have a clear signal that there's a bug,
I wouldn't touch it.
>> There also appears to be a pre-existing issue with state desynchronization
>> when handling failures. After ice_update_vsi() succeeds, vsi->rss_hfunc
>> is updated, but ice_set_rss_hfunc() then calls ice_set_rss_cfg_symm() at the
>> end of the function:
>> ice_set_rss_hfunc() {
>> ...
>> err = ice_update_vsi(hw, vsi->idx, ctx, NULL);
>> if (err) {
>> ...
>> } else {
>> vsi->info.q_opt_rss = ctx->info.q_opt_rss;
>> vsi->rss_hfunc = hfunc;
>> ...
>> }
>> ...
>> return ice_set_rss_cfg_symm(hw, vsi, symm);
>> }
>> If ice_set_rss_cfg_symm() fails, the error is returned but vsi->rss_hfunc
>> remains updated. If the user retries the command, the early check:
>> if (hfunc == vsi->rss_hfunc)
>> return 0;
>> evaluates to true and returns success immediately.
>> Could this skip the ice_set_rss_cfg_symm() retry entirely, leaving the
>> hardware's flow director rules in a non-symmetric state permanently while
>> falsely reporting success?
This looks valid.
Thanks,
Marcin
> Someone from the ice team should look into this and determine whether or
> not its valid.
^ permalink raw reply
* [PATCH ethtool-next 0/5] ethtool: Add 'pages on|off' option for module EEROM hex dump
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
The existing 'ethtool -m' command can dump module EEPROM data either as
a parsed pretty-print or as a raw/hex dump. The pretty-printer reads
multiple pages per module type, but decodes only specific fields from them.
In practice, both outputs are often needed together for offline debugging:
the pretty-print to identify the module type and decoded fields, and the
hex dump for fields the pretty-printer does not decode. However, there is
no single command that provides the raw hex dump of all relevant pages,
organized by page boundary. This is especially problematic for CMIS
transceivers where the existing hex dump does not provide Upper Pages
beyond Page 02h, let alone banked pages.
This series adds 'pages on|off' sub-option to 'hex on|off' for
'ethtool -m':
$ ethtool -m hex on pages on
That produces a hex dump organized by page, matching exactly the pages read
by the pretty-printer for each module type.
Each page is preceded by a header identifying the page number and, for
banked modules, the bank number. For SFP, where the two memory regions
are separate I2C addresses rather than pages, the header shows the I2C
address instead.
Output example (values zeroed to omit vendor-specific identifiers):
$ ethtool -m swp61 hex on pages on
Page: 0x0
Offset Values
------ ------
0x0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Page: 0x0
Offset Values
------ ------
0x0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Danielle Ratson (5):
module-common: Add module_dump_eeprom_page_hex() helper
sfpid: Refactor sff8079_show_all_nl() to separate page retrieval from
display
module: Add per-type EEPROM page hex dump functions
netlink: module-eeprom: Add 'hex on pages on' option for
page-organized hex dump
ethtool: Add man page and bash completion for 'pages on|off'
cmis.c | 49 +++++++++++++++++++++++----
cmis.h | 2 +-
ethtool.8.in | 14 ++++++++
ethtool.c | 1 +
internal.h | 4 +--
module-common.c | 16 +++++++++
module-common.h | 3 ++
netlink/module-eeprom.c | 43 ++++++++++++++++++++----
qsfp.c | 48 +++++++++++++++++++++++----
sfpid.c | 62 +++++++++++++++++++++++++----------
shell-completion/bash/ethtool | 2 ++
11 files changed, 202 insertions(+), 42 deletions(-)
--
2.51.0
^ permalink raw reply
* [PATCH ethtool-next 2/5] sfpid: Refactor sff8079_show_all_nl() to separate page retrieval from display
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Restructure sff8079_show_all_nl() to first retrieve all the necessary
pages (A0h and optionally A2h) and then pretty-print them, matching the
pattern already used in cmis_show_all_nl() and sff8636_show_all_nl().
This prepares for the next patch which extends the function with a hex
dump mode.
Note that if reading A2h fails, the function now returns an error
without producing partial output, matching the behavior of the other
parsers.
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
sfpid.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/sfpid.c b/sfpid.c
index 228b3ee..f753917 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -500,6 +500,7 @@ static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address,
int sff8079_show_all_nl(struct cmd_context *ctx)
{
+ bool a2h_present;
u8 *buf;
int ret;
@@ -516,24 +517,26 @@ int sff8079_show_all_nl(struct cmd_context *ctx)
if (ret)
goto out;
+ /* Check if A2h page is present */
+ a2h_present = buf[92] & (1 << 6);
+
+ if (a2h_present) {
+ /* Read A2h page */
+ ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_HIGH,
+ buf + ETH_MODULE_SFF_8079_LEN);
+ if (ret) {
+ fprintf(stderr, "Failed to read Page A2h\n");
+ goto out;
+ }
+ }
+
new_json_obj(ctx->json);
open_json_object(NULL);
sff8079_show_all_common(buf);
- /* Finish if A2h page is not present */
- if (!(buf[92] & (1 << 6)))
- goto out_json;
-
- /* Read A2h page */
- ret = sff8079_get_eeprom_page(ctx, SFF8079_I2C_ADDRESS_HIGH,
- buf + ETH_MODULE_SFF_8079_LEN);
- if (ret) {
- fprintf(stderr, "Failed to read Page A2h.\n");
- goto out_json;
- }
+ if (a2h_present)
+ sff8472_show_all(buf);
- sff8472_show_all(buf);
-out_json:
close_json_object();
delete_json_obj();
out:
--
2.51.0
^ permalink raw reply related
* [PATCH ethtool-next 1/5] module-common: Add module_dump_eeprom_page_hex() helper
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Add module_dump_eeprom_page_hex() to module-common.c as the shared
building block for per-type EEPROM page hex dump functions.
It prints a per-page header (page number and optional bank) followed by
a hex dump in the established ethtool format, using dump_hex().
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
module-common.c | 16 ++++++++++++++++
module-common.h | 3 +++
2 files changed, 19 insertions(+)
diff --git a/module-common.c b/module-common.c
index 4e9a0a7..17e4845 100644
--- a/module-common.c
+++ b/module-common.c
@@ -7,6 +7,7 @@
#include <math.h>
#include <ctype.h>
#include "module-common.h"
+#include "internal.h"
const struct module_aw_mod module_aw_mod_flags[] = {
{ MODULE_TYPE_CMIS, "Module temperature high alarm",
@@ -656,3 +657,18 @@ void module_show_dom_mod_lvl_monitors(const struct sff_diags *sd)
PRINT_VCC_ALL("Module voltage", "module_voltage_measurement",
sd->sfp_voltage[MCURR]);
}
+
+/* Print one EEPROM page with a descriptive header followed by hex dump.
+ * When bank is non-zero it is included in the header.
+ */
+void module_dump_eeprom_page_hex(const u8 *data, u8 bank, u8 page,
+ u32 offset, u32 length)
+{
+ if (bank)
+ printf("Bank: 0x%x, Page: 0x%x\n\n", bank, page);
+ else
+ printf("Page: 0x%x\n\n", page);
+
+ dump_hex(stdout, data, length, offset);
+ printf("\n");
+}
diff --git a/module-common.h b/module-common.h
index 985b518..94a3a8e 100644
--- a/module-common.h
+++ b/module-common.h
@@ -284,4 +284,7 @@ void module_show_connector(const __u8 *id, int ctor_offset);
void module_show_mit_compliance(u16 value);
void module_show_dom_mod_lvl_monitors(const struct sff_diags *sd);
+void module_dump_eeprom_page_hex(const u8 *data, u8 bank, u8 page,
+ u32 offset, u32 length);
+
#endif /* MODULE_COMMON_H__ */
--
2.51.0
^ permalink raw reply related
* [PATCH ethtool-next 4/5] netlink: module-eeprom: Add 'hex on pages on' option for page-organized hex dump
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Add 'pages on|off' sub-option to 'hex on|off' for 'ethtool -m'.
When 'hex on pages on' is specified, eeprom_parse() dispatches to the
appropriate per-type function with dump_pages=true, producing a hex dump
of all relevant EEPROM pages with a per-page header showing the page
number and optional bank number.
eeprom_parse() is extended with a bool dump_pages parameter to select
between pretty-print and hex dump output, avoiding duplication of the
module-type dispatch logic.
Unlike plain 'hex on', 'hex on pages on' does not fall back to the ioctl
path, as page selection is handled internally by the per-type functions.
Unknown module types fall back to dumping the lower 128 bytes.
'pages' and 'hex' are both parsed as independent flat options, since the
parameter parser does not support context-dependent argument recognition.
The requirement for 'hex on' when using 'pages on' is enforced by an
explicit validation check.
Output example (values zeroed to omit vendor-specific identifiers):
$ ethtool -m swp61 hex on pages on
Page: 0x0
Offset Values
------ ------
0x0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Page: 0x0
Offset Values
------ ------
0x0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Note: 'Page: 0x0' appears twice in the output. The first block is the
lower memory (bytes 0x00-0x7f), which is always accessible. The second
block is upper memory page 00h (bytes 0x80-0xff). Both carry the same
page label but are distinguished by their offset range in the hex dump.
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
ethtool.c | 1 +
netlink/module-eeprom.c | 43 ++++++++++++++++++++++++++++++++++-------
2 files changed, 37 insertions(+), 7 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index 2444d85..8869c06 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -6165,6 +6165,7 @@ static const struct option args[] = {
.help = "Query/Decode Module EEPROM information and optical diagnostics if available",
.xhelp = " [ raw on|off ]\n"
" [ hex on|off ]\n"
+ " [ pages on|off ]\n"
" [ offset N ]\n"
" [ length N ]\n"
" [ page N ]\n"
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index 7e4e6ac..ce88475 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -25,6 +25,7 @@ struct cmd_params {
unsigned long present;
u8 dump_hex;
u8 dump_raw;
+ u8 dump_pages;
u32 offset;
u32 length;
u32 page;
@@ -83,6 +84,12 @@ static const struct param_parser getmodule_params[] = {
.dest_offset = offsetof(struct cmd_params, i2c_address),
.min_argc = 1,
},
+ {
+ .arg = "pages",
+ .handler = nl_parse_u8bool,
+ .dest_offset = offsetof(struct cmd_params, dump_pages),
+ .min_argc = 1,
+ },
{}
};
@@ -207,7 +214,7 @@ static int eeprom_dump_hex(struct cmd_context *ctx)
return 0;
}
-static int eeprom_parse(struct cmd_context *ctx)
+static int eeprom_parse(struct cmd_context *ctx, bool dump_pages)
{
struct ethtool_module_eeprom request = {
.length = 1,
@@ -228,18 +235,18 @@ static int eeprom_parse(struct cmd_context *ctx)
case MODULE_ID_GBIC:
case MODULE_ID_SOLDERED_MODULE:
case MODULE_ID_SFP:
- return sff8079_show_all_nl(ctx, false);
+ return sff8079_show_all_nl(ctx, dump_pages);
case MODULE_ID_QSFP:
case MODULE_ID_QSFP28:
case MODULE_ID_QSFP_PLUS:
- return sff8636_show_all_nl(ctx, false);
+ return sff8636_show_all_nl(ctx, dump_pages);
case MODULE_ID_QSFP_DD:
case MODULE_ID_OSFP:
case MODULE_ID_DSFP:
case MODULE_ID_QSFP_PLUS_CMIS:
case MODULE_ID_SFP_DD_CMIS:
case MODULE_ID_SFP_PLUS_CMIS:
- return cmis_show_all_nl(ctx, false);
+ return cmis_show_all_nl(ctx, dump_pages);
#endif
default:
/* If we cannot recognize the memory map, default to dumping
@@ -272,10 +279,28 @@ int nl_getmodule(struct cmd_context *ctx)
return -EINVAL;
}
+ if (getmodule_cmd_params.dump_pages && !getmodule_cmd_params.dump_hex) {
+ fprintf(stderr, "Pages dump requires hex on\n");
+ return -EINVAL;
+ }
+
+ if (getmodule_cmd_params.dump_pages &&
+ (getmodule_cmd_params.present & (1 << PARAM_PAGE |
+ 1 << PARAM_BANK |
+ 1 << PARAM_OFFSET |
+ 1 << PARAM_LENGTH |
+ 1 << PARAM_I2C))) {
+ fprintf(stderr,
+ "Pages dump cannot be combined with offset, length, page, bank or i2c\n");
+ return -EINVAL;
+ }
+
/* When complete hex/raw dump of the EEPROM is requested, fallback to
- * ioctl. Netlink can only request specific pages.
+ * ioctl. Netlink can only request specific pages. Skip fallback when
+ * pages dump is requested, as it handles page selection internally.
*/
if ((getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) &&
+ !getmodule_cmd_params.dump_pages &&
!(getmodule_cmd_params.present & (1 << PARAM_PAGE |
1 << PARAM_BANK |
1 << PARAM_I2C))) {
@@ -300,7 +325,11 @@ int nl_getmodule(struct cmd_context *ctx)
if (request.page && !request.offset)
request.offset = 128;
- if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) {
+ if (getmodule_cmd_params.dump_pages) {
+ ret = eeprom_parse(ctx, true);
+ if (ret < 0)
+ goto cleanup;
+ } else if (getmodule_cmd_params.dump_hex || getmodule_cmd_params.dump_raw) {
ret = nl_get_eeprom_page(ctx, &request);
if (ret < 0)
goto cleanup;
@@ -311,7 +340,7 @@ int nl_getmodule(struct cmd_context *ctx)
dump_hex(stdout, request.data, request.length,
request.offset);
} else {
- ret = eeprom_parse(ctx);
+ ret = eeprom_parse(ctx, false);
if (ret < 0)
goto cleanup;
}
--
2.51.0
^ permalink raw reply related
* [PATCH ethtool-next 3/5] module: Add per-type EEPROM page hex dump functions
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Extend sff8079_show_all_nl(), cmis_show_all_nl() and
sff8636_show_all_nl() with a bool dump_pages parameter to support
hex dump output alongside their existing pretty-print output. Each
function first retrieves all the necessary pages and then either
pretty-prints them or performs a hex dump according to the argument.
The hex dump and pretty-print logic is extracted into dedicated static
functions for each parser type:
- cmis_hex_dump() / cmis_pretty_print()
- sff8636_hex_dump() / sff8636_pretty_print()
- sff8079_hex_dump() / sff8079_pretty_print()
Each function dumps the same pages as the corresponding pretty-printer:
- CMIS: uses cmis_memory_map_init_pages() to read the lower memory and
relevant upper pages across all supported banks, using generic iteration
over the memory map. Uses module_dump_eeprom_page_hex() for hex output.
- SFF-8636: uses sff8636_memory_map_init_pages() to read the lower memory
and relevant upper pages, using generic iteration over the memory map.
Uses module_dump_eeprom_page_hex() for hex output.
- SFF-8079: uses sff8079_get_eeprom_page() to read A0h lower and optional
A2h lower and identifies each block by its I2C address. Uses dump_hex()
directly with I2C address headers.
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
cmis.c | 49 +++++++++++++++++++++++++++++++++++------
cmis.h | 2 +-
internal.h | 4 ++--
netlink/module-eeprom.c | 6 ++---
qsfp.c | 48 ++++++++++++++++++++++++++++++++++------
sfpid.c | 43 +++++++++++++++++++++++++++---------
6 files changed, 122 insertions(+), 30 deletions(-)
diff --git a/cmis.c b/cmis.c
index 996e9eb..29592b2 100644
--- a/cmis.c
+++ b/cmis.c
@@ -1022,6 +1022,43 @@ void cmis_show_all_ioctl(const __u8 *id)
cmis_show_all_common(&map);
}
+static void cmis_hex_dump(const struct cmis_memory_map *map)
+{
+ u8 bank, page;
+
+ module_dump_eeprom_page_hex(map->lower_memory, 0, 0x0, 0,
+ CMIS_PAGE_SIZE);
+ for (bank = 0; bank < CMIS_MAX_BANKS; bank++) {
+ for (page = 0; page < CMIS_MAX_PAGES; page++) {
+ const __u8 *buf = map->upper_memory[bank][page];
+
+ if (!buf)
+ continue;
+
+ /* Upper memory starts at one page size into
+ * the buffer, since pages are accessed at
+ * offset between page size and twice the
+ * page size.
+ */
+ module_dump_eeprom_page_hex(buf + CMIS_PAGE_SIZE, bank,
+ page, CMIS_PAGE_SIZE,
+ CMIS_PAGE_SIZE);
+ }
+ }
+}
+
+static void cmis_pretty_print(struct cmd_context *ctx,
+ const struct cmis_memory_map *map)
+{
+ new_json_obj(ctx->json);
+ open_json_object(NULL);
+
+ cmis_show_all_common(map);
+
+ close_json_object();
+ delete_json_obj();
+}
+
static void cmis_request_init(struct ethtool_module_eeprom *request, u8 bank,
u8 page, u32 offset)
{
@@ -1117,21 +1154,19 @@ cmis_memory_map_init_pages(struct cmd_context *ctx,
return 0;
}
-int cmis_show_all_nl(struct cmd_context *ctx)
+int cmis_show_all_nl(struct cmd_context *ctx, bool dump_pages)
{
struct cmis_memory_map map = {};
int ret;
- new_json_obj(ctx->json);
- open_json_object(NULL);
-
ret = cmis_memory_map_init_pages(ctx, &map);
if (ret < 0)
return ret;
- cmis_show_all_common(&map);
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ cmis_hex_dump(&map);
+ else
+ cmis_pretty_print(ctx, &map);
return 0;
}
diff --git a/cmis.h b/cmis.h
index 007632a..82fd245 100644
--- a/cmis.h
+++ b/cmis.h
@@ -201,6 +201,6 @@
void cmis_show_all_ioctl(const __u8 *id);
-int cmis_show_all_nl(struct cmd_context *ctx);
+int cmis_show_all_nl(struct cmd_context *ctx, bool dump_pages);
#endif /* CMIS_H__ */
diff --git a/internal.h b/internal.h
index cbf3c09..19fff41 100644
--- a/internal.h
+++ b/internal.h
@@ -381,14 +381,14 @@ int rxclass_rule_del(struct cmd_context *ctx, __u32 loc);
/* Module EEPROM parsing code */
void sff8079_show_all_ioctl(const __u8 *id);
-int sff8079_show_all_nl(struct cmd_context *ctx);
+int sff8079_show_all_nl(struct cmd_context *ctx, bool dump_pages);
/* Optics diagnostics */
void sff8472_show_all(const __u8 *id);
/* QSFP Optics diagnostics */
void sff8636_show_all_ioctl(const __u8 *id, __u32 eeprom_len);
-int sff8636_show_all_nl(struct cmd_context *ctx);
+int sff8636_show_all_nl(struct cmd_context *ctx, bool dump_pages);
/* FUJITSU Extended Socket network device */
int fjes_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs);
diff --git a/netlink/module-eeprom.c b/netlink/module-eeprom.c
index ce6a7d9..7e4e6ac 100644
--- a/netlink/module-eeprom.c
+++ b/netlink/module-eeprom.c
@@ -228,18 +228,18 @@ static int eeprom_parse(struct cmd_context *ctx)
case MODULE_ID_GBIC:
case MODULE_ID_SOLDERED_MODULE:
case MODULE_ID_SFP:
- return sff8079_show_all_nl(ctx);
+ return sff8079_show_all_nl(ctx, false);
case MODULE_ID_QSFP:
case MODULE_ID_QSFP28:
case MODULE_ID_QSFP_PLUS:
- return sff8636_show_all_nl(ctx);
+ return sff8636_show_all_nl(ctx, false);
case MODULE_ID_QSFP_DD:
case MODULE_ID_OSFP:
case MODULE_ID_DSFP:
case MODULE_ID_QSFP_PLUS_CMIS:
case MODULE_ID_SFP_DD_CMIS:
case MODULE_ID_SFP_PLUS_CMIS:
- return cmis_show_all_nl(ctx);
+ return cmis_show_all_nl(ctx, false);
#endif
default:
/* If we cannot recognize the memory map, default to dumping
diff --git a/qsfp.c b/qsfp.c
index 09d9ace..6e1b9ff 100644
--- a/qsfp.c
+++ b/qsfp.c
@@ -62,9 +62,11 @@
#include "cmis.h"
#include "netlink/extapi.h"
+#define SFF8636_MAX_PAGES 4
+
struct sff8636_memory_map {
const __u8 *lower_memory;
- const __u8 *upper_memory[4];
+ const __u8 *upper_memory[SFF8636_MAX_PAGES];
#define page_00h upper_memory[0x0]
#define page_03h upper_memory[0x3]
};
@@ -1078,21 +1080,53 @@ sff8636_memory_map_init_pages(struct cmd_context *ctx,
return 0;
}
-int sff8636_show_all_nl(struct cmd_context *ctx)
+static void sff8636_hex_dump(const struct sff8636_memory_map *map)
{
- struct sff8636_memory_map map = {};
- int ret;
+ u8 page;
+
+ module_dump_eeprom_page_hex(map->lower_memory, 0, 0x0, 0,
+ SFF8636_PAGE_SIZE);
+ for (page = 0; page < SFF8636_MAX_PAGES; page++) {
+ const __u8 *buf = map->upper_memory[page];
+
+ if (!buf)
+ continue;
+ /* Upper memory starts at one page size into the
+ * buffer, since pages are accessed at offset between
+ * page size and twice the page size.
+ */
+ module_dump_eeprom_page_hex(buf + SFF8636_PAGE_SIZE, 0,
+ page, SFF8636_PAGE_SIZE,
+ SFF8636_PAGE_SIZE);
+ }
+}
+
+static void sff8636_pretty_print(struct cmd_context *ctx,
+ const struct sff8636_memory_map *map)
+{
new_json_obj(ctx->json);
open_json_object(NULL);
+ sff8636_show_all_common(map);
+
+ close_json_object();
+ delete_json_obj();
+}
+
+int sff8636_show_all_nl(struct cmd_context *ctx, bool dump_pages)
+{
+ struct sff8636_memory_map map = {};
+ int ret;
+
ret = sff8636_memory_map_init_pages(ctx, &map);
if (ret < 0)
return ret;
- sff8636_show_all_common(&map);
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ sff8636_hex_dump(&map);
+ else
+ sff8636_pretty_print(ctx, &map);
return 0;
}
diff --git a/sfpid.c b/sfpid.c
index f753917..73e714e 100644
--- a/sfpid.c
+++ b/sfpid.c
@@ -498,7 +498,35 @@ static int sff8079_get_eeprom_page(struct cmd_context *ctx, u8 i2c_address,
return ret;
}
-int sff8079_show_all_nl(struct cmd_context *ctx)
+static void sff8079_hex_dump(const u8 *buf, bool a2h_present)
+{
+ printf("I2C Address: 0x%02x\n\n", SFF8079_I2C_ADDRESS_LOW);
+ dump_hex(stdout, buf, SFF8079_PAGE_SIZE, 0);
+ printf("\n");
+
+ if (a2h_present) {
+ printf("I2C Address: 0x%02x\n\n", SFF8079_I2C_ADDRESS_HIGH);
+ dump_hex(stdout, buf + ETH_MODULE_SFF_8079_LEN,
+ SFF8079_PAGE_SIZE, 0);
+ printf("\n");
+ }
+}
+
+static void sff8079_pretty_print(struct cmd_context *ctx, const u8 *buf,
+ bool a2h_present)
+{
+ new_json_obj(ctx->json);
+ open_json_object(NULL);
+ sff8079_show_all_common(buf);
+
+ if (a2h_present)
+ sff8472_show_all(buf);
+
+ close_json_object();
+ delete_json_obj();
+}
+
+int sff8079_show_all_nl(struct cmd_context *ctx, bool dump_pages)
{
bool a2h_present;
u8 *buf;
@@ -530,15 +558,10 @@ int sff8079_show_all_nl(struct cmd_context *ctx)
}
}
- new_json_obj(ctx->json);
- open_json_object(NULL);
- sff8079_show_all_common(buf);
-
- if (a2h_present)
- sff8472_show_all(buf);
-
- close_json_object();
- delete_json_obj();
+ if (dump_pages)
+ sff8079_hex_dump(buf, a2h_present);
+ else
+ sff8079_pretty_print(ctx, buf, a2h_present);
out:
free(buf);
--
2.51.0
^ permalink raw reply related
* [PATCH ethtool-next 5/5] ethtool: Add man page and bash completion for 'pages on|off'
From: Danielle Ratson @ 2026-05-07 11:47 UTC (permalink / raw)
To: netdev; +Cc: mkubecek, idosch, petrm, Danielle Ratson
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
Add 'pages on|off' to the bash completion for ethtool -m and the
ethtool man page.
The man page documents that 'pages on' requires 'hex on', describes the
per-page header format, and notes that it cannot be combined with
offset, length, page, bank or i2c parameters.
Assisted-by: Claude:claude-sonnet-4.6
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Danielle Ratson <danieller@nvidia.com>
---
ethtool.8.in | 14 ++++++++++++++
shell-completion/bash/ethtool | 2 ++
2 files changed, 16 insertions(+)
diff --git a/ethtool.8.in b/ethtool.8.in
index 32b971a..2cea2bc 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -403,6 +403,7 @@ ethtool \- query or control network driver and hardware settings
.I devname
.B2 raw on off
.B2 hex on off
+.B2 pages on off
.BN offset
.BN length
.BN page
@@ -1431,6 +1432,19 @@ allowed. In such a case
and
.I length
parameters are treated relatively to EEPROM page boundaries.
+When
+.B hex on pages on
+is specified, dumps all relevant EEPROM pages in hex, organized by page.
+Each page is preceded by a header identifying the page number and, for
+banked pages, the bank number. For SFP modules, the header shows the
+I2C address instead, as different parts of the EEPROM memory map are
+accessible via different I2C addresses. The set of pages dumped matches
+what the pretty-printer reads for each module type. This option cannot be
+combined with
+.I offset, length, page, bank
+or
+.I i2c
+parameters.
.TP
.B \-\-show\-priv\-flags
Queries the specified network device for its private flags. The
diff --git a/shell-completion/bash/ethtool b/shell-completion/bash/ethtool
index 57c39c4..7a319a9 100644
--- a/shell-completion/bash/ethtool
+++ b/shell-completion/bash/ethtool
@@ -671,11 +671,13 @@ _ethtool_module_info()
[hex]=1
[length]=1
[offset]=1
+ [pages]=1
[raw]=1
)
case "$prev" in
hex|\
+ pages|\
raw)
COMPREPLY=( $( compgen -W 'on off' -- "$cur" ) )
return ;;
--
2.51.0
^ permalink raw reply related
* Re: [PATCH] dt-bindings: net: lan966x: Accept standard ethernet prefixes
From: Rob Herring @ 2026-05-07 11:59 UTC (permalink / raw)
To: Herve Codina
Cc: Linus Walleij, Andrew Lunn, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Krzysztof Kozlowski, Conor Dooley,
Horatiu Vultur, netdev, devicetree
In-Reply-To: <20260507134043.35fdb1b9@bootlin.com>
On Thu, May 07, 2026 at 01:40:43PM +0200, Herve Codina wrote:
> Hi Linus,
>
> On Thu, 07 May 2026 11:26:01 +0200
> Linus Walleij <linusw@kernel.org> wrote:
>
> > The dsa.yaml and ethernet-switch.yaml bindings recommend
> > prefixing ethernet switches and ports with "ethernet-" so
> > make the LAN966x do the same.
> >
> > Reported-by: Herve Codina <herve.codina@bootlin.com>
> > Signed-off-by: Linus Walleij <linusw@kernel.org>
> > ---
> > .../devicetree/bindings/net/microchip,lan966x-switch.yaml | 10 +++++-----
> > 1 file changed, 5 insertions(+), 5 deletions(-)
> >
> > diff --git a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> > index 306ef9ecf2b9..0f0f35865ef4 100644
> > --- a/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> > +++ b/Documentation/devicetree/bindings/net/microchip,lan966x-switch.yaml
> > @@ -17,7 +17,7 @@ description: |
> >
> > properties:
> > $nodename:
> > - pattern: "^switch@[0-9a-f]+$"
> > + pattern: "^(ethernet-)?switch@[0-9a-f]+$"
> >
> > compatible:
> > const: microchip,lan966x-switch
> > @@ -70,7 +70,7 @@ properties:
> > additionalProperties: false
> >
> > patternProperties:
> > - "^port@[0-9a-f]+$":
> > + "^(ethernet-)?port@[0-9a-f]+$":
> > type: object
> >
> > $ref: /schemas/net/ethernet-controller.yaml#
> > @@ -138,7 +138,7 @@ additionalProperties: false
> > examples:
> > - |
> > #include <dt-bindings/interrupt-controller/arm-gic.h>
> > - switch: switch@e0000000 {
> > + switch: ethernet-switch@e0000000 {
> > compatible = "microchip,lan966x-switch";
> > reg = <0xe0000000 0x0100000>,
> > <0xe2000000 0x0800000>;
> > @@ -151,14 +151,14 @@ examples:
> > #address-cells = <1>;
> > #size-cells = <0>;
> >
> > - port0: port@0 {
> > + port0: ethernet-port@0 {
> > reg = <0>;
> > phy-handle = <&phy0>;
> > phys = <&serdes 0 0>;
> > phy-mode = "gmii";
> > };
> >
> > - port1: port@1 {
> > + port1: ethernet-port@1 {
> > reg = <1>;
> > sfp = <&sfp_eth1>;
> > managed = "in-band-status";
> >
> > ---
> > base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731
> > change-id: 20260507-lan966-binding-0df62a018509
> >
> > Best regards,
> > --
> > Linus Walleij <linusw@kernel.org>
> >
>
> With those changes, dtb_check will not be happy when following dtsi/dts are
> involved:
> - arch/arm/boot/dts/microchip/lan966x.dtsi
> - arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt.dtsi
> - arch/arm/boot/dts/microchip/lan966x-pcb8290.dts
> - arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt-6g-2gs.dts
> - arch/arm/boot/dts/microchip/lan966x-kontron-kswitch-d10-mmt-8g.dts
How so? the added prefix is optional.
Rob
^ permalink raw reply
* [PATCH net] net: nsh: fix incorrect header length macros
From: Ilya Maximets @ 2026-05-07 12:04 UTC (permalink / raw)
To: netdev
Cc: Aaron Conole, Eelco Chaudron, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, Jiri Benc, Yi Yang,
dev, linux-kernel, Ilya Maximets
NSH header length is a 6-bit field that encodes the total length of
the header in 4-byte words. So the maximum length is 0b111111 * 4,
which is 252 and not 256. The maximum context length is the same
number minus the length of the base header (8), so 244.
These macros are used to validate push_nsh() action in openvswitch.
Miscalculation here doesn't cause any real issues. In the worst case
the oversized context is truncated while building the header, so we'll
construct and send a broken packet, which is not a big problem, as any
receiver should validate the fields. No invalid memory accesses will
happen during the header push. But we should fix the macros to reject
the incorrect actions in the first place.
Using previously defined values and calculating the length instead
of defining numbers directly, so it's easier to understand where they
come from and harder to make a mistake.
Fixes: 1f0b7744c505 ("net: add NSH header structures and helpers")
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
---
These macros were fixed in the userspace variant of this header some
years ago (by just adjusting the numbers though):
https://patchwork.ozlabs.org/project/openvswitch/patch/1540503710-23597-1-git-send-email-pkusunyifeng@gmail.com/
And there was a patch a few weeks ago with the attempt to change the
validation for push_nsh() instead of fixing the macros:
https://lore.kernel.org/all/9d2b5c6127e149ebd35094d662bfd008c20347c2.1777120226.git.ldy3087146292@gmail.com/
I haven't heard back from the author, so sending this patch myself
to cross it out of my todo list. It's not a v2, as it's more of a
separate change, even though the outcome is similar.
include/net/nsh.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/net/nsh.h b/include/net/nsh.h
index 16a7510938969..15a26c5908151 100644
--- a/include/net/nsh.h
+++ b/include/net/nsh.h
@@ -247,10 +247,10 @@ struct nshhdr {
#define NSH_M_TYPE1_LEN 24
/* NSH header maximum Length. */
-#define NSH_HDR_MAX_LEN 256
+#define NSH_HDR_MAX_LEN ((NSH_LEN_MASK >> NSH_LEN_SHIFT) * 4)
/* NSH context headers maximum Length. */
-#define NSH_CTX_HDRS_MAX_LEN 248
+#define NSH_CTX_HDRS_MAX_LEN (NSH_HDR_MAX_LEN - NSH_BASE_HDR_LEN)
static inline struct nshhdr *nsh_hdr(struct sk_buff *skb)
{
--
2.53.0
^ permalink raw reply related
* [PATCH] MAINTAINERS: change maintainers for macb Ethernet driver
From: nicolas.ferre @ 2026-05-07 12:04 UTC (permalink / raw)
To: theo.lebrun, conor.dooley, Claudiu Beznea, netdev
Cc: Alexandre Belloni, andrew+netdev, davem, edumazet, kuba, pabeni,
linux-arm-kernel, linux-kernel, Nicolas Ferre
From: Nicolas Ferre <nicolas.ferre@microchip.com>
I would like to hand over the macb maintenance to Théo, as I'm unable to
keep up with the recent flow of patches for this driver. After speaking
with Claudiu, he indicated that he is in the same position as me.
To help with this work, Conor has agreed to act as a reviewer.
I was given responsibility for this driver years ago, and I'm glad to
see it continue with talented developers.
Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com>
---
MAINTAINERS | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 37b105a443dd..ad60104f30a1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4181,8 +4181,8 @@ F: include/uapi/linux/sonet.h
F: net/atm/
ATMEL MACB ETHERNET DRIVER
-M: Nicolas Ferre <nicolas.ferre@microchip.com>
-M: Claudiu Beznea <claudiu.beznea@tuxon.dev>
+M: Théo Lebrun <theo.lebrun@bootlin.com>
+R: Conor Dooley <conor.dooley@microchip.com>
S: Maintained
F: drivers/net/ethernet/cadence/
--
2.43.0
^ permalink raw reply related
* Re: [PATCH net 1/1] openvswitch: reject oversized NSH MD2 metadata in push_nsh
From: Ilya Maximets @ 2026-05-07 12:06 UTC (permalink / raw)
To: Ren Wei, netdev, dev
Cc: i.maximets, aconole, echaudro, davem, edumazet, kuba, pabeni,
horms, jbenc, e, yi.y.yang, yuantan098, yifanwucs, tomapufckgml,
bird, ldy3087146292
In-Reply-To: <9c1f6c24-3641-4bef-aad7-8f276def50a8@ovn.org>
On 4/25/26 10:19 PM, Ilya Maximets wrote:
> On 4/25/26 6:40 PM, Ren Wei wrote:
>> From: Douya Le <ldy3087146292@gmail.com>
>>
>> The NSH header length is encoded in 4-byte words in a 6-bit field.
>> The current push_nsh validation only checks the MD2 payload against
>> NSH_CTX_HDRS_MAX_LEN, which still allows metadata sizes that cannot be
>> represented once the base header is included.
>>
>> Reject MD2 metadata lengths whose total NSH header size cannot be
>> encoded exactly in the NSH length field, whether because the field
>> would wrap or because the length is not a multiple of 4 bytes.
>>
>> Fixes: b2d0f5d5dc53 ("openvswitch: enable NSH support")
>> Cc: stable@kernel.org
>> Reported-by: Yuan Tan <yuantan098@gmail.com>
>> Reported-by: Yifan Wu <yifanwucs@gmail.com>
>> Reported-by: Juefei Pu <tomapufckgml@gmail.com>
>> Reported-by: Xin Liu <bird@lzu.edu.cn>
>> Tested-by: Douya Le <ldy3087146292@gmail.com>
>> Signed-off-by: Douya Le <ldy3087146292@gmail.com>
>> Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
>> ---
>> net/openvswitch/flow_netlink.c | 8 +++++++-
>> 1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
>> index 13052408a132..8a1ae5309c2c 100644
>> --- a/net/openvswitch/flow_netlink.c
>> +++ b/net/openvswitch/flow_netlink.c
>> @@ -1432,7 +1432,13 @@ static int nsh_key_put_from_nlattr(const struct nlattr *attr,
>>
>> has_md2 = true;
>> mdlen = nla_len(a);
>> - if (mdlen > NSH_CTX_HDRS_MAX_LEN || mdlen <= 0) {
>> + /* The NSH length field stores the total header size
>> + * in 4-byte words in 6 bits. Reject MD2 metadata
>> + * lengths that cannot be encoded exactly or would
>> + * make the length field wrap.
>> + */
>> + if (mdlen <= 0 || !IS_ALIGNED(mdlen, 4) ||
>> + NSH_BASE_HDR_LEN + mdlen > (NSH_LEN_MASK << 2)) {
>> OVS_NLERR(
>> log,
>> "Invalid MD length %d for MD type %d",
>
> I don't think the check is a problem here, the problem is that the constants
> are not correct. We actually had them fixed in userspace, but looks like
> no-one ported the change to the kernel side:
> https://patchwork.ozlabs.org/project/openvswitch/patch/1540503710-23597-1-git-send-email-pkusunyifeng@gmail.com/
>
> Adjusting the macros should solve the potential overflow issue. However,
> even if the value overflows the 6-bit length, it will just be truncated to
> a smaller value and nothing bad should happen in this case, as far as header
> push is concerned. The context was wrong already, so pushing a truncated
> context doesn't make it more wrong. But we should still fix the constants,
> so the checks make sense, of course.
I posted a fix for the macros here:
https://lore.kernel.org/netdev/20260507120434.2962505-1-i.maximets@ovn.org/T/#u
>
> The same for alignment, if the user provides an invalid header that is not
> multiple of 4, the code will just truncate it to the previous multiple of 4,
> which should not be a problem, as it wasn't correct in the first place. We
> could add this check just to warn the user that they are doing something wrong,
> but not having it should not cause any real issues.
>
> Note, the userpace change linked above did fix the real issue in userspace,
> but for the kernel side there seem to be no real memory related issues caused
> by the wrong constants.
>
> Best regards, Ilya Maximets.
^ permalink raw reply
* Re: [PATCH ethtool-next 0/5] ethtool: Add 'pages on|off' option for module EEROM hex dump
From: Michal Kubecek @ 2026-05-07 12:07 UTC (permalink / raw)
To: Danielle Ratson; +Cc: netdev, idosch, petrm
In-Reply-To: <20260507114721.3409128-1-danieller@nvidia.com>
[-- Attachment #1: Type: text/plain, Size: 2771 bytes --]
On Thu, May 07, 2026 at 02:47:16PM GMT, Danielle Ratson wrote:
> The existing 'ethtool -m' command can dump module EEPROM data either as
> a parsed pretty-print or as a raw/hex dump. The pretty-printer reads
> multiple pages per module type, but decodes only specific fields from them.
>
> In practice, both outputs are often needed together for offline debugging:
> the pretty-print to identify the module type and decoded fields, and the
> hex dump for fields the pretty-printer does not decode. However, there is
> no single command that provides the raw hex dump of all relevant pages,
> organized by page boundary. This is especially problematic for CMIS
> transceivers where the existing hex dump does not provide Upper Pages
> beyond Page 02h, let alone banked pages.
>
> This series adds 'pages on|off' sub-option to 'hex on|off' for
> 'ethtool -m':
> $ ethtool -m hex on pages on
>
> That produces a hex dump organized by page, matching exactly the pages read
> by the pretty-printer for each module type.
Do we need the "pages on|off" switch? Is there a reason not to show the
full dump always (whenever possible) but only when requested explicitly?
Michal
> Each page is preceded by a header identifying the page number and, for
> banked modules, the bank number. For SFP, where the two memory regions
> are separate I2C addresses rather than pages, the header shows the I2C
> address instead.
>
> Output example (values zeroed to omit vendor-specific identifiers):
>
> $ ethtool -m swp61 hex on pages on
> Page: 0x0
>
> Offset Values
> ------ ------
> 0x0000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>
> Page: 0x0
>
> Offset Values
> ------ ------
> 0x0080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> 0x00f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ 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