Commit 5a6cddb8 authored by Raed Salem's avatar Raed Salem Committed by Leon Romanovsky

net/mlx5e: Update IPsec per SA packets/bytes count

Providing per SA packets/bytes statistics mandates creating unique
counter per SA flow for Rx/Tx, whenever offloaded SA statistics is
desired query the specific SA counter to provide the stack with the
needed data.
Signed-off-by: default avatarRaed Salem <raeds@nvidia.com>
Link: https://lore.kernel.org/r/7d5ce20ac495f3054afb633128700e7b7eeeb3cd.1678714336.git.leon@kernel.orgSigned-off-by: default avatarLeon Romanovsky <leon@kernel.org>
parent d0c19a31
...@@ -495,24 +495,18 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x) ...@@ -495,24 +495,18 @@ static void mlx5e_xfrm_advance_esn_state(struct xfrm_state *x)
static void mlx5e_xfrm_update_curlft(struct xfrm_state *x) static void mlx5e_xfrm_update_curlft(struct xfrm_state *x)
{ {
struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x);
int err; struct mlx5e_ipsec_rule *ipsec_rule = &sa_entry->ipsec_rule;
u64 packets, bytes, lastuse;
lockdep_assert_held(&x->lock); lockdep_assert(lockdep_is_held(&x->lock) ||
lockdep_is_held(&dev_net(x->xso.real_dev)->xfrm.xfrm_cfg_mutex));
if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ) if (x->xso.flags & XFRM_DEV_OFFLOAD_FLAG_ACQ)
return; return;
if (sa_entry->attrs.soft_packet_limit == XFRM_INF) mlx5_fc_query_cached(ipsec_rule->fc, &bytes, &packets, &lastuse);
/* Limits are not configured, as soft limit x->curlft.packets += packets;
* must be lowever than hard limit. x->curlft.bytes += bytes;
*/
return;
err = mlx5e_ipsec_aso_query(sa_entry, NULL);
if (err)
return;
mlx5e_ipsec_aso_update_curlft(sa_entry, &x->curlft.packets);
} }
static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev, static int mlx5e_xfrm_validate_policy(struct mlx5_core_dev *mdev,
......
...@@ -162,6 +162,7 @@ struct mlx5e_ipsec_rule { ...@@ -162,6 +162,7 @@ struct mlx5e_ipsec_rule {
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct mlx5_modify_hdr *modify_hdr; struct mlx5_modify_hdr *modify_hdr;
struct mlx5_pkt_reformat *pkt_reformat; struct mlx5_pkt_reformat *pkt_reformat;
struct mlx5_fc *fc;
}; };
struct mlx5e_ipsec_modify_state_work { struct mlx5e_ipsec_modify_state_work {
...@@ -235,9 +236,6 @@ void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec); ...@@ -235,9 +236,6 @@ void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec);
int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
struct mlx5_wqe_aso_ctrl_seg *data); struct mlx5_wqe_aso_ctrl_seg *data);
void mlx5e_ipsec_aso_update_curlft(struct mlx5e_ipsec_sa_entry *sa_entry,
u64 *packets);
void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv,
void *ipsec_stats); void *ipsec_stats);
......
...@@ -876,11 +876,12 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -876,11 +876,12 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry); struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry);
struct mlx5e_ipsec *ipsec = sa_entry->ipsec; struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
struct mlx5_flow_destination dest = {}; struct mlx5_flow_destination dest[2];
struct mlx5_flow_act flow_act = {}; struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec; struct mlx5_flow_spec *spec;
struct mlx5e_ipsec_rx *rx; struct mlx5e_ipsec_rx *rx;
struct mlx5_fc *counter;
int err; int err;
rx = rx_ft_get(mdev, ipsec, attrs->family); rx = rx_ft_get(mdev, ipsec, attrs->family);
...@@ -917,14 +918,22 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -917,14 +918,22 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
break; break;
} }
counter = mlx5_fc_create(mdev, true);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
goto err_add_cnt;
}
flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_IPSEC; flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_IPSEC;
flow_act.crypto.obj_id = sa_entry->ipsec_obj_id; flow_act.crypto.obj_id = sa_entry->ipsec_obj_id;
flow_act.flags |= FLOW_ACT_NO_APPEND; flow_act.flags |= FLOW_ACT_NO_APPEND;
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT; MLX5_FLOW_CONTEXT_ACTION_CRYPTO_DECRYPT |
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; MLX5_FLOW_CONTEXT_ACTION_COUNT;
dest.ft = rx->ft.status; dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
rule = mlx5_add_flow_rules(rx->ft.sa, spec, &flow_act, &dest, 1); dest[0].ft = rx->ft.status;
dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
dest[1].counter_id = mlx5_fc_id(counter);
rule = mlx5_add_flow_rules(rx->ft.sa, spec, &flow_act, dest, 2);
if (IS_ERR(rule)) { if (IS_ERR(rule)) {
err = PTR_ERR(rule); err = PTR_ERR(rule);
mlx5_core_err(mdev, "fail to add RX ipsec rule err=%d\n", err); mlx5_core_err(mdev, "fail to add RX ipsec rule err=%d\n", err);
...@@ -934,10 +943,13 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -934,10 +943,13 @@ static int rx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
sa_entry->ipsec_rule.rule = rule; sa_entry->ipsec_rule.rule = rule;
sa_entry->ipsec_rule.modify_hdr = flow_act.modify_hdr; sa_entry->ipsec_rule.modify_hdr = flow_act.modify_hdr;
sa_entry->ipsec_rule.fc = counter;
sa_entry->ipsec_rule.pkt_reformat = flow_act.pkt_reformat; sa_entry->ipsec_rule.pkt_reformat = flow_act.pkt_reformat;
return 0; return 0;
err_add_flow: err_add_flow:
mlx5_fc_destroy(mdev, counter);
err_add_cnt:
if (flow_act.pkt_reformat) if (flow_act.pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, flow_act.pkt_reformat); mlx5_packet_reformat_dealloc(mdev, flow_act.pkt_reformat);
err_pkt_reformat: err_pkt_reformat:
...@@ -954,11 +966,12 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -954,11 +966,12 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs; struct mlx5_accel_esp_xfrm_attrs *attrs = &sa_entry->attrs;
struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry); struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry);
struct mlx5e_ipsec *ipsec = sa_entry->ipsec; struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
struct mlx5_flow_destination dest = {}; struct mlx5_flow_destination dest[2];
struct mlx5_flow_act flow_act = {}; struct mlx5_flow_act flow_act = {};
struct mlx5_flow_handle *rule; struct mlx5_flow_handle *rule;
struct mlx5_flow_spec *spec; struct mlx5_flow_spec *spec;
struct mlx5e_ipsec_tx *tx; struct mlx5e_ipsec_tx *tx;
struct mlx5_fc *counter;
int err; int err;
tx = tx_ft_get(mdev, ipsec); tx = tx_ft_get(mdev, ipsec);
...@@ -996,15 +1009,23 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -996,15 +1009,23 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
break; break;
} }
counter = mlx5_fc_create(mdev, true);
if (IS_ERR(counter)) {
err = PTR_ERR(counter);
goto err_add_cnt;
}
flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_IPSEC; flow_act.crypto.type = MLX5_FLOW_CONTEXT_ENCRYPT_DECRYPT_TYPE_IPSEC;
flow_act.crypto.obj_id = sa_entry->ipsec_obj_id; flow_act.crypto.obj_id = sa_entry->ipsec_obj_id;
flow_act.flags |= FLOW_ACT_NO_APPEND; flow_act.flags |= FLOW_ACT_NO_APPEND;
flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT | MLX5_FLOW_CONTEXT_ACTION_CRYPTO_ENCRYPT |
MLX5_FLOW_CONTEXT_ACTION_COUNT; MLX5_FLOW_CONTEXT_ACTION_COUNT;
dest.ft = tx->ft.status; dest[0].ft = tx->ft.status;
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; dest[0].type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
rule = mlx5_add_flow_rules(tx->ft.sa, spec, &flow_act, &dest, 1); dest[1].type = MLX5_FLOW_DESTINATION_TYPE_COUNTER;
dest[1].counter_id = mlx5_fc_id(counter);
rule = mlx5_add_flow_rules(tx->ft.sa, spec, &flow_act, dest, 2);
if (IS_ERR(rule)) { if (IS_ERR(rule)) {
err = PTR_ERR(rule); err = PTR_ERR(rule);
mlx5_core_err(mdev, "fail to add TX ipsec rule err=%d\n", err); mlx5_core_err(mdev, "fail to add TX ipsec rule err=%d\n", err);
...@@ -1013,10 +1034,13 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -1013,10 +1034,13 @@ static int tx_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
kvfree(spec); kvfree(spec);
sa_entry->ipsec_rule.rule = rule; sa_entry->ipsec_rule.rule = rule;
sa_entry->ipsec_rule.fc = counter;
sa_entry->ipsec_rule.pkt_reformat = flow_act.pkt_reformat; sa_entry->ipsec_rule.pkt_reformat = flow_act.pkt_reformat;
return 0; return 0;
err_add_flow: err_add_flow:
mlx5_fc_destroy(mdev, counter);
err_add_cnt:
if (flow_act.pkt_reformat) if (flow_act.pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, flow_act.pkt_reformat); mlx5_packet_reformat_dealloc(mdev, flow_act.pkt_reformat);
err_pkt_reformat: err_pkt_reformat:
...@@ -1299,7 +1323,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry) ...@@ -1299,7 +1323,7 @@ void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry)
struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry); struct mlx5_core_dev *mdev = mlx5e_ipsec_sa2dev(sa_entry);
mlx5_del_flow_rules(ipsec_rule->rule); mlx5_del_flow_rules(ipsec_rule->rule);
mlx5_fc_destroy(mdev, ipsec_rule->fc);
if (ipsec_rule->pkt_reformat) if (ipsec_rule->pkt_reformat)
mlx5_packet_reformat_dealloc(mdev, ipsec_rule->pkt_reformat); mlx5_packet_reformat_dealloc(mdev, ipsec_rule->pkt_reformat);
......
...@@ -489,18 +489,3 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, ...@@ -489,18 +489,3 @@ int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry,
spin_unlock_bh(&aso->lock); spin_unlock_bh(&aso->lock);
return ret; return ret;
} }
void mlx5e_ipsec_aso_update_curlft(struct mlx5e_ipsec_sa_entry *sa_entry,
u64 *packets)
{
struct mlx5e_ipsec *ipsec = sa_entry->ipsec;
struct mlx5e_ipsec_aso *aso = ipsec->aso;
u64 hard_cnt;
hard_cnt = MLX5_GET(ipsec_aso, aso->ctx, remove_flow_pkt_cnt);
/* HW decresases the limit till it reaches zero to fire an avent.
* We need to fix the calculations, so the returned count is a total
* number of passed packets and not how much left.
*/
*packets = sa_entry->attrs.hard_packet_limit - hard_cnt;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment