Skip to content

Commit

Permalink
Merge tag 'mlx5-updates-2021-04-16' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2021-04-16

This patchset introduces updates to mlx5e netdev driver.

1) Tariq refactors TLS offloads and adds resiliency against RX resync
   failures

2) Maxim reduces code duplications by unifying channels reset flow
   regardless if channels are closed or open

3) Aya Enhances TX/RX health reporters diagnostics to expose the
   internal clock time-stamping format

4) Moshe adds support for ethtool extended link state, to show the reason
   for link down
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Apr 16, 2021
2 parents 70c1837 + 95742c1 commit 03e481e
Show file tree
Hide file tree
Showing 23 changed files with 621 additions and 344 deletions.
13 changes: 8 additions & 5 deletions drivers/net/ethernet/mellanox/mlx5/core/en.h
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,9 @@ enum {
MLX5E_SQ_STATE_RECOVERING,
MLX5E_SQ_STATE_IPSEC,
MLX5E_SQ_STATE_AM,
MLX5E_SQ_STATE_TLS,
MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE,
MLX5E_SQ_STATE_PENDING_XSK_TX,
MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC,
};

struct mlx5e_tx_mpwqe {
Expand Down Expand Up @@ -500,6 +500,8 @@ struct mlx5e_xdpsq {
struct mlx5e_channel *channel;
} ____cacheline_aligned_in_smp;

struct mlx5e_ktls_resync_resp;

struct mlx5e_icosq {
/* data path */
u16 cc;
Expand All @@ -519,6 +521,7 @@ struct mlx5e_icosq {
u32 sqn;
u16 reserved_room;
unsigned long state;
struct mlx5e_ktls_resync_resp *ktls_resync;

/* control path */
struct mlx5_wq_ctrl wq_ctrl;
Expand Down Expand Up @@ -1015,10 +1018,10 @@ int fn##_ctx(struct mlx5e_priv *priv, void *context) \
return fn(priv); \
}
int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv);
int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
struct mlx5e_channels *new_chs,
mlx5e_fp_preactivate preactivate,
void *context);
int mlx5e_safe_switch_params(struct mlx5e_priv *priv,
struct mlx5e_params *new_params,
mlx5e_fp_preactivate preactivate,
void *context, bool reset);
int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv);
int mlx5e_num_channels_changed(struct mlx5e_priv *priv);
int mlx5e_num_channels_changed_ctx(struct mlx5e_priv *priv, void *context);
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/params.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,9 @@ static void mlx5e_build_async_icosq_param(struct mlx5_core_dev *mdev,

mlx5e_build_sq_param_common(mdev, param);
param->stop_room = mlx5e_stop_room_for_wqe(1); /* for XSK NOP */
param->is_tls = mlx5_accel_is_ktls_rx(mdev);
if (param->is_tls)
param->stop_room += mlx5e_stop_room_for_wqe(1); /* for TLS RX resync NOP */
MLX5_SET(sqc, sqc, reg_umr, MLX5_CAP_ETH(mdev, reg_umr_sq));
MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
mlx5e_build_ico_cq_param(mdev, log_wq_size, &param->cqp);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ struct mlx5e_sq_param {
u32 sqc[MLX5_ST_SZ_DW(sqc)];
struct mlx5_wq_param wq;
bool is_mpw;
bool is_tls;
u16 stop_room;
};

Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -792,6 +792,9 @@ int mlx5e_ptp_rx_manage_fs(struct mlx5e_priv *priv, bool set)
if (!priv->profile->rx_ptp_support)
return 0;

if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
return 0;

if (set) {
if (!c || !test_bit(MLX5E_PTP_STATE_RX, c->state)) {
netdev_WARN_ONCE(priv->netdev, "Don't try to add PTP RX-FS rules");
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/reporter_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,10 +323,12 @@ static int mlx5e_rx_reporter_diagnose_generic_rq(struct mlx5e_rq *rq,
struct mlx5e_priv *priv = rq->priv;
struct mlx5e_params *params;
u32 rq_stride, rq_sz;
bool real_time;
int err;

params = &priv->channels.params;
rq_sz = mlx5e_rqwq_get_size(rq);
real_time = mlx5_is_real_time_rq(priv->mdev);
rq_stride = BIT(mlx5e_mpwqe_get_log_stride_size(priv->mdev, params, NULL));

err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "RQ");
Expand All @@ -345,6 +347,10 @@ static int mlx5e_rx_reporter_diagnose_generic_rq(struct mlx5e_rq *rq,
if (err)
return err;

err = devlink_fmsg_string_pair_put(fmsg, "ts_format", real_time ? "RT" : "FRC");
if (err)
return err;

err = mlx5e_health_cq_common_diag_fmsg(&rq->cq, fmsg);
if (err)
return err;
Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en/reporter_tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,14 @@ mlx5e_tx_reporter_diagnose_generic_txqsq(struct devlink_fmsg *fmsg,
struct mlx5e_txqsq *txqsq)
{
u32 sq_stride, sq_sz;
bool real_time;
int err;

err = mlx5e_health_fmsg_named_obj_nest_start(fmsg, "SQ");
if (err)
return err;

real_time = mlx5_is_real_time_sq(txqsq->mdev);
sq_sz = mlx5_wq_cyc_get_size(&txqsq->wq);
sq_stride = MLX5_SEND_WQE_BB;

Expand All @@ -274,6 +276,10 @@ mlx5e_tx_reporter_diagnose_generic_txqsq(struct devlink_fmsg *fmsg,
if (err)
return err;

err = devlink_fmsg_string_pair_put(fmsg, "ts_format", real_time ? "RT" : "FRC");
if (err)
return err;

err = mlx5e_health_cq_common_diag_fmsg(&txqsq->cq, fmsg);
if (err)
return err;
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/en_accel.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,11 +123,10 @@ static inline bool mlx5e_accel_tx_begin(struct net_device *dev,
mlx5e_udp_gso_handle_tx_skb(skb);

#ifdef CONFIG_MLX5_EN_TLS
if (test_bit(MLX5E_SQ_STATE_TLS, &sq->state)) {
/* May send SKBs and WQEs. */
/* May send SKBs and WQEs. */
if (mlx5e_tls_skb_offloaded(skb))
if (unlikely(!mlx5e_tls_handle_tx_skb(dev, sq, skb, &state->tls)))
return false;
}
#endif

#ifdef CONFIG_MLX5_EN_IPSEC
Expand Down Expand Up @@ -186,7 +185,7 @@ static inline void mlx5e_accel_tx_finish(struct mlx5e_txqsq *sq,
struct mlx5_wqe_inline_seg *inlseg)
{
#ifdef CONFIG_MLX5_EN_TLS
mlx5e_tls_handle_tx_wqe(sq, &wqe->ctrl, &state->tls);
mlx5e_tls_handle_tx_wqe(&wqe->ctrl, &state->tls);
#endif

#ifdef CONFIG_MLX5_EN_IPSEC
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv);
int mlx5e_ktls_init_rx(struct mlx5e_priv *priv);
void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv);
int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable);
struct mlx5e_ktls_resync_resp *
mlx5e_ktls_rx_resync_create_resp_list(void);
void mlx5e_ktls_rx_resync_destroy_resp_list(struct mlx5e_ktls_resync_resp *resp_list);
#else

static inline void mlx5e_ktls_build_netdev(struct mlx5e_priv *priv)
Expand All @@ -33,6 +36,14 @@ static inline int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enab
return -EOPNOTSUPP;
}

static inline struct mlx5e_ktls_resync_resp *
mlx5e_ktls_rx_resync_create_resp_list(void)
{
return ERR_PTR(-EOPNOTSUPP);
}

static inline void
mlx5e_ktls_rx_resync_destroy_resp_list(struct mlx5e_ktls_resync_resp *resp_list) {}
#endif

#endif /* __MLX5E_TLS_H__ */
129 changes: 108 additions & 21 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct mlx5e_ktls_offload_context_rx {

/* resync */
struct mlx5e_ktls_rx_resync_ctx resync;
struct list_head list;
};

static bool mlx5e_ktls_priv_rx_put(struct mlx5e_ktls_offload_context_rx *priv_rx)
Expand All @@ -72,6 +73,32 @@ static void mlx5e_ktls_priv_rx_get(struct mlx5e_ktls_offload_context_rx *priv_rx
refcount_inc(&priv_rx->resync.refcnt);
}

struct mlx5e_ktls_resync_resp {
/* protects list changes */
spinlock_t lock;
struct list_head list;
};

void mlx5e_ktls_rx_resync_destroy_resp_list(struct mlx5e_ktls_resync_resp *resp_list)
{
kvfree(resp_list);
}

struct mlx5e_ktls_resync_resp *
mlx5e_ktls_rx_resync_create_resp_list(void)
{
struct mlx5e_ktls_resync_resp *resp_list;

resp_list = kvzalloc(sizeof(*resp_list), GFP_KERNEL);
if (!resp_list)
return ERR_PTR(-ENOMEM);

INIT_LIST_HEAD(&resp_list->list);
spin_lock_init(&resp_list->lock);

return resp_list;
}

static int mlx5e_ktls_create_tir(struct mlx5_core_dev *mdev, u32 *tirn, u32 rqtn)
{
int err, inlen;
Expand Down Expand Up @@ -119,8 +146,7 @@ static void accel_rule_handle_work(struct work_struct *work)
complete(&priv_rx->add_ctx);
}

static void accel_rule_init(struct accel_rule *rule, struct mlx5e_priv *priv,
struct sock *sk)
static void accel_rule_init(struct accel_rule *rule, struct mlx5e_priv *priv)
{
INIT_WORK(&rule->work, accel_rule_handle_work);
rule->priv = priv;
Expand Down Expand Up @@ -359,33 +385,32 @@ static void resync_init(struct mlx5e_ktls_rx_resync_ctx *resync,
/* Function can be called with the refcount being either elevated or not.
* It does not affect the refcount.
*/
static int resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx,
struct mlx5e_channel *c)
static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_rx,
struct mlx5e_channel *c)
{
struct tls12_crypto_info_aes_gcm_128 *info = &priv_rx->crypto_info;
struct mlx5_wqe_ctrl_seg *cseg;
struct mlx5e_ktls_resync_resp *ktls_resync;
struct mlx5e_icosq *sq;
int err;
bool trigger_poll;

memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
err = 0;

sq = &c->async_icosq;
spin_lock_bh(&c->async_icosq_lock);
ktls_resync = sq->ktls_resync;

cseg = post_static_params(sq, priv_rx);
if (IS_ERR(cseg)) {
priv_rx->rq_stats->tls_resync_res_skip++;
err = PTR_ERR(cseg);
goto unlock;
}
/* Do not increment priv_rx refcnt, CQE handling is empty */
mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, cseg);
priv_rx->rq_stats->tls_resync_res_ok++;
unlock:
spin_unlock_bh(&c->async_icosq_lock);
spin_lock_bh(&ktls_resync->lock);
list_add_tail(&priv_rx->list, &ktls_resync->list);
trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
spin_unlock_bh(&ktls_resync->lock);

return err;
if (!trigger_poll)
return;

if (!napi_if_scheduled_mark_missed(&c->napi)) {
spin_lock_bh(&c->async_icosq_lock);
mlx5e_trigger_irq(sq);
spin_unlock_bh(&c->async_icosq_lock);
}
}

/* Function can be called with the refcount being either elevated or not.
Expand Down Expand Up @@ -618,7 +643,7 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,

init_completion(&priv_rx->add_ctx);

accel_rule_init(&priv_rx->rule, priv, sk);
accel_rule_init(&priv_rx->rule, priv);
resync = &priv_rx->resync;
resync_init(resync, priv);
tls_offload_ctx_rx(tls_ctx)->resync_async = &resync->core;
Expand Down Expand Up @@ -676,3 +701,65 @@ void mlx5e_ktls_del_rx(struct net_device *netdev, struct tls_context *tls_ctx)
*/
mlx5e_ktls_priv_rx_put(priv_rx);
}

bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget)
{
struct mlx5e_ktls_offload_context_rx *priv_rx, *tmp;
struct mlx5e_ktls_resync_resp *ktls_resync;
struct mlx5_wqe_ctrl_seg *db_cseg;
struct mlx5e_icosq *sq;
LIST_HEAD(local_list);
int i, j;

sq = &c->async_icosq;

if (unlikely(!test_bit(MLX5E_SQ_STATE_ENABLED, &sq->state)))
return false;

ktls_resync = sq->ktls_resync;
db_cseg = NULL;
i = 0;

spin_lock(&ktls_resync->lock);
list_for_each_entry_safe(priv_rx, tmp, &ktls_resync->list, list) {
list_move(&priv_rx->list, &local_list);
if (++i == budget)
break;
}
if (list_empty(&ktls_resync->list))
clear_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
spin_unlock(&ktls_resync->lock);

spin_lock(&c->async_icosq_lock);
for (j = 0; j < i; j++) {
struct mlx5_wqe_ctrl_seg *cseg;

priv_rx = list_first_entry(&local_list,
struct mlx5e_ktls_offload_context_rx,
list);
cseg = post_static_params(sq, priv_rx);
if (IS_ERR(cseg))
break;
list_del(&priv_rx->list);
db_cseg = cseg;
}
if (db_cseg)
mlx5e_notify_hw(&sq->wq, sq->pc, sq->uar_map, db_cseg);
spin_unlock(&c->async_icosq_lock);

priv_rx->rq_stats->tls_resync_res_ok += j;

if (!list_empty(&local_list)) {
/* This happens only if ICOSQ is full.
* There is no need to mark busy or explicitly ask for a NAPI cycle,
* it will be triggered by the outstanding ICOSQ completions.
*/
spin_lock(&ktls_resync->lock);
list_splice(&local_list, &ktls_resync->list);
set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
spin_unlock(&ktls_resync->lock);
priv_rx->rq_stats->tls_resync_res_retry++;
}

return i == budget;
}
20 changes: 20 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/en_accel/ktls_txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ mlx5e_ktls_tx_try_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
}
return false;
}

bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget);

static inline bool
mlx5e_ktls_rx_pending_resync_list(struct mlx5e_channel *c, int budget)
{
return budget && test_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &c->async_icosq.state);
}
#else
static inline bool
mlx5e_ktls_tx_try_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
Expand All @@ -49,6 +57,18 @@ mlx5e_ktls_tx_try_handle_resync_dump_comp(struct mlx5e_txqsq *sq,
return false;
}

static inline bool
mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget)
{
return false;
}

static inline bool
mlx5e_ktls_rx_pending_resync_list(struct mlx5e_channel *c, int budget)
{
return false;
}

#endif /* CONFIG_MLX5_EN_TLS */

#endif /* __MLX5E_TLS_TXRX_H__ */
Loading

0 comments on commit 03e481e

Please sign in to comment.