* [PATCH net-next 1/5] psp: report basic stats from the core
2025-10-22 19:37 [PATCH net-next 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
@ 2025-10-22 19:37 ` Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats Daniel Zahka
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Daniel Zahka @ 2025-10-22 19:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Shuah Khan
Cc: Simon Horman, Donald Hunter, Boris Pismenny, Mark Bloch,
Andrew Lunn, Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu,
Raed Salem, Kuniyuki Iwashima, netdev, 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>
---
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 | 79 ++++++++++++++++++++++++++++
net/psp/psp_sock.c | 4 +-
7 files changed, 162 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..094da52e357e 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,81 @@ 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;
+ unsigned long index;
+ int err = 0;
+
+ mutex_lock(&psp_devs_lock);
+ xa_for_each_start(&psp_devs, index, 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);
+
+ if (err != -EMSGSIZE)
+ return err;
+
+ cb->args[0] = index;
+ 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] 7+ messages in thread* [PATCH net-next 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats
2025-10-22 19:37 [PATCH net-next 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 1/5] psp: report basic stats from the core Daniel Zahka
@ 2025-10-22 19:37 ` Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 3/5] psp: add stats from psp spec to driver facing api Daniel Zahka
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Daniel Zahka @ 2025-10-22 19:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Shuah Khan
Cc: Simon Horman, Donald Hunter, Boris Pismenny, Mark Bloch,
Andrew Lunn, Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu,
Raed Salem, Kuniyuki Iwashima, netdev, 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] 7+ messages in thread* [PATCH net-next 3/5] psp: add stats from psp spec to driver facing api
2025-10-22 19:37 [PATCH net-next 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 1/5] psp: report basic stats from the core Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 2/5] selftests: drv-net: psp: add assertions on core-tracked psp dev stats Daniel Zahka
@ 2025-10-22 19:37 ` Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
2025-10-22 19:37 ` [PATCH net-next 5/5] netdevsim: implement psp device stats Daniel Zahka
4 siblings, 0 replies; 7+ messages in thread
From: Daniel Zahka @ 2025-10-22 19:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Shuah Khan
Cc: Simon Horman, Donald Hunter, Boris Pismenny, Mark Bloch,
Andrew Lunn, Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu,
Raed Salem, Kuniyuki Iwashima, netdev, 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 094da52e357e..9fe683c952f9 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] 7+ messages in thread* [PATCH net-next 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows
2025-10-22 19:37 [PATCH net-next 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
` (2 preceding siblings ...)
2025-10-22 19:37 ` [PATCH net-next 3/5] psp: add stats from psp spec to driver facing api Daniel Zahka
@ 2025-10-22 19:37 ` Daniel Zahka
2025-10-23 0:56 ` Jakub Kicinski
2025-10-22 19:37 ` [PATCH net-next 5/5] netdevsim: implement psp device stats Daniel Zahka
4 siblings, 1 reply; 7+ messages in thread
From: Daniel Zahka @ 2025-10-22 19:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Shuah Khan
Cc: Simon Horman, Donald Hunter, Boris Pismenny, Mark Bloch,
Andrew Lunn, Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu,
Raed Salem, Kuniyuki Iwashima, netdev, 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>
---
.../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..93c8f1f19d6b 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(%ld)\n",
+ PTR_ERR(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(%ld)\n",
+ PTR_ERR(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(%ld)\n",
+ PTR_ERR(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 auth fail flow counter err(%ld)\n",
+ PTR_ERR(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(%ld)\n",
+ PTR_ERR(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 a56825921c23..9fe18ae1e4e1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3998,6 +3998,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] 7+ messages in thread* Re: [PATCH net-next 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows
2025-10-22 19:37 ` [PATCH net-next 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
@ 2025-10-23 0:56 ` Jakub Kicinski
0 siblings, 0 replies; 7+ messages in thread
From: Jakub Kicinski @ 2025-10-23 0:56 UTC (permalink / raw)
To: Daniel Zahka
Cc: David S. Miller, Eric Dumazet, Paolo Abeni, Saeed Mahameed,
Leon Romanovsky, Tariq Toukan, Shuah Khan, Simon Horman,
Donald Hunter, Boris Pismenny, Mark Bloch, Andrew Lunn,
Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu, Raed Salem,
Kuniyuki Iwashima, netdev, linux-kselftest
On Wed, 22 Oct 2025 12:37:36 -0700 Daniel Zahka wrote:
> mlx5_core_warn(mdev,
> + "fail to create psp rx flow counter err(%ld)\n",
> + PTR_ERR(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(%ld)\n",
> + PTR_ERR(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(%ld)\n",
> + PTR_ERR(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 auth fail flow counter err(%ld)\n",
> + PTR_ERR(flow_counter));
Coccicheck sayeth (5x):
drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c:
WARNING: Consider using %pe to print PTR_ERR()
That's %pe, flow_counter instead of %d, PTR_ERR(flow_counter)
--
pw-bot: cr
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH net-next 5/5] netdevsim: implement psp device stats
2025-10-22 19:37 [PATCH net-next 0/5] psp: track stats from core and provide a driver stats api Daniel Zahka
` (3 preceding siblings ...)
2025-10-22 19:37 ` [PATCH net-next 4/5] net/mlx5e: Add PSP stats support for Rx/Tx flows Daniel Zahka
@ 2025-10-22 19:37 ` Daniel Zahka
4 siblings, 0 replies; 7+ messages in thread
From: Daniel Zahka @ 2025-10-22 19:37 UTC (permalink / raw)
To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
Saeed Mahameed, Leon Romanovsky, Tariq Toukan, Shuah Khan
Cc: Simon Horman, Donald Hunter, Boris Pismenny, Mark Bloch,
Andrew Lunn, Willem de Bruijn, Rahul Rameshbabu, Cosmin Ratiu,
Raed Salem, Kuniyuki Iwashima, netdev, 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] 7+ messages in thread