Skip to content

Commit cc628c9

Browse files
committed
Merge tag 'mlx5e-failsafe' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux
Saeed Mahameed says: ==================== mlx5e-failsafe 27-03-2017 This series provides a fail-safe mechanism to allow safely re-configuring mlx5e netdevice and provides a resiliency against sporadic configuration failures. To enable this we do some refactoring and code reorganizing to allow breaking the drivers open/close flows to stages: open -> activate -> deactivate -> close. In addition we need to allow creating fresh HW ring resources (mlx5e_channels) with their own "new" set of parameters, while keeping the current ones running and active until the new channels are successfully created with the new configuration, and only then we can safly replace (switch) old channels with new ones. For that we introduce mlx5e_channels object and an API to manage it: - channels = open_channels(new_params): open fresh TX/RX channels - activate_channels(channels): redirect traffic to them and attach them to the netdev - deactivate_channes(channels) stop traffic and detach from netdev - close(channels) Free the TX/RX HW resources of those channels With the above strategy it is straightforward to achieve the desired behavior of fail-safe configuration. In pseudo code: make_new_config(new_params) { old_channels = current_active_channels; new_channels = create_channels(new_params); if (!new_channels) return "Failed, but current channels are still active :)" deactivate_channels(old_channels); /* Can't fail */ set_hw_new_state(); /* If needed */ activate_channels(new_channels); /* Can't fail */ close_channels(old_channels); current_active_channels = new_channels; return "SUCCESS"; } At the top of this series, we change the following flows to be fail-safe: ethtool: - ring parameters - coalesce parameters - tx copy break parameters - cqe compressing/moderation mode setting (priv flags) ndos: - tc setup - set features: LRO - change mtu ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 95ed0ed + 2e20a15 commit cc628c9

File tree

12 files changed

+984
-789
lines changed

12 files changed

+984
-789
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en.h

Lines changed: 69 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -182,15 +182,15 @@ enum mlx5e_priv_flag {
182182
MLX5E_PFLAG_RX_CQE_COMPRESS = (1 << 1),
183183
};
184184

185-
#define MLX5E_SET_PFLAG(priv, pflag, enable) \
185+
#define MLX5E_SET_PFLAG(params, pflag, enable) \
186186
do { \
187187
if (enable) \
188-
(priv)->params.pflags |= (pflag); \
188+
(params)->pflags |= (pflag); \
189189
else \
190-
(priv)->params.pflags &= ~(pflag); \
190+
(params)->pflags &= ~(pflag); \
191191
} while (0)
192192

193-
#define MLX5E_GET_PFLAG(priv, pflag) (!!((priv)->params.pflags & (pflag)))
193+
#define MLX5E_GET_PFLAG(params, pflag) (!!((params)->pflags & (pflag)))
194194

195195
#ifdef CONFIG_MLX5_CORE_EN_DCB
196196
#define MLX5E_MAX_BW_ALLOC 100 /* Max percentage of BW allocation */
@@ -213,7 +213,6 @@ struct mlx5e_params {
213213
bool rx_cqe_compress_def;
214214
struct mlx5e_cq_moder rx_cq_moderation;
215215
struct mlx5e_cq_moder tx_cq_moderation;
216-
u16 min_rx_wqes;
217216
bool lro_en;
218217
u32 lro_wqe_sz;
219218
u16 tx_max_inline;
@@ -225,6 +224,7 @@ struct mlx5e_params {
225224
bool rx_am_enabled;
226225
u32 lro_timeout;
227226
u32 pflags;
227+
struct bpf_prog *xdp_prog;
228228
};
229229

230230
#ifdef CONFIG_MLX5_CORE_EN_DCB
@@ -280,7 +280,6 @@ struct mlx5e_cq {
280280
struct napi_struct *napi;
281281
struct mlx5_core_cq mcq;
282282
struct mlx5e_channel *channel;
283-
struct mlx5e_priv *priv;
284283

285284
/* cqe decompression */
286285
struct mlx5_cqe64 title;
@@ -290,6 +289,7 @@ struct mlx5e_cq {
290289
u16 decmprs_wqe_counter;
291290

292291
/* control */
292+
struct mlx5_core_dev *mdev;
293293
struct mlx5_frag_wq_ctrl wq_ctrl;
294294
} ____cacheline_aligned_in_smp;
295295

@@ -357,7 +357,7 @@ struct mlx5e_txqsq {
357357
/* control path */
358358
struct mlx5_wq_ctrl wq_ctrl;
359359
struct mlx5e_channel *channel;
360-
int tc;
360+
int txq_ix;
361361
u32 rate_limit;
362362
} ____cacheline_aligned_in_smp;
363363

@@ -533,7 +533,7 @@ struct mlx5e_rq {
533533
u32 mpwqe_num_strides;
534534
u32 rqn;
535535
struct mlx5e_channel *channel;
536-
struct mlx5e_priv *priv;
536+
struct mlx5_core_dev *mdev;
537537
struct mlx5_core_mkey umr_mkey;
538538
} ____cacheline_aligned_in_smp;
539539

@@ -556,10 +556,18 @@ struct mlx5e_channel {
556556

557557
/* control */
558558
struct mlx5e_priv *priv;
559+
struct mlx5_core_dev *mdev;
560+
struct mlx5e_tstamp *tstamp;
559561
int ix;
560562
int cpu;
561563
};
562564

565+
struct mlx5e_channels {
566+
struct mlx5e_channel **c;
567+
unsigned int num;
568+
struct mlx5e_params params;
569+
};
570+
563571
enum mlx5e_traffic_types {
564572
MLX5E_TT_IPV4_TCP,
565573
MLX5E_TT_IPV6_TCP,
@@ -709,34 +717,17 @@ enum {
709717
MLX5E_NIC_PRIO
710718
};
711719

712-
struct mlx5e_profile {
713-
void (*init)(struct mlx5_core_dev *mdev,
714-
struct net_device *netdev,
715-
const struct mlx5e_profile *profile, void *ppriv);
716-
void (*cleanup)(struct mlx5e_priv *priv);
717-
int (*init_rx)(struct mlx5e_priv *priv);
718-
void (*cleanup_rx)(struct mlx5e_priv *priv);
719-
int (*init_tx)(struct mlx5e_priv *priv);
720-
void (*cleanup_tx)(struct mlx5e_priv *priv);
721-
void (*enable)(struct mlx5e_priv *priv);
722-
void (*disable)(struct mlx5e_priv *priv);
723-
void (*update_stats)(struct mlx5e_priv *priv);
724-
int (*max_nch)(struct mlx5_core_dev *mdev);
725-
int max_tc;
726-
};
727-
728720
struct mlx5e_priv {
729721
/* priv data path fields - start */
730-
struct mlx5e_txqsq **txq_to_sq_map;
731-
int channeltc_to_txq_map[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
732-
struct bpf_prog *xdp_prog;
722+
struct mlx5e_txqsq *txq2sq[MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC];
723+
int channel_tc2txq[MLX5E_MAX_NUM_CHANNELS][MLX5E_MAX_NUM_TC];
733724
/* priv data path fields - end */
734725

735726
unsigned long state;
736727
struct mutex state_lock; /* Protects Interface state */
737728
struct mlx5e_rq drop_rq;
738729

739-
struct mlx5e_channel **channel;
730+
struct mlx5e_channels channels;
740731
u32 tisn[MLX5E_MAX_NUM_TC];
741732
struct mlx5e_rqt indir_rqt;
742733
struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
@@ -746,7 +737,6 @@ struct mlx5e_priv {
746737
struct mlx5e_flow_steering fs;
747738
struct mlx5e_vxlan_db vxlan;
748739

749-
struct mlx5e_params params;
750740
struct workqueue_struct *wq;
751741
struct work_struct update_carrier_work;
752742
struct work_struct set_rx_mode_work;
@@ -766,6 +756,22 @@ struct mlx5e_priv {
766756
void *ppriv;
767757
};
768758

759+
struct mlx5e_profile {
760+
void (*init)(struct mlx5_core_dev *mdev,
761+
struct net_device *netdev,
762+
const struct mlx5e_profile *profile, void *ppriv);
763+
void (*cleanup)(struct mlx5e_priv *priv);
764+
int (*init_rx)(struct mlx5e_priv *priv);
765+
void (*cleanup_rx)(struct mlx5e_priv *priv);
766+
int (*init_tx)(struct mlx5e_priv *priv);
767+
void (*cleanup_tx)(struct mlx5e_priv *priv);
768+
void (*enable)(struct mlx5e_priv *priv);
769+
void (*disable)(struct mlx5e_priv *priv);
770+
void (*update_stats)(struct mlx5e_priv *priv);
771+
int (*max_nch)(struct mlx5_core_dev *mdev);
772+
int max_tc;
773+
};
774+
769775
void mlx5e_build_ptys2ethtool_map(void);
770776

771777
u16 mlx5e_select_queue(struct net_device *dev, struct sk_buff *skb,
@@ -827,7 +833,7 @@ void mlx5e_pps_event_handler(struct mlx5e_priv *priv,
827833
struct ptp_clock_event *event);
828834
int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr);
829835
int mlx5e_hwstamp_get(struct net_device *dev, struct ifreq *ifr);
830-
void mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val);
836+
int mlx5e_modify_rx_cqe_compression_locked(struct mlx5e_priv *priv, bool val);
831837

832838
int mlx5e_vlan_rx_add_vid(struct net_device *dev, __always_unused __be16 proto,
833839
u16 vid);
@@ -836,22 +842,49 @@ int mlx5e_vlan_rx_kill_vid(struct net_device *dev, __always_unused __be16 proto,
836842
void mlx5e_enable_vlan_filter(struct mlx5e_priv *priv);
837843
void mlx5e_disable_vlan_filter(struct mlx5e_priv *priv);
838844

839-
int mlx5e_modify_rqs_vsd(struct mlx5e_priv *priv, bool vsd);
845+
int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd);
846+
847+
struct mlx5e_redirect_rqt_param {
848+
bool is_rss;
849+
union {
850+
u32 rqn; /* Direct RQN (Non-RSS) */
851+
struct {
852+
u8 hfunc;
853+
struct mlx5e_channels *channels;
854+
} rss; /* RSS data */
855+
};
856+
};
840857

841-
int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz, int ix);
842-
void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_priv *priv, void *tirc,
843-
enum mlx5e_traffic_types tt);
858+
int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz,
859+
struct mlx5e_redirect_rqt_param rrp);
860+
void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_params *params,
861+
enum mlx5e_traffic_types tt,
862+
void *tirc);
844863

845864
int mlx5e_open_locked(struct net_device *netdev);
846865
int mlx5e_close_locked(struct net_device *netdev);
866+
867+
int mlx5e_open_channels(struct mlx5e_priv *priv,
868+
struct mlx5e_channels *chs);
869+
void mlx5e_close_channels(struct mlx5e_channels *chs);
870+
871+
/* Function pointer to be used to modify WH settings while
872+
* switching channels
873+
*/
874+
typedef int (*mlx5e_fp_hw_modify)(struct mlx5e_priv *priv);
875+
void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
876+
struct mlx5e_channels *new_chs,
877+
mlx5e_fp_hw_modify hw_modify);
878+
847879
void mlx5e_build_default_indir_rqt(struct mlx5_core_dev *mdev,
848880
u32 *indirection_rqt, int len,
849881
int num_channels);
850882
int mlx5e_get_max_linkspeed(struct mlx5_core_dev *mdev, u32 *speed);
851883

852884
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
853885
u8 cq_period_mode);
854-
void mlx5e_set_rq_type_params(struct mlx5e_priv *priv, u8 rq_type);
886+
void mlx5e_set_rq_type_params(struct mlx5_core_dev *mdev,
887+
struct mlx5e_params *params, u8 rq_type);
855888

856889
static inline
857890
struct mlx5e_tx_wqe *mlx5e_post_nop(struct mlx5_wq_cyc *wq, u32 sqn, u16 *pc)
@@ -942,8 +975,7 @@ void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
942975
struct mlx5e_tir *tir);
943976
int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev);
944977
void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev);
945-
int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev,
946-
bool enable_uc_lb);
978+
int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb);
947979

948980
struct mlx5_eswitch_rep;
949981
int mlx5e_vport_rep_load(struct mlx5_eswitch *esw,

drivers/net/ethernet/mellanox/mlx5/core/en_clock.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
9090
{
9191
struct mlx5e_priv *priv = netdev_priv(dev);
9292
struct hwtstamp_config config;
93+
int err;
9394

9495
if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz))
9596
return -EOPNOTSUPP;
@@ -111,7 +112,7 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
111112
switch (config.rx_filter) {
112113
case HWTSTAMP_FILTER_NONE:
113114
/* Reset CQE compression to Admin default */
114-
mlx5e_modify_rx_cqe_compression_locked(priv, priv->params.rx_cqe_compress_def);
115+
mlx5e_modify_rx_cqe_compression_locked(priv, priv->channels.params.rx_cqe_compress_def);
115116
break;
116117
case HWTSTAMP_FILTER_ALL:
117118
case HWTSTAMP_FILTER_SOME:
@@ -129,7 +130,12 @@ int mlx5e_hwstamp_set(struct net_device *dev, struct ifreq *ifr)
129130
case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
130131
/* Disable CQE compression */
131132
netdev_warn(dev, "Disabling cqe compression");
132-
mlx5e_modify_rx_cqe_compression_locked(priv, false);
133+
err = mlx5e_modify_rx_cqe_compression_locked(priv, false);
134+
if (err) {
135+
netdev_err(dev, "Failed disabling cqe compression err=%d\n", err);
136+
mutex_unlock(&priv->state_lock);
137+
return err;
138+
}
133139
config.rx_filter = HWTSTAMP_FILTER_ALL;
134140
break;
135141
default:

drivers/net/ethernet/mellanox/mlx5/core/en_common.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,20 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
136136
mlx5_core_dealloc_pd(mdev, res->pdn);
137137
}
138138

139-
int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev,
140-
bool enable_uc_lb)
139+
int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
141140
{
141+
struct mlx5_core_dev *mdev = priv->mdev;
142142
struct mlx5e_tir *tir;
143-
void *in;
143+
int err = -ENOMEM;
144+
u32 tirn = 0;
144145
int inlen;
145-
int err = 0;
146+
void *in;
147+
146148

147149
inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
148150
in = mlx5_vzalloc(inlen);
149151
if (!in)
150-
return -ENOMEM;
152+
goto out;
151153

152154
if (enable_uc_lb)
153155
MLX5_SET(modify_tir_in, in, ctx.self_lb_block,
@@ -156,13 +158,16 @@ int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev,
156158
MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
157159

158160
list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) {
159-
err = mlx5_core_modify_tir(mdev, tir->tirn, in, inlen);
161+
tirn = tir->tirn;
162+
err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
160163
if (err)
161164
goto out;
162165
}
163166

164167
out:
165168
kvfree(in);
169+
if (err)
170+
netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err);
166171

167172
return err;
168173
}

0 commit comments

Comments
 (0)