Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'psp-track-stats-from-core-and-provide-a-driver-stats-api'

Daniel Zahka says:

====================
psp: track stats from core and provide a driver stats api

This series introduces stats counters for psp. Device key rotations,
and so called 'stale-events' are common to all drivers and are tracked
by the core.

A driver facing api is provided for reporting stats required by the
"Implementation Requirements" section of the PSP Architecture
Specification. Drivers must implement these stats.

Lastly, implementations of the driver stats api for mlx5 and netdevsim
are included.

Here is the output of running the psp selftest suite and then
printing out stats with the ynl cli on system with a psp-capable CX7:

$ ./ksft-psp-stats/drivers/net/psp.py
TAP version 13
1..28
ok 1 psp.test_case # SKIP Test requires IPv4 connectivity
ok 2 psp.data_basic_send_v0_ip6
ok 3 psp.test_case # SKIP Test requires IPv4 connectivity
ok 4 psp.data_basic_send_v1_ip6
ok 5 psp.test_case # SKIP Test requires IPv4 connectivity
ok 6 psp.data_basic_send_v2_ip6 # SKIP ('PSP version not supported', 'hdr0-aes-gmac-128')
ok 7 psp.test_case # SKIP Test requires IPv4 connectivity
ok 8 psp.data_basic_send_v3_ip6 # SKIP ('PSP version not supported', 'hdr0-aes-gmac-256')
ok 9 psp.test_case # SKIP Test requires IPv4 connectivity
ok 10 psp.data_mss_adjust_ip6
ok 11 psp.dev_list_devices
ok 12 psp.dev_get_device
ok 13 psp.dev_get_device_bad
ok 14 psp.dev_rotate
ok 15 psp.dev_rotate_spi
ok 16 psp.assoc_basic
ok 17 psp.assoc_bad_dev
ok 18 psp.assoc_sk_only_conn
ok 19 psp.assoc_sk_only_mismatch
ok 20 psp.assoc_sk_only_mismatch_tx
ok 21 psp.assoc_sk_only_unconn
ok 22 psp.assoc_version_mismatch
ok 23 psp.assoc_twice
ok 24 psp.data_send_bad_key
ok 25 psp.data_send_disconnect
ok 26 psp.data_stale_key
ok 27 psp.removal_device_rx # XFAIL Test only works on netdevsim
ok 28 psp.removal_device_bi # XFAIL Test only works on netdevsim
# Totals: pass:19 fail:0 xfail:2 xpass:0 skip:7 error:0
#
# Responder logs (0):
# STDERR:
# Set PSP enable on device 1 to 0x3
# Set PSP enable on device 1 to 0x0

$ ynl --family psp --dump get-stats
[{'dev-id': 1,
'key-rotations': 5,
'rx-auth-fail': 21,
'rx-bad': 0,
'rx-bytes': 11844,
'rx-error': 0,
'rx-packets': 94,
'stale-events': 6,
'tx-bytes': 1128456,
'tx-error': 0,
'tx-packets': 780}]
====================

Link: https://patch.msgid.link/20251106002608.1578518-1-daniel.zahka@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+550 -18
+95
Documentation/netlink/specs/psp.yaml
··· 76 76 name: spi 77 77 doc: Security Parameters Index (SPI) of the association. 78 78 type: u32 79 + - 80 + name: stats 81 + attributes: 82 + - 83 + name: dev-id 84 + doc: PSP device ID. 85 + type: u32 86 + checks: 87 + min: 1 88 + - 89 + name: key-rotations 90 + type: uint 91 + doc: | 92 + Number of key rotations during the lifetime of the device. 93 + Kernel statistic. 94 + - 95 + name: stale-events 96 + type: uint 97 + doc: | 98 + Number of times a socket's Rx got shut down due to using 99 + a key which went stale (fully rotated out). 100 + Kernel statistic. 101 + - 102 + name: rx-packets 103 + type: uint 104 + doc: | 105 + Number of successfully processed and authenticated PSP packets. 106 + Device statistic (from the PSP spec). 107 + - 108 + name: rx-bytes 109 + type: uint 110 + doc: | 111 + Number of successfully authenticated PSP bytes received, counting from 112 + the first byte after the IV through the last byte of payload. 113 + The fixed initial portion of the PSP header (16 bytes) 114 + and the PSP trailer/ICV (16 bytes) are not included in this count. 115 + Device statistic (from the PSP spec). 116 + - 117 + name: rx-auth-fail 118 + type: uint 119 + doc: | 120 + Number of received PSP packets with unsuccessful authentication. 121 + Device statistic (from the PSP spec). 122 + - 123 + name: rx-error 124 + type: uint 125 + doc: | 126 + Number of received PSP packets with length/framing errors. 127 + Device statistic (from the PSP spec). 128 + - 129 + name: rx-bad 130 + type: uint 131 + doc: | 132 + Number of received PSP packets with miscellaneous errors 133 + (invalid master key indicated by SPI, unsupported version, etc.) 134 + Device statistic (from the PSP spec). 135 + - 136 + name: tx-packets 137 + type: uint 138 + doc: | 139 + Number of successfully processed PSP packets for transmission. 140 + Device statistic (from the PSP spec). 141 + - 142 + name: tx-bytes 143 + type: uint 144 + doc: | 145 + Number of successfully processed PSP bytes for transmit, counting from 146 + the first byte after the IV through the last byte of payload. 147 + The fixed initial portion of the PSP header (16 bytes) 148 + and the PSP trailer/ICV (16 bytes) are not included in this count. 149 + Device statistic (from the PSP spec). 150 + - 151 + name: tx-error 152 + type: uint 153 + doc: | 154 + Number of PSP packets for transmission with errors. 155 + Device statistic (from the PSP spec). 79 156 80 157 operations: 81 158 list: ··· 253 176 attributes: [] 254 177 pre: psp-assoc-device-get-locked 255 178 post: psp-device-unlock 179 + 180 + - 181 + name: get-stats 182 + doc: Get device statistics. 183 + attribute-set: stats 184 + do: 185 + request: 186 + attributes: 187 + - dev-id 188 + reply: &stats-all 189 + attributes: 190 + - dev-id 191 + - key-rotations 192 + - stale-events 193 + pre: psp-device-get-locked 194 + post: psp-device-unlock 195 + dump: 196 + reply: *stats-all 256 197 257 198 mcast-groups: 258 199 list:
+219 -16
drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.c
··· 28 28 struct mlx5_flow_handle *rule; 29 29 struct mutex mutex; /* Protect PSP TX steering */ 30 30 u32 refcnt; 31 + struct mlx5_fc *tx_counter; 31 32 }; 32 33 33 34 struct mlx5e_psp_rx_err { 34 35 struct mlx5_flow_table *ft; 35 36 struct mlx5_flow_handle *rule; 36 - struct mlx5_flow_handle *drop_rule; 37 + struct mlx5_flow_handle *auth_fail_rule; 38 + struct mlx5_flow_handle *err_rule; 39 + struct mlx5_flow_handle *bad_rule; 37 40 struct mlx5_modify_hdr *copy_modify_hdr; 38 41 }; 39 42 ··· 53 50 54 51 struct mlx5e_accel_fs_psp { 55 52 struct mlx5e_accel_fs_psp_prot fs_prot[ACCEL_FS_PSP_NUM_TYPES]; 53 + struct mlx5_fc *rx_counter; 54 + struct mlx5_fc *rx_auth_fail_counter; 55 + struct mlx5_fc *rx_err_counter; 56 + struct mlx5_fc *rx_bad_counter; 56 57 }; 57 58 58 59 struct mlx5e_psp_fs { ··· 79 72 static void accel_psp_fs_rx_err_del_rules(struct mlx5e_psp_fs *fs, 80 73 struct mlx5e_psp_rx_err *rx_err) 81 74 { 82 - if (rx_err->drop_rule) { 83 - mlx5_del_flow_rules(rx_err->drop_rule); 84 - rx_err->drop_rule = NULL; 75 + if (rx_err->bad_rule) { 76 + mlx5_del_flow_rules(rx_err->bad_rule); 77 + rx_err->bad_rule = NULL; 78 + } 79 + 80 + if (rx_err->err_rule) { 81 + mlx5_del_flow_rules(rx_err->err_rule); 82 + rx_err->err_rule = NULL; 83 + } 84 + 85 + if (rx_err->auth_fail_rule) { 86 + mlx5_del_flow_rules(rx_err->auth_fail_rule); 87 + rx_err->auth_fail_rule = NULL; 85 88 } 86 89 87 90 if (rx_err->rule) { ··· 134 117 { 135 118 u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {}; 136 119 struct mlx5_core_dev *mdev = fs->mdev; 120 + struct mlx5_flow_destination dest[2]; 137 121 struct mlx5_flow_act flow_act = {}; 138 122 struct mlx5_modify_hdr *modify_hdr; 139 123 struct mlx5_flow_handle *fte; ··· 165 147 accel_psp_setup_syndrome_match(spec, PSP_OK); 166 148 /* create fte */ 167 149 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_MOD_HDR | 168 - MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; 150 + MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | 151 + MLX5_FLOW_CONTEXT_ACTION_COUNT; 169 152 flow_act.modify_hdr = modify_hdr; 170 - fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, 171 - &fs_prot->default_dest, 1); 153 + dest[0].type = fs_prot->default_dest.type; 154 + dest[0].ft = fs_prot->default_dest.ft; 155 + dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 156 + dest[1].counter = fs->rx_fs->rx_counter; 157 + fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 2); 172 158 if (IS_ERR(fte)) { 173 159 err = PTR_ERR(fte); 174 160 mlx5_core_err(mdev, "fail to add psp rx err copy rule err=%d\n", err); ··· 180 158 } 181 159 rx_err->rule = fte; 182 160 183 - /* add default drop rule */ 161 + /* add auth fail drop rule */ 162 + memset(spec, 0, sizeof(*spec)); 163 + memset(&flow_act, 0, sizeof(flow_act)); 164 + accel_psp_setup_syndrome_match(spec, PSP_ICV_FAIL); 165 + /* create fte */ 166 + flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | 167 + MLX5_FLOW_CONTEXT_ACTION_COUNT; 168 + dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 169 + dest[0].counter = fs->rx_fs->rx_auth_fail_counter; 170 + fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1); 171 + if (IS_ERR(fte)) { 172 + err = PTR_ERR(fte); 173 + mlx5_core_err(mdev, "fail to add psp rx auth fail drop rule err=%d\n", 174 + err); 175 + goto out_drop_rule; 176 + } 177 + rx_err->auth_fail_rule = fte; 178 + 179 + /* add framing drop rule */ 180 + memset(spec, 0, sizeof(*spec)); 181 + memset(&flow_act, 0, sizeof(flow_act)); 182 + accel_psp_setup_syndrome_match(spec, PSP_BAD_TRAILER); 183 + /* create fte */ 184 + flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | 185 + MLX5_FLOW_CONTEXT_ACTION_COUNT; 186 + dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 187 + dest[0].counter = fs->rx_fs->rx_err_counter; 188 + fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1); 189 + if (IS_ERR(fte)) { 190 + err = PTR_ERR(fte); 191 + mlx5_core_err(mdev, "fail to add psp rx framing err drop rule err=%d\n", 192 + err); 193 + goto out_drop_auth_fail_rule; 194 + } 195 + rx_err->err_rule = fte; 196 + 197 + /* add misc. errors drop rule */ 184 198 memset(spec, 0, sizeof(*spec)); 185 199 memset(&flow_act, 0, sizeof(flow_act)); 186 200 /* create fte */ 187 - flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; 188 - fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, NULL, 0); 201 + flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP | 202 + MLX5_FLOW_CONTEXT_ACTION_COUNT; 203 + dest[0].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 204 + dest[0].counter = fs->rx_fs->rx_bad_counter; 205 + fte = mlx5_add_flow_rules(rx_err->ft, spec, &flow_act, dest, 1); 189 206 if (IS_ERR(fte)) { 190 207 err = PTR_ERR(fte); 191 - mlx5_core_err(mdev, "fail to add psp rx err drop rule err=%d\n", err); 192 - goto out_drop_rule; 208 + mlx5_core_err(mdev, "fail to add psp rx misc. err drop rule err=%d\n", 209 + err); 210 + goto out_drop_error_rule; 193 211 } 194 - rx_err->drop_rule = fte; 212 + rx_err->bad_rule = fte; 213 + 195 214 rx_err->copy_modify_hdr = modify_hdr; 196 215 197 216 goto out_spec; 198 217 218 + out_drop_error_rule: 219 + mlx5_del_flow_rules(rx_err->err_rule); 220 + rx_err->err_rule = NULL; 221 + out_drop_auth_fail_rule: 222 + mlx5_del_flow_rules(rx_err->auth_fail_rule); 223 + rx_err->auth_fail_rule = NULL; 199 224 out_drop_rule: 200 225 mlx5_del_flow_rules(rx_err->rule); 201 226 rx_err->rule = NULL; ··· 530 461 return; 531 462 532 463 accel_psp = fs->rx_fs; 464 + mlx5_fc_destroy(fs->mdev, accel_psp->rx_bad_counter); 465 + mlx5_fc_destroy(fs->mdev, accel_psp->rx_err_counter); 466 + mlx5_fc_destroy(fs->mdev, accel_psp->rx_auth_fail_counter); 467 + mlx5_fc_destroy(fs->mdev, accel_psp->rx_counter); 533 468 for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) { 534 469 fs_prot = &accel_psp->fs_prot[i]; 535 470 mutex_destroy(&fs_prot->prot_mutex); ··· 547 474 { 548 475 struct mlx5e_accel_fs_psp_prot *fs_prot; 549 476 struct mlx5e_accel_fs_psp *accel_psp; 477 + struct mlx5_core_dev *mdev = fs->mdev; 478 + struct mlx5_fc *flow_counter; 550 479 enum accel_fs_psp_type i; 480 + int err; 551 481 552 482 accel_psp = kzalloc(sizeof(*accel_psp), GFP_KERNEL); 553 483 if (!accel_psp) ··· 561 485 mutex_init(&fs_prot->prot_mutex); 562 486 } 563 487 488 + flow_counter = mlx5_fc_create(mdev, false); 489 + if (IS_ERR(flow_counter)) { 490 + mlx5_core_warn(mdev, 491 + "fail to create psp rx flow counter err=%pe\n", 492 + flow_counter); 493 + err = PTR_ERR(flow_counter); 494 + goto out_err; 495 + } 496 + accel_psp->rx_counter = flow_counter; 497 + 498 + flow_counter = mlx5_fc_create(mdev, false); 499 + if (IS_ERR(flow_counter)) { 500 + mlx5_core_warn(mdev, 501 + "fail to create psp rx auth fail flow counter err=%pe\n", 502 + flow_counter); 503 + err = PTR_ERR(flow_counter); 504 + goto out_counter_err; 505 + } 506 + accel_psp->rx_auth_fail_counter = flow_counter; 507 + 508 + flow_counter = mlx5_fc_create(mdev, false); 509 + if (IS_ERR(flow_counter)) { 510 + mlx5_core_warn(mdev, 511 + "fail to create psp rx error flow counter err=%pe\n", 512 + flow_counter); 513 + err = PTR_ERR(flow_counter); 514 + goto out_auth_fail_counter_err; 515 + } 516 + accel_psp->rx_err_counter = flow_counter; 517 + 518 + flow_counter = mlx5_fc_create(mdev, false); 519 + if (IS_ERR(flow_counter)) { 520 + mlx5_core_warn(mdev, 521 + "fail to create psp rx bad flow counter err=%pe\n", 522 + flow_counter); 523 + err = PTR_ERR(flow_counter); 524 + goto out_err_counter_err; 525 + } 526 + accel_psp->rx_bad_counter = flow_counter; 527 + 564 528 fs->rx_fs = accel_psp; 565 529 566 530 return 0; 531 + 532 + out_err_counter_err: 533 + mlx5_fc_destroy(mdev, accel_psp->rx_err_counter); 534 + accel_psp->rx_err_counter = NULL; 535 + out_auth_fail_counter_err: 536 + mlx5_fc_destroy(mdev, accel_psp->rx_auth_fail_counter); 537 + accel_psp->rx_auth_fail_counter = NULL; 538 + out_counter_err: 539 + mlx5_fc_destroy(mdev, accel_psp->rx_counter); 540 + accel_psp->rx_counter = NULL; 541 + out_err: 542 + for (i = 0; i < ACCEL_FS_PSP_NUM_TYPES; i++) { 543 + fs_prot = &accel_psp->fs_prot[i]; 544 + mutex_destroy(&fs_prot->prot_mutex); 545 + } 546 + kfree(accel_psp); 547 + fs->rx_fs = NULL; 548 + 549 + return err; 567 550 } 568 551 569 552 void mlx5_accel_psp_fs_cleanup_rx_tables(struct mlx5e_priv *priv) ··· 667 532 { 668 533 int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); 669 534 struct mlx5_flow_table_attr ft_attr = {}; 535 + struct mlx5_flow_destination dest = {}; 670 536 struct mlx5_core_dev *mdev = fs->mdev; 671 537 struct mlx5_flow_act flow_act = {}; 672 538 u32 *in, *mc, *outer_headers_c; ··· 716 580 flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_PSP; 717 581 flow_act.flags |= FLOW_ACT_NO_APPEND; 718 582 flow_act.action = MLX5_FLOW_CONTEXT_ACTION_ALLOW | 719 - MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT; 720 - rule = mlx5_add_flow_rules(ft, spec, &flow_act, NULL, 0); 583 + MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT | 584 + MLX5_FLOW_CONTEXT_ACTION_COUNT; 585 + dest.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; 586 + dest.counter = tx_fs->tx_counter; 587 + rule = mlx5_add_flow_rules(ft, spec, &flow_act, &dest, 1); 721 588 if (IS_ERR(rule)) { 722 589 err = PTR_ERR(rule); 723 590 mlx5_core_err(mdev, "PSP: fail to add psp tx flow rule, err = %d\n", err); ··· 789 650 if (!tx_fs) 790 651 return; 791 652 653 + mlx5_fc_destroy(fs->mdev, tx_fs->tx_counter); 792 654 mutex_destroy(&tx_fs->mutex); 793 655 WARN_ON(tx_fs->refcnt); 794 656 kfree(tx_fs); ··· 798 658 799 659 static int accel_psp_fs_init_tx(struct mlx5e_psp_fs *fs) 800 660 { 661 + struct mlx5_core_dev *mdev = fs->mdev; 801 662 struct mlx5_flow_namespace *ns; 663 + struct mlx5_fc *flow_counter; 802 664 struct mlx5e_psp_tx *tx_fs; 803 665 804 - ns = mlx5_get_flow_namespace(fs->mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC); 666 + ns = mlx5_get_flow_namespace(mdev, MLX5_FLOW_NAMESPACE_EGRESS_IPSEC); 805 667 if (!ns) 806 668 return -EOPNOTSUPP; 807 669 ··· 811 669 if (!tx_fs) 812 670 return -ENOMEM; 813 671 672 + flow_counter = mlx5_fc_create(mdev, false); 673 + if (IS_ERR(flow_counter)) { 674 + mlx5_core_warn(mdev, 675 + "fail to create psp tx flow counter err=%pe\n", 676 + flow_counter); 677 + kfree(tx_fs); 678 + return PTR_ERR(flow_counter); 679 + } 680 + tx_fs->tx_counter = flow_counter; 814 681 mutex_init(&tx_fs->mutex); 815 682 tx_fs->ns = ns; 816 683 fs->tx_fs = tx_fs; 817 684 return 0; 685 + } 686 + 687 + static void 688 + mlx5e_accel_psp_fs_get_stats_fill(struct mlx5e_priv *priv, 689 + struct mlx5e_psp_stats *stats) 690 + { 691 + struct mlx5e_psp_tx *tx_fs = priv->psp->fs->tx_fs; 692 + struct mlx5_core_dev *mdev = priv->mdev; 693 + struct mlx5e_accel_fs_psp *accel_psp; 694 + 695 + accel_psp = (struct mlx5e_accel_fs_psp *)priv->psp->fs->rx_fs; 696 + 697 + if (tx_fs->tx_counter) 698 + mlx5_fc_query(mdev, tx_fs->tx_counter, &stats->psp_tx_pkts, 699 + &stats->psp_tx_bytes); 700 + 701 + if (accel_psp->rx_counter) 702 + mlx5_fc_query(mdev, accel_psp->rx_counter, &stats->psp_rx_pkts, 703 + &stats->psp_rx_bytes); 704 + 705 + if (accel_psp->rx_auth_fail_counter) 706 + mlx5_fc_query(mdev, accel_psp->rx_auth_fail_counter, 707 + &stats->psp_rx_pkts_auth_fail, 708 + &stats->psp_rx_bytes_auth_fail); 709 + 710 + if (accel_psp->rx_err_counter) 711 + mlx5_fc_query(mdev, accel_psp->rx_err_counter, 712 + &stats->psp_rx_pkts_frame_err, 713 + &stats->psp_rx_bytes_frame_err); 714 + 715 + if (accel_psp->rx_bad_counter) 716 + mlx5_fc_query(mdev, accel_psp->rx_bad_counter, 717 + &stats->psp_rx_pkts_drop, 718 + &stats->psp_rx_bytes_drop); 818 719 } 819 720 820 721 void mlx5_accel_psp_fs_cleanup_tx_tables(struct mlx5e_priv *priv) ··· 1034 849 return mlx5e_psp_rotate_key(priv->mdev); 1035 850 } 1036 851 852 + static void 853 + mlx5e_psp_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats) 854 + { 855 + struct mlx5e_priv *priv = netdev_priv(psd->main_netdev); 856 + struct mlx5e_psp_stats nstats; 857 + 858 + mlx5e_accel_psp_fs_get_stats_fill(priv, &nstats); 859 + stats->rx_packets = nstats.psp_rx_pkts; 860 + stats->rx_bytes = nstats.psp_rx_bytes; 861 + stats->rx_auth_fail = nstats.psp_rx_pkts_auth_fail; 862 + stats->rx_error = nstats.psp_rx_pkts_frame_err; 863 + stats->rx_bad = nstats.psp_rx_pkts_drop; 864 + stats->tx_packets = nstats.psp_tx_pkts; 865 + stats->tx_bytes = nstats.psp_tx_bytes; 866 + stats->tx_error = atomic_read(&priv->psp->tx_drop); 867 + } 868 + 1037 869 static struct psp_dev_ops mlx5_psp_ops = { 1038 870 .set_config = mlx5e_psp_set_config, 1039 871 .rx_spi_alloc = mlx5e_psp_rx_spi_alloc, 1040 872 .tx_key_add = mlx5e_psp_assoc_add, 1041 873 .tx_key_del = mlx5e_psp_assoc_del, 1042 874 .key_rotate = mlx5e_psp_key_rotate, 875 + .get_stats = mlx5e_psp_get_stats, 1043 876 }; 1044 877 1045 878 void mlx5e_psp_unregister(struct mlx5e_priv *priv)
+16
drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp.h
··· 7 7 #include <net/psp/types.h> 8 8 #include "en.h" 9 9 10 + struct mlx5e_psp_stats { 11 + u64 psp_rx_pkts; 12 + u64 psp_rx_bytes; 13 + u64 psp_rx_pkts_auth_fail; 14 + u64 psp_rx_bytes_auth_fail; 15 + u64 psp_rx_pkts_frame_err; 16 + u64 psp_rx_bytes_frame_err; 17 + u64 psp_rx_pkts_drop; 18 + u64 psp_rx_bytes_drop; 19 + u64 psp_tx_pkts; 20 + u64 psp_tx_bytes; 21 + u64 psp_tx_pkts_drop; 22 + u64 psp_tx_bytes_drop; 23 + }; 24 + 10 25 struct mlx5e_psp { 11 26 struct psp_dev *psp; 12 27 struct psp_dev_caps caps; 13 28 struct mlx5e_psp_fs *fs; 14 29 atomic_t tx_key_cnt; 30 + atomic_t tx_drop; 15 31 }; 16 32 17 33 static inline bool mlx5_is_psp_device(struct mlx5_core_dev *mdev)
+1
drivers/net/ethernet/mellanox/mlx5/core/en_accel/psp_rxtx.c
··· 186 186 /* psp_encap of the packet */ 187 187 if (!psp_dev_encapsulate(net, skb, psp_st->spi, psp_st->ver, 0)) { 188 188 kfree_skb_reason(skb, SKB_DROP_REASON_PSP_OUTPUT); 189 + atomic_inc(&priv->psp->tx_drop); 189 190 return false; 190 191 } 191 192 if (skb_is_gso(skb)) {
+5
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
··· 4025 4025 s->rx_bytes += rq_stats->bytes; 4026 4026 s->multicast += rq_stats->mcast_packets; 4027 4027 } 4028 + 4029 + #ifdef CONFIG_MLX5_EN_PSP 4030 + if (priv->psp) 4031 + s->tx_dropped += atomic_read(&priv->psp->tx_drop); 4032 + #endif 4028 4033 } 4029 4034 4030 4035 void
+5
drivers/net/netdevsim/netdevsim.h
··· 109 109 int rq_reset_mode; 110 110 111 111 struct { 112 + u64 rx_packets; 113 + u64 rx_bytes; 114 + u64 tx_packets; 115 + u64 tx_bytes; 116 + struct u64_stats_sync syncp; 112 117 struct psp_dev *dev; 113 118 u32 spi; 114 119 u32 assoc_cnt;
+27
drivers/net/netdevsim/psp.c
··· 70 70 *psp_ext = skb->extensions; 71 71 refcount_inc(&(*psp_ext)->refcnt); 72 72 skb->decrypted = 1; 73 + 74 + u64_stats_update_begin(&ns->psp.syncp); 75 + ns->psp.tx_packets++; 76 + ns->psp.rx_packets++; 77 + ns->psp.tx_bytes += skb->len - skb_inner_transport_offset(skb); 78 + ns->psp.rx_bytes += skb->len - skb_inner_transport_offset(skb); 79 + u64_stats_update_end(&ns->psp.syncp); 73 80 } else { 74 81 struct ipv6hdr *ip6h __maybe_unused; 75 82 struct iphdr *iph; ··· 171 164 ns->psp.assoc_cnt--; 172 165 } 173 166 167 + static void nsim_get_stats(struct psp_dev *psd, struct psp_dev_stats *stats) 168 + { 169 + struct netdevsim *ns = psd->drv_priv; 170 + unsigned int start; 171 + 172 + /* WARNING: do *not* blindly zero stats in real drivers! 173 + * All required stats must be reported by the device! 174 + */ 175 + memset(stats, 0, sizeof(struct psp_dev_stats)); 176 + 177 + do { 178 + start = u64_stats_fetch_begin(&ns->psp.syncp); 179 + stats->rx_bytes = ns->psp.rx_bytes; 180 + stats->rx_packets = ns->psp.rx_packets; 181 + stats->tx_bytes = ns->psp.tx_bytes; 182 + stats->tx_packets = ns->psp.tx_packets; 183 + } while (u64_stats_fetch_retry(&ns->psp.syncp, start)); 184 + } 185 + 174 186 static struct psp_dev_ops nsim_psp_ops = { 175 187 .set_config = nsim_psp_set_config, 176 188 .rx_spi_alloc = nsim_rx_spi_alloc, 177 189 .tx_key_add = nsim_assoc_add, 178 190 .tx_key_del = nsim_assoc_del, 179 191 .key_rotate = nsim_key_rotate, 192 + .get_stats = nsim_get_stats, 180 193 }; 181 194 182 195 static struct psp_dev_caps nsim_psp_caps = {
+32
include/net/psp/types.h
··· 59 59 * device key 60 60 * @stale_assocs: associations which use a rotated out key 61 61 * 62 + * @stats: statistics maintained by the core 63 + * @stats.rotations: See stats attr key-rotations 64 + * @stats.stales: See stats attr stale-events 65 + * 62 66 * @rcu: RCU head for freeing the structure 63 67 */ 64 68 struct psp_dev { ··· 84 80 struct list_head active_assocs; 85 81 struct list_head prev_assocs; 86 82 struct list_head stale_assocs; 83 + 84 + struct { 85 + unsigned long rotations; 86 + unsigned long stales; 87 + } stats; 87 88 88 89 struct rcu_head rcu; 89 90 }; ··· 150 141 u8 drv_data[] __aligned(8); 151 142 }; 152 143 144 + struct psp_dev_stats { 145 + union { 146 + struct { 147 + u64 rx_packets; 148 + u64 rx_bytes; 149 + u64 rx_auth_fail; 150 + u64 rx_error; 151 + u64 rx_bad; 152 + u64 tx_packets; 153 + u64 tx_bytes; 154 + u64 tx_error; 155 + }; 156 + DECLARE_FLEX_ARRAY(u64, required); 157 + }; 158 + }; 159 + 153 160 /** 154 161 * struct psp_dev_ops - netdev driver facing PSP callbacks 155 162 */ ··· 204 179 * Remove an association from the device. 205 180 */ 206 181 void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas); 182 + 183 + /** 184 + * @get_stats: get statistics from the device 185 + * Stats required by the spec must be maintained and filled in. 186 + * Stats must be filled in member-by-member, never memset the struct. 187 + */ 188 + void (*get_stats)(struct psp_dev *psd, struct psp_dev_stats *stats); 207 189 }; 208 190 209 191 #endif /* __NET_PSP_H */
+18
include/uapi/linux/psp.h
··· 46 46 }; 47 47 48 48 enum { 49 + PSP_A_STATS_DEV_ID = 1, 50 + PSP_A_STATS_KEY_ROTATIONS, 51 + PSP_A_STATS_STALE_EVENTS, 52 + PSP_A_STATS_RX_PACKETS, 53 + PSP_A_STATS_RX_BYTES, 54 + PSP_A_STATS_RX_AUTH_FAIL, 55 + PSP_A_STATS_RX_ERROR, 56 + PSP_A_STATS_RX_BAD, 57 + PSP_A_STATS_TX_PACKETS, 58 + PSP_A_STATS_TX_BYTES, 59 + PSP_A_STATS_TX_ERROR, 60 + 61 + __PSP_A_STATS_MAX, 62 + PSP_A_STATS_MAX = (__PSP_A_STATS_MAX - 1) 63 + }; 64 + 65 + enum { 49 66 PSP_CMD_DEV_GET = 1, 50 67 PSP_CMD_DEV_ADD_NTF, 51 68 PSP_CMD_DEV_DEL_NTF, ··· 72 55 PSP_CMD_KEY_ROTATE_NTF, 73 56 PSP_CMD_RX_ASSOC, 74 57 PSP_CMD_TX_ASSOC, 58 + PSP_CMD_GET_STATS, 75 59 76 60 __PSP_CMD_MAX, 77 61 PSP_CMD_MAX = (__PSP_CMD_MAX - 1)
+19
net/psp/psp-nl-gen.c
··· 47 47 [PSP_A_ASSOC_SOCK_FD] = { .type = NLA_U32, }, 48 48 }; 49 49 50 + /* PSP_CMD_GET_STATS - do */ 51 + static const struct nla_policy psp_get_stats_nl_policy[PSP_A_STATS_DEV_ID + 1] = { 52 + [PSP_A_STATS_DEV_ID] = NLA_POLICY_MIN(NLA_U32, 1), 53 + }; 54 + 50 55 /* Ops table for psp */ 51 56 static const struct genl_split_ops psp_nl_ops[] = { 52 57 { ··· 103 98 .policy = psp_tx_assoc_nl_policy, 104 99 .maxattr = PSP_A_ASSOC_SOCK_FD, 105 100 .flags = GENL_CMD_CAP_DO, 101 + }, 102 + { 103 + .cmd = PSP_CMD_GET_STATS, 104 + .pre_doit = psp_device_get_locked, 105 + .doit = psp_nl_get_stats_doit, 106 + .post_doit = psp_device_unlock, 107 + .policy = psp_get_stats_nl_policy, 108 + .maxattr = PSP_A_STATS_DEV_ID, 109 + .flags = GENL_CMD_CAP_DO, 110 + }, 111 + { 112 + .cmd = PSP_CMD_GET_STATS, 113 + .dumpit = psp_nl_get_stats_dumpit, 114 + .flags = GENL_CMD_CAP_DUMP, 106 115 }, 107 116 }; 108 117
+2
net/psp/psp-nl-gen.h
··· 28 28 int psp_nl_key_rotate_doit(struct sk_buff *skb, struct genl_info *info); 29 29 int psp_nl_rx_assoc_doit(struct sk_buff *skb, struct genl_info *info); 30 30 int psp_nl_tx_assoc_doit(struct sk_buff *skb, struct genl_info *info); 31 + int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info); 32 + int psp_nl_get_stats_dumpit(struct sk_buff *skb, struct netlink_callback *cb); 31 33 32 34 enum { 33 35 PSP_NLGRP_MGMT,
+2 -1
net/psp/psp_main.c
··· 60 60 !psd_ops->key_rotate || 61 61 !psd_ops->rx_spi_alloc || 62 62 !psd_ops->tx_key_add || 63 - !psd_ops->tx_key_del)) 63 + !psd_ops->tx_key_del || 64 + !psd_ops->get_stats)) 64 65 return ERR_PTR(-EINVAL); 65 66 66 67 psd = kzalloc(sizeof(*psd), GFP_KERNEL);
+93
net/psp/psp_nl.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 3 + #include <linux/ethtool.h> 3 4 #include <linux/skbuff.h> 4 5 #include <linux/xarray.h> 5 6 #include <net/genetlink.h> ··· 263 262 psd->generation & ~PSP_GEN_VALID_MASK); 264 263 265 264 psp_assocs_key_rotated(psd); 265 + psd->stats.rotations++; 266 266 267 267 nlmsg_end(ntf, (struct nlmsghdr *)ntf->data); 268 268 genlmsg_multicast_netns(&psp_nl_family, dev_net(psd->main_netdev), ntf, ··· 503 501 504 502 err_free_msg: 505 503 nlmsg_free(rsp); 504 + return err; 505 + } 506 + 507 + static int 508 + psp_nl_stats_fill(struct psp_dev *psd, struct sk_buff *rsp, 509 + const struct genl_info *info) 510 + { 511 + unsigned int required_cnt = sizeof(struct psp_dev_stats) / sizeof(u64); 512 + struct psp_dev_stats stats; 513 + void *hdr; 514 + int i; 515 + 516 + memset(&stats, 0xff, sizeof(stats)); 517 + psd->ops->get_stats(psd, &stats); 518 + 519 + for (i = 0; i < required_cnt; i++) 520 + if (WARN_ON_ONCE(stats.required[i] == ETHTOOL_STAT_NOT_SET)) 521 + return -EOPNOTSUPP; 522 + 523 + hdr = genlmsg_iput(rsp, info); 524 + if (!hdr) 525 + return -EMSGSIZE; 526 + 527 + if (nla_put_u32(rsp, PSP_A_STATS_DEV_ID, psd->id) || 528 + nla_put_uint(rsp, PSP_A_STATS_KEY_ROTATIONS, 529 + psd->stats.rotations) || 530 + nla_put_uint(rsp, PSP_A_STATS_STALE_EVENTS, psd->stats.stales) || 531 + nla_put_uint(rsp, PSP_A_STATS_RX_PACKETS, stats.rx_packets) || 532 + nla_put_uint(rsp, PSP_A_STATS_RX_BYTES, stats.rx_bytes) || 533 + nla_put_uint(rsp, PSP_A_STATS_RX_AUTH_FAIL, stats.rx_auth_fail) || 534 + nla_put_uint(rsp, PSP_A_STATS_RX_ERROR, stats.rx_error) || 535 + nla_put_uint(rsp, PSP_A_STATS_RX_BAD, stats.rx_bad) || 536 + nla_put_uint(rsp, PSP_A_STATS_TX_PACKETS, stats.tx_packets) || 537 + nla_put_uint(rsp, PSP_A_STATS_TX_BYTES, stats.tx_bytes) || 538 + nla_put_uint(rsp, PSP_A_STATS_TX_ERROR, stats.tx_error)) 539 + goto err_cancel_msg; 540 + 541 + genlmsg_end(rsp, hdr); 542 + return 0; 543 + 544 + err_cancel_msg: 545 + genlmsg_cancel(rsp, hdr); 546 + return -EMSGSIZE; 547 + } 548 + 549 + int psp_nl_get_stats_doit(struct sk_buff *skb, struct genl_info *info) 550 + { 551 + struct psp_dev *psd = info->user_ptr[0]; 552 + struct sk_buff *rsp; 553 + int err; 554 + 555 + rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 556 + if (!rsp) 557 + return -ENOMEM; 558 + 559 + err = psp_nl_stats_fill(psd, rsp, info); 560 + if (err) 561 + goto err_free_msg; 562 + 563 + return genlmsg_reply(rsp, info); 564 + 565 + err_free_msg: 566 + nlmsg_free(rsp); 567 + return err; 568 + } 569 + 570 + static int 571 + psp_nl_stats_get_dumpit_one(struct sk_buff *rsp, struct netlink_callback *cb, 572 + struct psp_dev *psd) 573 + { 574 + if (psp_dev_check_access(psd, sock_net(rsp->sk))) 575 + return 0; 576 + 577 + return psp_nl_stats_fill(psd, rsp, genl_info_dump(cb)); 578 + } 579 + 580 + int psp_nl_get_stats_dumpit(struct sk_buff *rsp, struct netlink_callback *cb) 581 + { 582 + struct psp_dev *psd; 583 + int err = 0; 584 + 585 + mutex_lock(&psp_devs_lock); 586 + xa_for_each_start(&psp_devs, cb->args[0], psd, cb->args[0]) { 587 + mutex_lock(&psd->lock); 588 + err = psp_nl_stats_get_dumpit_one(rsp, cb, psd); 589 + mutex_unlock(&psd->lock); 590 + if (err) 591 + break; 592 + } 593 + mutex_unlock(&psp_devs_lock); 594 + 506 595 return err; 507 596 }
+3 -1
net/psp/psp_sock.c
··· 253 253 /* Mark the stale associations as invalid, they will no longer 254 254 * be able to Rx any traffic. 255 255 */ 256 - list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) 256 + list_for_each_entry_safe(pas, next, &psd->prev_assocs, assocs_list) { 257 257 pas->generation |= ~PSP_GEN_VALID_MASK; 258 + psd->stats.stales++; 259 + } 258 260 list_splice_init(&psd->prev_assocs, &psd->stale_assocs); 259 261 list_splice_init(&psd->active_assocs, &psd->prev_assocs); 260 262
+13
tools/testing/selftests/drivers/net/psp.py
··· 109 109 time.sleep(0.01) 110 110 ksft_eq(outq, exp_len) 111 111 112 + 113 + def _get_stat(cfg, key): 114 + return cfg.pspnl.get_stats({'dev-id': cfg.psp_dev_id})[key] 115 + 112 116 # 113 117 # Test case boiler plate 114 118 # ··· 175 171 """ Test key rotation """ 176 172 _init_psp_dev(cfg) 177 173 174 + prev_rotations = _get_stat(cfg, 'key-rotations') 175 + 178 176 rot = cfg.pspnl.key_rotate({"id": cfg.psp_dev_id}) 179 177 ksft_eq(rot['id'], cfg.psp_dev_id) 180 178 rot = cfg.pspnl.key_rotate({"id": cfg.psp_dev_id}) 181 179 ksft_eq(rot['id'], cfg.psp_dev_id) 180 + 181 + cur_rotations = _get_stat(cfg, 'key-rotations') 182 + ksft_eq(cur_rotations, prev_rotations + 2) 182 183 183 184 184 185 def dev_rotate_spi(cfg): ··· 484 475 """ Test send on a double-rotated key """ 485 476 _init_psp_dev(cfg) 486 477 478 + prev_stale = _get_stat(cfg, 'stale-events') 487 479 s = _make_psp_conn(cfg) 488 480 try: 489 481 rx_assoc = cfg.pspnl.rx_assoc({"version": 0, ··· 504 494 505 495 cfg.pspnl.key_rotate({"id": cfg.psp_dev_id}) 506 496 cfg.pspnl.key_rotate({"id": cfg.psp_dev_id}) 497 + 498 + cur_stale = _get_stat(cfg, 'stale-events') 499 + ksft_gt(cur_stale, prev_stale) 507 500 508 501 s.send(b'0123456789' * 200) 509 502 _check_data_outq(s, 2000, force_wait=True)