* [PATCH net-next v2 1/5] psp: report basic stats from the core
2025-10-28 0:00 [PATCH net-next v2 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
@ 2025-10-28 0:00 ` Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats Daniel Zahka
` (3 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Daniel Zahka @ 2025-10-28 0:00 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
From: Jakub Kicinski <kuba@kernel.org>
Track and report stats common to all psp devices from the core. A
'stale-event' is when the core marks the rx state of an active
psp_assoc as incapable of authenticating psp encapsulated data.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
Notes:
v2:
- don't return skb->len from psp_nl_get_stats_dumpit() on success and
EMSGSIZE
Documentation/netlink/specs/psp.yaml | 40 +++++++++++++++
include/net/psp/types.h | 9 ++++
include/uapi/linux/psp.h | 10 ++++
net/psp/psp-nl-gen.c | 19 +++++++
net/psp/psp-nl-gen.h | 2 +
net/psp/psp_nl.c | 74 ++++++++++++++++++++++++++++
net/psp/psp_sock.c | 4 +-
7 files changed, 157 insertions(+), 1 deletion(-)
diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
index 944429e5c9a8..914148221384 100644
--- a/Documentation/netlink/specs/psp.yaml
+++ b/Documentation/netlink/specs/psp.yaml
@@ -76,6 +76,28 @@ attribute-sets:
name: spi
doc: Security Parameters Index (SPI) of the association.
type: u32
+ -
+ name: stats
+ attributes:
+ -
+ name: dev-id
+ doc: PSP device ID.
+ type: u32
+ checks:
+ min: 1
+ -
+ name: key-rotations
+ type: uint
+ doc: |
+ Number of key rotations during the lifetime of the device.
+ Kernel statistic.
+ -
+ name: stale-events
+ type: uint
+ doc: |
+ Number of times a socket's Rx got shut down due to using
+ a key which went stale (fully rotated out).
+ Kernel statistic.
operations:
list:
@@ -177,6 +199,24 @@ operations:
pre: psp-assoc-device-get-locked
post: psp-device-unlock
+ -
+ name: get-stats
+ doc: Get device statistics.
+ attribute-set: stats
+ do:
+ request:
+ attributes:
+ - dev-id
+ reply: &stats-all
+ attributes:
+ - dev-id
+ - key-rotations
+ - stale-events
+ pre: psp-device-get-locked
+ post: psp-device-unlock
+ dump:
+ reply: *stats-all
+
mcast-groups:
list:
-
diff --git a/include/net/psp/types.h b/include/net/psp/types.h
index 31cee64b7c86..5b0ccaac3882 100644
--- a/include/net/psp/types.h
+++ b/include/net/psp/types.h
@@ -59,6 +59,10 @@ struct psp_dev_config {
* device key
* @stale_assocs: associations which use a rotated out key
*
+ * @stats: statistics maintained by the core
+ * @stats.rotations: See stats attr key-rotations
+ * @stats.stales: See stats attr stale-events
+ *
* @rcu: RCU head for freeing the structure
*/
struct psp_dev {
@@ -81,6 +85,11 @@ struct psp_dev {
struct list_head prev_assocs;
struct list_head stale_assocs;
+ struct {
+ unsigned long rotations;
+ unsigned long stales;
+ } stats;
+
struct rcu_head rcu;
};
diff --git a/include/uapi/linux/psp.h b/include/uapi/linux/psp.h
index 607c42c39ba5..31592760ad79 100644
--- a/include/uapi/linux/psp.h
+++ b/include/uapi/linux/psp.h
@@ -45,6 +45,15 @@ enum {
PSP_A_KEYS_MAX = (__PSP_A_KEYS_MAX - 1)
};
+enum {
+ PSP_A_STATS_DEV_ID = 1,
+ PSP_A_STATS_KEY_ROTATIONS,
+ PSP_A_STATS_STALE_EVENTS,
+
+ __PSP_A_STATS_MAX,
+ PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1)
+};
+
enum {
PSP_CMD_DEV_GET = 1,
PSP_CMD_DEV_ADD_NTF,
@@ -55,6 +64,7 @@ enum {
PSP_CMD_KEY_ROTATE_NTF,
PSP_CMD_RX_ASSOC,
PSP_CMD_TX_ASSOC,
+ PSP_CMD_GET_STATS,
__PSP_CMD_MAX,
PSP_CMD_MAX = (__PSP_CMD_MAX - 1)
diff --git a/net/psp/psp-nl-gen.c b/net/psp/psp-nl-gen.c
index 9fdd6f831803..73f8b06d66f0 100644
--- a/net/psp/psp-nl-gen.c
+++ b/net/psp/psp-nl-gen.c
@@ -47,6 +47,11 @@ static const struct nla_policy psp_tx_assoc_nl_policy[PSP_A_ASSOC_SOCK_FD + 1] =
[PSP_A_ASSOC_SOCK_FD] = { .type = NLA_U32, },
};
+/* PSP_CMD_GET_STATS - do */
+static const struct nla_policy psp_get_stats_nl_policy[PSP_A_STATS_DEV_ID + 1] = {
+ [PSP_A_STATS_DEV_ID] = NLA_POLICY_MIN(NLA_U32, 1),
+};
+
/* Ops table for psp */
static const struct genl_split_ops psp_nl_ops[] = {
{
@@ -99,6 +104,20 @@ static const struct genl_split_ops psp_nl_ops[] = {
.maxattr = PSP_A_ASSOC_SOCK_FD,
.flags = GENL_CMD_CAP_DO,
},
+ {
+ .cmd = PSP_CMD_GET_STATS,
+ .pre_doit = psp_device_get_locked,
+ .doit = psp_nl_get_stats_doit,
+ .post_doit = psp_device_unlock,
+ .policy = psp_get_stats_nl_policy,
+ .maxattr = PSP_A_STATS_DEV_ID,
+ .flags = GENL_CMD_CAP_DO,
+ },
+ {
+ .cmd = PSP_CMD_GET_STATS,
+ .dumpit = psp_nl_get_stats_dumpit,
+ .flags = GENL_CMD_CAP_DUMP,
+ },
};
static const struct genl_multicast_group psp_nl_mcgrps[] = {
diff --git a/net/psp/psp-nl-gen.h b/net/psp/psp-nl-gen.h
index 25268ed11fb5..5bc3b5d5a53e 100644
--- a/net/psp/psp-nl-gen.h
+++ b/net/psp/psp-nl-gen.h
@@ -28,6 +28,8 @@ int psp_nl_dev_set_doit(struct sk_buff *skb, struct genl_info *info);
int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info);
int psp_nl_rx_assoc_doit(struct sk_buff *skb, struct genl_info *info);
int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info);
+int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info);
+int psp_nl_get_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb);
enum {
PSP_NLGRP_MGMT,
diff --git a/net/psp/psp_nl.c b/net/psp/psp_nl.c
index 8aaca62744c3..f990cccbe99c 100644
--- a/net/psp/psp_nl.c
+++ b/net/psp/psp_nl.c
@@ -262,6 +262,7 @@ int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info)
psd->generation & ~PSP_GEN_VALID_MASK);
psp_assocs_key_rotated(psd);
+ psd->stats.rotations++;
nlmsg_end(ntf, (struct nlmsghdr *)ntf->data);
genlmsg_multicast_netns(&psp_nl_family, dev_net(psd->main_netdev), ntf,
@@ -503,3 +504,76 @@ int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info)
nlmsg_free(rsp);
return err;
}
+
+static int
+psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
+ const struct genl_info *info)
+{
+ void *hdr;
+
+ hdr = genlmsg_iput(rsp, info);
+ if (!hdr)
+ return -EMSGSIZE;
+
+ if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) ||
+ nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS,
+ psd->stats.rotations) ||
+ nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales))
+ goto err_cancel_msg;
+
+ genlmsg_end(rsp, hdr);
+ return 0;
+
+err_cancel_msg:
+ genlmsg_cancel(rsp, hdr);
+ return -EMSGSIZE;
+}
+
+int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info)
+{
+ struct psp_dev *psd = info->user_ptr[0];
+ struct sk_buff *rsp;
+ int err;
+
+ rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!rsp)
+ return -ENOMEM;
+
+ err = psp_nl_stats_fill(psd, rsp, info);
+ if (err)
+ goto err_free_msg;
+
+ return genlmsg_reply(rsp, info);
+
+err_free_msg:
+ nlmsg_free(rsp);
+ return err;
+}
+
+static int
+psp_nl_stats_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb,
+ struct psp_dev *psd)
+{
+ if (psp_dev_check_access(psd, sock_net(rsp->sk)))
+ return 0;
+
+ return psp_nl_stats_fill(psd, rsp, genl_info_dump(cb));
+}
+
+int psp_nl_get_stats_dumpit(struct sk_buff *rsp, struct netlink_callback *cb)
+{
+ struct psp_dev *psd;
+ int err = 0;
+
+ mutex_lock(&psp_devs_lock);
+ xa_for_each_start(&psp_devs, cb->args[0], psd, cb->args[0]) {
+ mutex_lock(&psd->lock);
+ err = psp_nl_stats_get_dumpit_one(rsp, cb, psd);
+ mutex_unlock(&psd->lock);
+ if (err)
+ break;
+ }
+ mutex_unlock(&psp_devs_lock);
+
+ return err;
+}
diff --git a/net/psp/psp_sock.c b/net/psp/psp_sock.c
index a931d825d1cc..f785672b7df6 100644
--- a/net/psp/psp_sock.c
+++ b/net/psp/psp_sock.c
@@ -253,8 +253,10 @@ void psp_assocs_key_rotated(struct psp_dev *psd)
/* Mark the stale associations as invalid, they will no longer
* be able to Rx any traffic.
*/
- list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list)
+ list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) {
pas->generation |= ~PSP_GEN_VALID_MASK;
+ psd->stats.stales++;
+ }
list_splice_init(&psd->prev_assocs, &psd->stale_assocs);
list_splice_init(&psd->active_assocs, &psd->prev_assocs);
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats
2025-10-28 0:00 [PATCH net-next v2 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 1/5] psp: report basic stats from the core Daniel Zahka
@ 2025-10-28 0:00 ` Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api Daniel Zahka
` (2 subsequent siblings)
4 siblings, 0 replies; 11+ messages in thread
From: Daniel Zahka @ 2025-10-28 0:00 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
Add assertions to existing test cases to cover key rotations and
'stale-events'.
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
tools/testing/selftests/drivers/net/psp.py | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/psp.py b/tools/testing/selftests/drivers/net/psp.py
index 4ae7a785ff10..06559ef49b9a 100755
--- a/tools/testing/selftests/drivers/net/psp.py
+++ b/tools/testing/selftests/drivers/net/psp.py
@@ -109,6 +109,10 @@ def _check_data_outq(s, exp_len, force_wait=False):
time.sleep(0.01)
ksft_eq(outq, exp_len)
+
+def _get_stat(cfg, key):
+ return cfg.pspnl.get_stats({'dev-id': cfg.psp_dev_id})[key]
+
#
# Test case boiler plate
#
@@ -171,11 +175,16 @@ def dev_rotate(cfg):
""" Test key rotation """
_init_psp_dev(cfg)
+ prev_rotations = _get_stat(cfg, 'key-rotations')
+
rot = cfg.pspnl.key_rotate({"id": cfg.psp_dev_id})
ksft_eq(rot['id'], cfg.psp_dev_id)
rot = cfg.pspnl.key_rotate({"id": cfg.psp_dev_id})
ksft_eq(rot['id'], cfg.psp_dev_id)
+ cur_rotations = _get_stat(cfg, 'key-rotations')
+ ksft_eq(cur_rotations, prev_rotations + 2)
+
def dev_rotate_spi(cfg):
""" Test key rotation and SPI check """
@@ -475,6 +484,7 @@ def data_stale_key(cfg):
""" Test send on a double-rotated key """
_init_psp_dev(cfg)
+ prev_stale = _get_stat(cfg, 'stale-events')
s = _make_psp_conn(cfg)
try:
rx_assoc = cfg.pspnl.rx_assoc({"version": 0,
@@ -495,6 +505,9 @@ def data_stale_key(cfg):
cfg.pspnl.key_rotate({"id": cfg.psp_dev_id})
cfg.pspnl.key_rotate({"id": cfg.psp_dev_id})
+ cur_stale = _get_stat(cfg, 'stale-events')
+ ksft_gt(cur_stale, prev_stale)
+
s.send(b'0123456789' * 200)
_check_data_outq(s, 2000, force_wait=True)
finally:
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api
2025-10-28 0:00 [PATCH net-next v2 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 1/5] psp: report basic stats from the core Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats Daniel Zahka
@ 2025-10-28 0:00 ` Daniel Zahka
2025-10-28 9:02 ` Paolo Abeni
2025-10-28 0:00 ` [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
2025-10-28 0:00 ` [PATCH net-next v2 5/5] netdevsim: implement psp device stats Daniel Zahka
4 siblings, 1 reply; 11+ messages in thread
From: Daniel Zahka @ 2025-10-28 0:00 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
From: Jakub Kicinski <kuba@kernel.org>
Provide a driver api for reporting device statistics required by the
"Implementation Requirements" section of the PSP Architecture
Specification. Use a warning to ensure drivers report stats required
by the spec.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
Documentation/netlink/specs/psp.yaml | 55 ++++++++++++++++++++++++++++
include/net/psp/types.h | 26 +++++++++++++
include/uapi/linux/psp.h | 8 ++++
net/psp/psp_main.c | 3 +-
net/psp/psp_nl.c | 22 ++++++++++-
5 files changed, 112 insertions(+), 2 deletions(-)
diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
index 914148221384..f3a57782d2cf 100644
--- a/Documentation/netlink/specs/psp.yaml
+++ b/Documentation/netlink/specs/psp.yaml
@@ -98,6 +98,61 @@ attribute-sets:
Number of times a socket's Rx got shut down due to using
a key which went stale (fully rotated out).
Kernel statistic.
+ -
+ name: rx-packets
+ type: uint
+ doc: |
+ Number of successfully processed and authenticated PSP packets.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-bytes
+ type: uint
+ doc: |
+ Number of successfully authenticated PSP bytes received, counting from
+ the first byte after the IV through the last byte of payload.
+ The fixed initial portion of the PSP header (16 bytes)
+ and the PSP trailer/ICV (16 bytes) are not included in this count.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-auth-fail
+ type: uint
+ doc: |
+ Number of received PSP packets with unsuccessful authentication.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-error
+ type: uint
+ doc: |
+ Number of received PSP packets with length/framing errors.
+ Device statistic (from the PSP spec).
+ -
+ name: rx-bad
+ type: uint
+ doc: |
+ Number of received PSP packets with miscellaneous errors
+ (invalid master key indicated by SPI, unsupported version, etc.)
+ Device statistic (from the PSP spec).
+ -
+ name: tx-packets
+ type: uint
+ doc: |
+ Number of successfully processed PSP packets for transmission.
+ Device statistic (from the PSP spec).
+ -
+ name: tx-bytes
+ type: uint
+ doc: |
+ Number of successfully processed PSP bytes for transmit, counting from
+ the first byte after the IV through the last byte of payload.
+ The fixed initial portion of the PSP header (16 bytes)
+ and the PSP trailer/ICV (16 bytes) are not included in this count.
+ Device statistic (from the PSP spec).
+ -
+ name: tx-error
+ type: uint
+ doc: |
+ Number of PSP packets for transmission with errors.
+ Device statistic (from the PSP spec).
operations:
list:
diff --git a/include/net/psp/types.h b/include/net/psp/types.h
index 5b0ccaac3882..1aa3857a85c1 100644
--- a/include/net/psp/types.h
+++ b/include/net/psp/types.h
@@ -150,6 +150,25 @@ struct psp_assoc {
u8 drv_data[] __aligned(8);
};
+struct psp_dev_stats {
+ union {
+ struct {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 rx_auth_fail;
+ u64 rx_error;
+ u64 rx_bad;
+ u64 tx_packets;
+ u64 tx_bytes;
+ u64 tx_error;
+ };
+ DECLARE_FLEX_ARRAY(u64, required);
+ };
+ char required_end[0];
+
+ /* optional stats would go here */
+};
+
/**
* struct psp_dev_ops - netdev driver facing PSP callbacks
*/
@@ -188,6 +207,13 @@ struct psp_dev_ops {
* Remove an association from the device.
*/
void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas);
+
+ /**
+ * @get_stats: get statistics from the device
+ * Stats required by the spec must be maintained and filled in.
+ * Stats must be filled in member-by-member, never memset the struct.
+ */
+ void (*get_stats)(struct psp_dev *psd, struct psp_dev_stats *stats);
};
#endif /* __NET_PSP_H */
diff --git a/include/uapi/linux/psp.h b/include/uapi/linux/psp.h
index 31592760ad79..d8449c043ba1 100644
--- a/include/uapi/linux/psp.h
+++ b/include/uapi/linux/psp.h
@@ -49,6 +49,14 @@ enum {
PSP_A_STATS_DEV_ID = 1,
PSP_A_STATS_KEY_ROTATIONS,
PSP_A_STATS_STALE_EVENTS,
+ PSP_A_STATS_RX_PACKETS,
+ PSP_A_STATS_RX_BYTES,
+ PSP_A_STATS_RX_AUTH_FAIL,
+ PSP_A_STATS_RX_ERROR,
+ PSP_A_STATS_RX_BAD,
+ PSP_A_STATS_TX_PACKETS,
+ PSP_A_STATS_TX_BYTES,
+ PSP_A_STATS_TX_ERROR,
__PSP_A_STATS_MAX,
PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1)
diff --git a/net/psp/psp_main.c b/net/psp/psp_main.c
index 481aaf0fc9fc..a8534124f626 100644
--- a/net/psp/psp_main.c
+++ b/net/psp/psp_main.c
@@ -60,7 +60,8 @@ psp_dev_create(struct net_device *netdev,
!psd_ops->key_rotate ||
!psd_ops->rx_spi_alloc ||
!psd_ops->tx_key_add ||
- !psd_ops->tx_key_del))
+ !psd_ops->tx_key_del ||
+ !psd_ops->get_stats))
return ERR_PTR(-EINVAL);
psd = kzalloc(sizeof(*psd), GFP_KERNEL);
diff --git a/net/psp/psp_nl.c b/net/psp/psp_nl.c
index f990cccbe99c..1bace9731d3c 100644
--- a/net/psp/psp_nl.c
+++ b/net/psp/psp_nl.c
@@ -1,5 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
+#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/xarray.h>
#include <net/genetlink.h>
@@ -509,7 +510,18 @@ static int
psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
const struct genl_info *info)
{
+ const unsigned int required_cnt = offsetof(struct psp_dev_stats,
+ required_end) / sizeof(u64);
+ struct psp_dev_stats stats;
void *hdr;
+ int i;
+
+ memset(&stats, 0xff, sizeof(stats));
+ psd->ops->get_stats(psd, &stats);
+
+ for (i = 0; i < required_cnt; i++)
+ if (WARN_ON_ONCE(stats.required[i] == ETHTOOL_STAT_NOT_SET))
+ return -EOPNOTSUPP;
hdr = genlmsg_iput(rsp, info);
if (!hdr)
@@ -518,7 +530,15 @@ psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp,
if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) ||
nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS,
psd->stats.rotations) ||
- nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales))
+ nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_PACKETS, stats.rx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BYTES, stats.rx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_AUTH_FAIL, stats.rx_auth_fail) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_ERROR, stats.rx_error) ||
+ nla_put_uint(rsp, PSP_A_STATS_RX_BAD, stats.rx_bad) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_PACKETS, stats.tx_packets) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_BYTES, stats.tx_bytes) ||
+ nla_put_uint(rsp, PSP_A_STATS_TX_ERROR, stats.tx_error))
goto err_cancel_msg;
genlmsg_end(rsp, hdr);
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api
2025-10-28 0:00 ` [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api Daniel Zahka
@ 2025-10-28 9:02 ` Paolo Abeni
2025-10-28 17:30 ` Jakub Kicinski
0 siblings, 1 reply; 11+ messages in thread
From: Paolo Abeni @ 2025-10-28 9:02 UTC (permalink / raw)
To: Daniel Zahka, David S . Miller, Eric Dumazet, Jakub Kicinski,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
On 10/28/25 1:00 AM, Daniel Zahka wrote:
> From: Jakub Kicinski <kuba@kernel.org>
>
> Provide a driver api for reporting device statistics required by the
> "Implementation Requirements" section of the PSP Architecture
> Specification. Use a warning to ensure drivers report stats required
> by the spec.
>
> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
> Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
> ---
> Documentation/netlink/specs/psp.yaml | 55 ++++++++++++++++++++++++++++
> include/net/psp/types.h | 26 +++++++++++++
> include/uapi/linux/psp.h | 8 ++++
> net/psp/psp_main.c | 3 +-
> net/psp/psp_nl.c | 22 ++++++++++-
> 5 files changed, 112 insertions(+), 2 deletions(-)
>
> diff --git a/Documentation/netlink/specs/psp.yaml b/Documentation/netlink/specs/psp.yaml
> index 914148221384..f3a57782d2cf 100644
> --- a/Documentation/netlink/specs/psp.yaml
> +++ b/Documentation/netlink/specs/psp.yaml
> @@ -98,6 +98,61 @@ attribute-sets:
> Number of times a socket's Rx got shut down due to using
> a key which went stale (fully rotated out).
> Kernel statistic.
> + -
> + name: rx-packets
> + type: uint
> + doc: |
> + Number of successfully processed and authenticated PSP packets.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-bytes
> + type: uint
> + doc: |
> + Number of successfully authenticated PSP bytes received, counting from
> + the first byte after the IV through the last byte of payload.
> + The fixed initial portion of the PSP header (16 bytes)
> + and the PSP trailer/ICV (16 bytes) are not included in this count.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-auth-fail
> + type: uint
> + doc: |
> + Number of received PSP packets with unsuccessful authentication.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-error
> + type: uint
> + doc: |
> + Number of received PSP packets with length/framing errors.
> + Device statistic (from the PSP spec).
> + -
> + name: rx-bad
> + type: uint
> + doc: |
> + Number of received PSP packets with miscellaneous errors
> + (invalid master key indicated by SPI, unsupported version, etc.)
> + Device statistic (from the PSP spec).
> + -
> + name: tx-packets
> + type: uint
> + doc: |
> + Number of successfully processed PSP packets for transmission.
> + Device statistic (from the PSP spec).
> + -
> + name: tx-bytes
> + type: uint
> + doc: |
> + Number of successfully processed PSP bytes for transmit, counting from
> + the first byte after the IV through the last byte of payload.
> + The fixed initial portion of the PSP header (16 bytes)
> + and the PSP trailer/ICV (16 bytes) are not included in this count.
> + Device statistic (from the PSP spec).
> + -
> + name: tx-error
> + type: uint
> + doc: |
> + Number of PSP packets for transmission with errors.
> + Device statistic (from the PSP spec).
>
> operations:
> list:
> diff --git a/include/net/psp/types.h b/include/net/psp/types.h
> index 5b0ccaac3882..1aa3857a85c1 100644
> --- a/include/net/psp/types.h
> +++ b/include/net/psp/types.h
> @@ -150,6 +150,25 @@ struct psp_assoc {
> u8 drv_data[] __aligned(8);
> };
>
> +struct psp_dev_stats {
> + union {
> + struct {
> + u64 rx_packets;
> + u64 rx_bytes;
> + u64 rx_auth_fail;
> + u64 rx_error;
> + u64 rx_bad;
> + u64 tx_packets;
> + u64 tx_bytes;
> + u64 tx_error;
> + };
> + DECLARE_FLEX_ARRAY(u64, required);
> + };
> + char required_end[0];
This makes static checker unhappy:
/home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use
flexible-array member instead
(https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
I think/guess the warning could be avoided using something alike the
following (completely untested!!!):
struct psp_dev_stats {
struct_group(required,
union {
struct {
u64 rx_packets;
u64 rx_bytes;
u64 rx_auth_fail;
u64 rx_error;
u64 rx_bad;
u64 tx_packets;
u64 tx_bytes;
u64 tx_error;
};
DECLARE_FLEX_ARRAY(u64, required);
};
);
};
// ...
const unsigned int required_cnt = sizeof(stats.required) / sizeof(u64);
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api
2025-10-28 9:02 ` Paolo Abeni
@ 2025-10-28 17:30 ` Jakub Kicinski
2025-10-28 17:33 ` Jakub Kicinski
0 siblings, 1 reply; 11+ messages in thread
From: Jakub Kicinski @ 2025-10-28 17:30 UTC (permalink / raw)
To: Paolo Abeni
Cc: Daniel Zahka, David S . Miller, Eric Dumazet, Simon Horman,
Donald Hunter, Andrew Lunn, Shuah Khan, Boris Pismenny,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Mark Bloch, netdev,
linux-kernel, linux-kselftest
On Tue, 28 Oct 2025 10:02:16 +0100 Paolo Abeni wrote:
> This makes static checker unhappy:
>
> /home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use
> flexible-array member instead
> (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
>
> I think/guess the warning could be avoided using something alike the
> following (completely untested!!!):
It's not a VLA, it's an end marker for calculating offsets.
The patch is fine, we should have added in the commit msg that the
false positive from cocci is expected.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api
2025-10-28 17:30 ` Jakub Kicinski
@ 2025-10-28 17:33 ` Jakub Kicinski
0 siblings, 0 replies; 11+ messages in thread
From: Jakub Kicinski @ 2025-10-28 17:33 UTC (permalink / raw)
To: Paolo Abeni
Cc: Daniel Zahka, David S . Miller, Eric Dumazet, Simon Horman,
Donald Hunter, Andrew Lunn, Shuah Khan, Boris Pismenny,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Mark Bloch, netdev,
linux-kernel, linux-kselftest
On Tue, 28 Oct 2025 10:30:01 -0700 Jakub Kicinski wrote:
> On Tue, 28 Oct 2025 10:02:16 +0100 Paolo Abeni wrote:
> > This makes static checker unhappy:
> >
> > /home/cocci/testing/include/net/psp/types.h:167:6-18: WARNING use
> > flexible-array member instead
> > (https://www.kernel.org/doc/html/latest/process/deprecated.html#zero-length-and-one-element-arrays)
> >
> > I think/guess the warning could be avoided using something alike the
> > following (completely untested!!!):
>
> It's not a VLA, it's an end marker for calculating offsets.
> The patch is fine, we should have added in the commit msg that the
> false positive from cocci is expected.
I guess we could avoid this problem by naming the union.
Let's do that instead..
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows
2025-10-28 0:00 [PATCH net-next v2 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
` (2 preceding siblings ...)
2025-10-28 0:00 ` [PATCH net-next v2 3/5] psp: add stats from psp spec to driver facing api Daniel Zahka
@ 2025-10-28 0:00 ` Daniel Zahka
2025-10-30 16:11 ` Cosmin Ratiu
2025-10-28 0:00 ` [PATCH net-next v2 5/5] netdevsim: implement psp device stats Daniel Zahka
4 siblings, 1 reply; 11+ messages in thread
From: Daniel Zahka @ 2025-10-28 0:00 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
From: Jakub Kicinski <kuba@kernel.org>
Add all statistics described under the "Implementation Requirements"
section of the PSP Architecture Specification:
Rx successfully decrypted PSP packets:
psp_rx_pkts : Number of packets decrypted successfully
psp_rx_bytes : Number of bytes decrypted successfully
Rx PSP authentication failure statistics:
psp_rx_pkts_auth_fail : Number of PSP packets that failed authentication
psp_rx_bytes_auth_fail : Number of PSP bytes that failed authentication
Rx PSP bad frame error statistics:
psp_rx_pkts_frame_err;
psp_rx_bytes_frame_err;
Rx PSP drop statistics:
psp_rx_pkts_drop : Number of PSP packets dropped
psp_rx_bytes_drop : Number of PSP bytes dropped
Tx successfully encrypted PSP packets:
psp_tx_pkts : Number of packets encrypted successfully
psp_tx_bytes : Number of bytes encrypted successfully
Tx drops:
tx_drop : Number of misc psp related drops
The above can be seen using the ynl cli:
./pyynl/cli.py --spec netlink/specs/psp.yaml --dump get-stats
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Raed Salem <raeds@nvidia.com>
Signed-off-by: Rahul Rameshbabu <rrameshbabu@nvidia.com>
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
Notes:
v2:
- use %pe to print PTR_ERR()
.../mellanox/mlx5/core/en_accel/psp.c | 239 ++++++++++++++++--
.../mellanox/mlx5/core/en_accel/psp.h | 18 ++
.../mellanox/mlx5/core/en_accel/psp_rxtx.c | 1 +
.../net/ethernet/mellanox/mlx5/core/en_main.c | 5 +
4 files changed, 248 insertions(+), 15 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
index 8565cfe8d7dc..93a1ddfc7f8a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
@@ -28,12 +28,15 @@ struct mlx5e_psp_tx {
struct mlx5_flow_handle *rule;
struct mutex mutex; /* Protect PSP TX steering */
u32 refcnt;
+ struct mlx5_fc *tx_counter;
};
struct mlx5e_psp_rx_err {
struct mlx5_flow_table *ft;
struct mlx5_flow_handle *rule;
- struct mlx5_flow_handle *drop_rule;
+ struct mlx5_flow_handle *auth_fail_rule;
+ struct mlx5_flow_handle *err_rule;
+ struct mlx5_flow_handle *bad_rule;
struct mlx5_modify_hdr *copy_modify_hdr;
};
@@ -50,6 +53,10 @@ struct mlx5e_accel_fs_psp_prot {
struct mlx5e_accel_fs_psp {
struct mlx5e_accel_fs_psp_prot fs_prot[ACCEL_FS_PSP_NUM_TYPES];
+ struct mlx5_fc *rx_counter;
+ struct mlx5_fc *rx_auth_fail_counter;
+ struct mlx5_fc *rx_err_counter;
+ struct mlx5_fc *rx_bad_counter;
};
struct mlx5e_psp_fs {
@@ -72,9 +79,19 @@ static enum mlx5_traffic_types fs_psp2tt(enum accel_fs_psp_type i)
static void accel_psp_fs_rx_err_del_rules(struct mlx5e_psp_fs *fs,
struct mlx5e_psp_rx_err *rx_err)
{
- if (rx_err->drop_rule) {
- mlx5_del_flow_rules(rx_err->drop_rule);
- rx_err->drop_rule = NULL;
+ if (rx_err->bad_rule) {
+ mlx5_del_flow_rules(rx_err->bad_rule);
+ rx_err->bad_rule = NULL;
+ }
+
+ if (rx_err->err_rule) {
+ mlx5_del_flow_rules(rx_err->err_rule);
+ rx_err->err_rule = NULL;
+ }
+
+ if (rx_err->auth_fail_rule) {
+ mlx5_del_flow_rules(rx_err->auth_fail_rule);
+ rx_err->auth_fail_rule = NULL;
}
if (rx_err->rule) {
@@ -117,6 +134,7 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,
{
u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {};
struct mlx5_core_dev *mdev = fs->mdev;
+ struct mlx5_flow_destination dest[2];
struct mlx5_flow_act flow_act = {};
struct mlx5_modify_hdr *modify_hdr;
struct mlx5_flow_handle *fte;
@@ -147,10 +165,14 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,
accel_psp_setup_syndrome_match(spec, PSP_OK);
/* create fte */
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR |
- MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
+ MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
flow_act.modify_hdr = modify_hdr;
- fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act,
- &fs_prot->default_dest, 1);
+ dest[0].type = fs_prot->default_dest.type;
+ dest[0].ft = fs_prot->default_dest.ft;
+ dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ dest[1].counter = fs->rx_fs->rx_counter;
+ fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 2);
if (IS_ERR(fte)) {
err = PTR_ERR(fte);
mlx5_core_err(mdev, "fail to add psp rx err copy rule err=%d\n", err);
@@ -158,22 +180,69 @@ static int accel_psp_fs_rx_err_add_rule(struct mlx5e_psp_fs *fs,
}
rx_err->rule = fte;
- /* add default drop rule */
+ /* add auth fail drop rule */
memset(spec, 0, sizeof(*spec));
memset(&flow_act, 0, sizeof(flow_act));
+ accel_psp_setup_syndrome_match(spec, PSP_ICV_FAIL);
/* create fte */
- flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP;
- fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, NULL, 0);
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
+ dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ dest[0].counter = fs->rx_fs->rx_auth_fail_counter;
+ fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
if (IS_ERR(fte)) {
err = PTR_ERR(fte);
- mlx5_core_err(mdev, "fail to add psp rx err drop rule err=%d\n", err);
+ mlx5_core_err(mdev, "fail to add psp rx auth fail drop rule err=%d\n",
+ err);
goto out_drop_rule;
}
- rx_err->drop_rule = fte;
+ rx_err->auth_fail_rule = fte;
+
+ /* add framing drop rule */
+ memset(spec, 0, sizeof(*spec));
+ memset(&flow_act, 0, sizeof(flow_act));
+ accel_psp_setup_syndrome_match(spec, PSP_BAD_TRAILER);
+ /* create fte */
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
+ dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ dest[0].counter = fs->rx_fs->rx_err_counter;
+ fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
+ if (IS_ERR(fte)) {
+ err = PTR_ERR(fte);
+ mlx5_core_err(mdev, "fail to add psp rx framing err drop rule err=%d\n",
+ err);
+ goto out_drop_auth_fail_rule;
+ }
+ rx_err->err_rule = fte;
+
+ /* add misc. errors drop rule */
+ memset(spec, 0, sizeof(*spec));
+ memset(&flow_act, 0, sizeof(flow_act));
+ /* create fte */
+ flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
+ dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ dest[0].counter = fs->rx_fs->rx_bad_counter;
+ fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1);
+ if (IS_ERR(fte)) {
+ err = PTR_ERR(fte);
+ mlx5_core_err(mdev, "fail to add psp rx misc. err drop rule err=%d\n",
+ err);
+ goto out_drop_error_rule;
+ }
+ rx_err->bad_rule = fte;
+
rx_err->copy_modify_hdr = modify_hdr;
goto out_spec;
+out_drop_error_rule:
+ mlx5_del_flow_rules(rx_err->err_rule);
+ rx_err->err_rule = NULL;
+out_drop_auth_fail_rule:
+ mlx5_del_flow_rules(rx_err->auth_fail_rule);
+ rx_err->auth_fail_rule = NULL;
out_drop_rule:
mlx5_del_flow_rules(rx_err->rule);
rx_err->rule = NULL;
@@ -461,6 +530,10 @@ static void accel_psp_fs_cleanup_rx(struct mlx5e_psp_fs *fs)
return;
accel_psp = fs->rx_fs;
+ mlx5_fc_destroy(fs->mdev, accel_psp->rx_bad_counter);
+ mlx5_fc_destroy(fs->mdev, accel_psp->rx_err_counter);
+ mlx5_fc_destroy(fs->mdev, accel_psp->rx_auth_fail_counter);
+ mlx5_fc_destroy(fs->mdev, accel_psp->rx_counter);
for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
fs_prot = &accel_psp->fs_prot[i];
mutex_destroy(&fs_prot->prot_mutex);
@@ -474,7 +547,10 @@ static int accel_psp_fs_init_rx(struct mlx5e_psp_fs *fs)
{
struct mlx5e_accel_fs_psp_prot *fs_prot;
struct mlx5e_accel_fs_psp *accel_psp;
+ struct mlx5_core_dev *mdev = fs->mdev;
+ struct mlx5_fc *flow_counter;
enum accel_fs_psp_type i;
+ int err;
accel_psp = kzalloc(sizeof(*accel_psp), GFP_KERNEL);
if (!accel_psp)
@@ -485,9 +561,68 @@ static int accel_psp_fs_init_rx(struct mlx5e_psp_fs *fs)
mutex_init(&fs_prot->prot_mutex);
}
+ flow_counter = mlx5_fc_create(mdev, false);
+ if (IS_ERR(flow_counter)) {
+ mlx5_core_warn(mdev,
+ "fail to create psp rx flow counter err=%pe\n",
+ flow_counter);
+ err = PTR_ERR(flow_counter);
+ goto out_err;
+ }
+ accel_psp->rx_counter = flow_counter;
+
+ flow_counter = mlx5_fc_create(mdev, false);
+ if (IS_ERR(flow_counter)) {
+ mlx5_core_warn(mdev,
+ "fail to create psp rx auth fail flow counter err=%pe\n",
+ flow_counter);
+ err = PTR_ERR(flow_counter);
+ goto out_counter_err;
+ }
+ accel_psp->rx_auth_fail_counter = flow_counter;
+
+ flow_counter = mlx5_fc_create(mdev, false);
+ if (IS_ERR(flow_counter)) {
+ mlx5_core_warn(mdev,
+ "fail to create psp rx error flow counter err=%pe\n",
+ flow_counter);
+ err = PTR_ERR(flow_counter);
+ goto out_auth_fail_counter_err;
+ }
+ accel_psp->rx_err_counter = flow_counter;
+
+ flow_counter = mlx5_fc_create(mdev, false);
+ if (IS_ERR(flow_counter)) {
+ mlx5_core_warn(mdev,
+ "fail to create psp rx bad flow counter err=%pe\n",
+ flow_counter);
+ err = PTR_ERR(flow_counter);
+ goto out_err_counter_err;
+ }
+ accel_psp->rx_bad_counter = flow_counter;
+
fs->rx_fs = accel_psp;
return 0;
+
+out_err_counter_err:
+ mlx5_fc_destroy(mdev, accel_psp->rx_err_counter);
+ accel_psp->rx_err_counter = NULL;
+out_auth_fail_counter_err:
+ mlx5_fc_destroy(mdev, accel_psp->rx_auth_fail_counter);
+ accel_psp->rx_auth_fail_counter = NULL;
+out_counter_err:
+ mlx5_fc_destroy(mdev, accel_psp->rx_counter);
+ accel_psp->rx_counter = NULL;
+out_err:
+ for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) {
+ fs_prot = &accel_psp->fs_prot[i];
+ mutex_destroy(&fs_prot->prot_mutex);
+ }
+ kfree(accel_psp);
+ fs->rx_fs = NULL;
+
+ return err;
}
void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv)
@@ -532,6 +667,7 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
{
int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in);
struct mlx5_flow_table_attr ft_attr = {};
+ struct mlx5_flow_destination dest = {};
struct mlx5_core_dev *mdev = fs->mdev;
struct mlx5_flow_act flow_act = {};
u32 *in, *mc, *outer_headers_c;
@@ -580,8 +716,11 @@ static int accel_psp_fs_tx_create_ft_table(struct mlx5e_psp_fs *fs)
flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_PSP;
flow_act.flags |= FLOW_ACT_NO_APPEND;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW |
- MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT;
- rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0);
+ MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
+ MLX5_FLOW_CONTEXT_ACTION_COUNT;
+ dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
+ dest.counter = tx_fs->tx_counter;
+ rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1);
if (IS_ERR(rule)) {
err = PTR_ERR(rule);
mlx5_core_err(mdev, "PSP: fail to add psp tx flow rule, err = %d\n", err);
@@ -650,6 +789,7 @@ static void accel_psp_fs_cleanup_tx(struct mlx5e_psp_fs *fs)
if (!tx_fs)
return;
+ mlx5_fc_destroy(fs->mdev, tx_fs->tx_counter);
mutex_destroy(&tx_fs->mutex);
WARN_ON(tx_fs->refcnt);
kfree(tx_fs);
@@ -658,10 +798,13 @@ static void accel_psp_fs_cleanup_tx(struct mlx5e_psp_fs *fs)
static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs)
{
+ struct mlx5_core_dev *mdev = fs->mdev;
struct mlx5_flow_namespace *ns;
+ struct mlx5_fc *flow_counter;
struct mlx5e_psp_tx *tx_fs;
+ int err;
- ns = mlx5_get_flow_namespace(fs->mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);
+ ns = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC);
if (!ns)
return -EOPNOTSUPP;
@@ -670,9 +813,57 @@ static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs)
return -ENOMEM;
mutex_init(&tx_fs->mutex);
+ flow_counter = mlx5_fc_create(mdev, false);
+ if (IS_ERR(flow_counter)) {
+ mlx5_core_warn(mdev,
+ "fail to create psp tx flow counter err=%pe\n",
+ flow_counter);
+ err = PTR_ERR(flow_counter);
+ goto out_err;
+ }
+ tx_fs->tx_counter = flow_counter;
tx_fs->ns = ns;
fs->tx_fs = tx_fs;
return 0;
+
+out_err:
+ mutex_destroy(&tx_fs->mutex);
+ kfree(tx_fs);
+ return err;
+}
+
+static void
+mlx5e_accel_psp_fs_get_stats_fill(struct mlx5e_priv *priv, void *psp_stats)
+{
+ struct mlx5e_psp_stats *stats = (struct mlx5e_psp_stats *)psp_stats;
+ struct mlx5e_psp_tx *tx_fs = priv->psp->fs->tx_fs;
+ struct mlx5_core_dev *mdev = priv->mdev;
+ struct mlx5e_accel_fs_psp *accel_psp;
+
+ accel_psp = (struct mlx5e_accel_fs_psp *)priv->psp->fs->rx_fs;
+
+ if (tx_fs->tx_counter)
+ mlx5_fc_query(mdev, tx_fs->tx_counter, &stats->psp_tx_pkts,
+ &stats->psp_tx_bytes);
+
+ if (accel_psp->rx_counter)
+ mlx5_fc_query(mdev, accel_psp->rx_counter, &stats->psp_rx_pkts,
+ &stats->psp_rx_bytes);
+
+ if (accel_psp->rx_auth_fail_counter)
+ mlx5_fc_query(mdev, accel_psp->rx_auth_fail_counter,
+ &stats->psp_rx_pkts_auth_fail,
+ &stats->psp_rx_bytes_auth_fail);
+
+ if (accel_psp->rx_err_counter)
+ mlx5_fc_query(mdev, accel_psp->rx_err_counter,
+ &stats->psp_rx_pkts_frame_err,
+ &stats->psp_rx_bytes_frame_err);
+
+ if (accel_psp->rx_bad_counter)
+ mlx5_fc_query(mdev, accel_psp->rx_bad_counter,
+ &stats->psp_rx_pkts_drop,
+ &stats->psp_rx_bytes_drop);
}
void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv)
@@ -849,12 +1040,30 @@ mlx5e_psp_key_rotate(struct psp_dev *psd, struct netlink_ext_ack *exack)
return mlx5e_psp_rotate_key(priv->mdev);
}
+static void
+mlx5e_psp_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats)
+{
+ struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
+ struct mlx5e_psp_stats nstats;
+
+ mlx5e_accel_psp_fs_get_stats_fill(priv, &nstats);
+ stats->rx_packets = nstats.psp_rx_pkts;
+ stats->rx_bytes = nstats.psp_rx_bytes;
+ stats->rx_auth_fail = nstats.psp_rx_pkts_auth_fail;
+ stats->rx_error = nstats.psp_rx_pkts_frame_err;
+ stats->rx_bad = nstats.psp_rx_pkts_drop;
+ stats->tx_packets = nstats.psp_tx_pkts;
+ stats->tx_bytes = nstats.psp_tx_bytes;
+ stats->tx_error = atomic_read(&priv->psp->tx_drop);
+}
+
static struct psp_dev_ops mlx5_psp_ops = {
.set_config = mlx5e_psp_set_config,
.rx_spi_alloc = mlx5e_psp_rx_spi_alloc,
.tx_key_add = mlx5e_psp_assoc_add,
.tx_key_del = mlx5e_psp_assoc_del,
.key_rotate = mlx5e_psp_key_rotate,
+ .get_stats = mlx5e_psp_get_stats,
};
void mlx5e_psp_unregister(struct mlx5e_priv *priv)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
index 42bb671fb2cb..b3284d00415f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
@@ -7,11 +7,29 @@
#include <net/psp/types.h>
#include "en.h"
+struct mlx5e_psp_stats {
+ u64 psp_rx_pkts;
+ u64 psp_rx_bytes;
+ u64 psp_rx_pkts_auth_fail;
+ u64 psp_rx_bytes_auth_fail;
+ u64 psp_rx_pkts_frame_err;
+ u64 psp_rx_bytes_frame_err;
+ u64 psp_rx_pkts_drop;
+ u64 psp_rx_bytes_drop;
+ u64 psp_tx_pkts;
+ u64 psp_tx_bytes;
+ u64 psp_tx_pkts_drop;
+ u64 psp_tx_bytes_drop;
+};
+
struct mlx5e_psp {
struct psp_dev *psp;
struct psp_dev_caps caps;
struct mlx5e_psp_fs *fs;
atomic_t tx_key_cnt;
+ atomic_t tx_drop;
+ /* Stats manage */
+ struct mlx5e_psp_stats stats;
};
static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
index 828bff1137af..c17ea0fcd8ef 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
@@ -186,6 +186,7 @@ bool mlx5e_psp_handle_tx_skb(struct net_device *netdev,
/* psp_encap of the packet */
if (!psp_dev_encapsulate(net, skb, psp_st->spi, psp_st->ver, 0)) {
kfree_skb_reason(skb, SKB_DROP_REASON_PSP_OUTPUT);
+ atomic_inc(&priv->psp->tx_drop);
return false;
}
if (skb_is_gso(skb)) {
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 9c46511e7b43..7d2419fda70a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3999,6 +3999,11 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
s->rx_bytes += rq_stats->bytes;
s->multicast += rq_stats->mcast_packets;
}
+
+#ifdef CONFIG_MLX5_EN_PSP
+ if (priv->psp)
+ s->tx_dropped += atomic_read(&priv->psp->tx_drop);
+#endif
}
void
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows
2025-10-28 0:00 ` [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
@ 2025-10-30 16:11 ` Cosmin Ratiu
2025-11-05 20:31 ` Daniel Zahka
0 siblings, 1 reply; 11+ messages in thread
From: Cosmin Ratiu @ 2025-10-30 16:11 UTC (permalink / raw)
To: andrew+netdev@lunn.ch, Saeed Mahameed, davem@davemloft.net,
Tariq Toukan, leon@kernel.org, shuah@kernel.org, Mark Bloch,
kuba@kernel.org, horms@kernel.org, daniel.zahka@gmail.com,
donald.hunter@gmail.com, Boris Pismenny, edumazet@google.com,
pabeni@redhat.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
On Mon, 2025-10-27 at 17:00 -0700, Daniel Zahka wrote:
> @@ -670,9 +813,57 @@ static int accel_psp_fs_init_tx(struct
> mlx5e_psp_fs *fs)
> return -ENOMEM;
>
> mutex_init(&tx_fs->mutex);
> + flow_counter = mlx5_fc_create(mdev, false);
> + if (IS_ERR(flow_counter)) {
> + mlx5_core_warn(mdev,
> + "fail to create psp tx flow counter
> err=%pe\n",
> + flow_counter);
> + err = PTR_ERR(flow_counter);
> + goto out_err;
> + }
> + tx_fs->tx_counter = flow_counter;
Nit: Moving the flow counter init before the mutex init would simplify
cleanup a bit (simple return instead of goto out_err).
> +static void
> +mlx5e_accel_psp_fs_get_stats_fill(struct mlx5e_priv *priv, void
> *psp_stats)
> +{
> + struct mlx5e_psp_stats *stats = (struct mlx5e_psp_stats
> *)psp_stats;
Why can't this function receive an mlx5e_psp_stats pointer directly? It
would avoid the boilerplate cast.
> +static void
> +mlx5e_psp_get_stats(struct psp_dev *psd, struct psp_dev_stats
> *stats)
> +{
> + struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
> + struct mlx5e_psp_stats nstats;
> +
> + mlx5e_accel_psp_fs_get_stats_fill(priv, &nstats);
I don't see the point of the intermediate struct mlx5e_psp_stats, this
function could query counters directly into stats.
>
> +struct mlx5e_psp_stats {
> + u64 psp_rx_pkts;
> + u64 psp_rx_bytes;
> + u64 psp_rx_pkts_auth_fail;
> + u64 psp_rx_bytes_auth_fail;
> + u64 psp_rx_pkts_frame_err;
> + u64 psp_rx_bytes_frame_err;
> + u64 psp_rx_pkts_drop;
> + u64 psp_rx_bytes_drop;
> + u64 psp_tx_pkts;
> + u64 psp_tx_bytes;
> + u64 psp_tx_pkts_drop;
> + u64 psp_tx_bytes_drop;
> +};
> +
> struct mlx5e_psp {
> struct psp_dev *psp;
> struct psp_dev_caps caps;
> struct mlx5e_psp_fs *fs;
> atomic_t tx_key_cnt;
> + atomic_t tx_drop;
> + /* Stats manage */
> + struct mlx5e_psp_stats stats;
This does not appear written anywhere. Is it planned to be used in a
future patch?
Cosmin.
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows
2025-10-30 16:11 ` Cosmin Ratiu
@ 2025-11-05 20:31 ` Daniel Zahka
0 siblings, 0 replies; 11+ messages in thread
From: Daniel Zahka @ 2025-11-05 20:31 UTC (permalink / raw)
To: Cosmin Ratiu, andrew+netdev@lunn.ch, Saeed Mahameed,
davem@davemloft.net, Tariq Toukan, leon@kernel.org,
shuah@kernel.org, Mark Bloch, kuba@kernel.org, horms@kernel.org,
donald.hunter@gmail.com, Boris Pismenny, edumazet@google.com,
pabeni@redhat.com
Cc: netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
On 10/30/25 12:11 PM, Cosmin Ratiu wrote:
>> +static void
>> +mlx5e_psp_get_stats(struct psp_dev *psd, struct psp_dev_stats
>> *stats)
>> +{
>> + struct mlx5e_priv *priv = netdev_priv(psd->main_netdev);
>> + struct mlx5e_psp_stats nstats;
>> +
>> + mlx5e_accel_psp_fs_get_stats_fill(priv, &nstats);
> I don't see the point of the intermediate struct mlx5e_psp_stats, this
> function could query counters directly into stats.
Just because mlx5_fc_query() populates packet and byte counts, but
psp_dev_stats required stats only have byte counts for two of the
categories.
I'll address the rest of you comments on the respin. Thanks for taking a
look.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH net-next v2 5/5] netdevsim: implement psp device stats
2025-10-28 0:00 [PATCH net-next v2 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
` (3 preceding siblings ...)
2025-10-28 0:00 ` [PATCH net-next v2 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
@ 2025-10-28 0:00 ` Daniel Zahka
4 siblings, 0 replies; 11+ messages in thread
From: Daniel Zahka @ 2025-10-28 0:00 UTC (permalink / raw)
To: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Simon Horman, Donald Hunter, Andrew Lunn, Shuah Khan,
Boris Pismenny, Saeed Mahameed, Leon Romanovsky, Tariq Toukan,
Mark Bloch
Cc: netdev, linux-kernel, linux-kselftest
For now only tx/rx packets/bytes are reported. This is not compliant
with the PSP Architecture Specification.
Signed-off-by: Daniel Zahka <daniel.zahka@gmail.com>
---
drivers/net/netdevsim/netdevsim.h | 5 +++++
drivers/net/netdevsim/psp.c | 27 +++++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/drivers/net/netdevsim/netdevsim.h b/drivers/net/netdevsim/netdevsim.h
index 02c1c97b7008..af6fcfcda8ba 100644
--- a/drivers/net/netdevsim/netdevsim.h
+++ b/drivers/net/netdevsim/netdevsim.h
@@ -109,6 +109,11 @@ struct netdevsim {
int rq_reset_mode;
struct {
+ u64 rx_packets;
+ u64 rx_bytes;
+ u64 tx_packets;
+ u64 tx_bytes;
+ struct u64_stats_sync syncp;
struct psp_dev *dev;
u32 spi;
u32 assoc_cnt;
diff --git a/drivers/net/netdevsim/psp.c b/drivers/net/netdevsim/psp.c
index 332b5b744f01..3912f2611862 100644
--- a/drivers/net/netdevsim/psp.c
+++ b/drivers/net/netdevsim/psp.c
@@ -70,6 +70,13 @@ nsim_do_psp(struct sk_buff *skb, struct netdevsim *ns,
*psp_ext = skb->extensions;
refcount_inc(&(*psp_ext)->refcnt);
skb->decrypted = 1;
+
+ u64_stats_update_begin(&ns->psp.syncp);
+ ns->psp.tx_packets++;
+ ns->psp.rx_packets++;
+ ns->psp.tx_bytes += skb->len - skb_inner_transport_offset(skb);
+ ns->psp.rx_bytes += skb->len - skb_inner_transport_offset(skb);
+ u64_stats_update_end(&ns->psp.syncp);
} else {
struct ipv6hdr *ip6h __maybe_unused;
struct iphdr *iph;
@@ -164,12 +171,32 @@ static void nsim_assoc_del(struct psp_dev *psd, struct psp_assoc *pas)
ns->psp.assoc_cnt--;
}
+static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats)
+{
+ struct netdevsim *ns = psd->drv_priv;
+ unsigned int start;
+
+ /* WARNING: do *not* blindly zero stats in real drivers!
+ * All required stats must be reported by the device!
+ */
+ memset(stats, 0, offsetof(struct psp_dev_stats, required_end));
+
+ do {
+ start = u64_stats_fetch_begin(&ns->psp.syncp);
+ stats->rx_bytes = ns->psp.rx_bytes;
+ stats->rx_packets = ns->psp.rx_packets;
+ stats->tx_bytes = ns->psp.tx_bytes;
+ stats->tx_packets = ns->psp.tx_packets;
+ } while (u64_stats_fetch_retry(&ns->psp.syncp, start));
+}
+
static struct psp_dev_ops nsim_psp_ops = {
.set_config = nsim_psp_set_config,
.rx_spi_alloc = nsim_rx_spi_alloc,
.tx_key_add = nsim_assoc_add,
.tx_key_del = nsim_assoc_del,
.key_rotate = nsim_key_rotate,
+ .get_stats = nsim_get_stats,
};
static struct psp_dev_caps nsim_psp_caps = {
--
2.47.3
^ permalink raw reply related [flat|nested] 11+ messages in thread