Skip to content

Commit 26bf309

Browse files
Tariq ToukanSaeed Mahameed
authored andcommitted
net/mlx5: Use order-0 allocations for EQs
Currently we are allocating high-order page for EQs. In case of fragmented system, VF hot remove/add in VMs for example, there isn't enough contiguous memory for EQs allocation, which results in crashing of the VM. Therefore, use order-0 fragments for the EQ allocations instead. Performance tests: ConnectX-5 100Gbps, CPU: Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz Performance tests show no sensible degradation. Signed-off-by: Tariq Toukan <[email protected]> Signed-off-by: Shay Drory <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent c3e666f commit 26bf309

File tree

5 files changed

+32
-22
lines changed

5 files changed

+32
-22
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en/health.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ int mlx5e_health_eq_diag_fmsg(struct mlx5_eq_comp *eq, struct devlink_fmsg *fmsg
128128
if (err)
129129
return err;
130130

131-
err = devlink_fmsg_u32_pair_put(fmsg, "size", eq->core.nent);
131+
err = devlink_fmsg_u32_pair_put(fmsg, "size", eq_get_size(&eq->core));
132132
if (err)
133133
return err;
134134

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static void init_eq_buf(struct mlx5_eq *eq)
271271
struct mlx5_eqe *eqe;
272272
int i;
273273

274-
for (i = 0; i < eq->nent; i++) {
274+
for (i = 0; i < eq_get_size(eq); i++) {
275275
eqe = get_eqe(eq, i);
276276
eqe->owner = MLX5_EQE_OWNER_INIT_VAL;
277277
}
@@ -281,8 +281,10 @@ static int
281281
create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
282282
struct mlx5_eq_param *param)
283283
{
284+
u8 log_eq_size = order_base_2(param->nent + MLX5_NUM_SPARE_EQE);
284285
struct mlx5_cq_table *cq_table = &eq->cq_table;
285286
u32 out[MLX5_ST_SZ_DW(create_eq_out)] = {0};
287+
u8 log_eq_stride = ilog2(MLX5_EQE_SIZE);
286288
struct mlx5_priv *priv = &dev->priv;
287289
u8 vecidx = param->irq_index;
288290
__be64 *pas;
@@ -297,16 +299,18 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
297299
spin_lock_init(&cq_table->lock);
298300
INIT_RADIX_TREE(&cq_table->tree, GFP_ATOMIC);
299301

300-
eq->nent = roundup_pow_of_two(param->nent + MLX5_NUM_SPARE_EQE);
301302
eq->cons_index = 0;
302-
err = mlx5_buf_alloc(dev, eq->nent * MLX5_EQE_SIZE, &eq->buf);
303+
304+
err = mlx5_frag_buf_alloc_node(dev, wq_get_byte_sz(log_eq_size, log_eq_stride),
305+
&eq->frag_buf, dev->priv.numa_node);
303306
if (err)
304307
return err;
305308

309+
mlx5_init_fbc(eq->frag_buf.frags, log_eq_stride, log_eq_size, &eq->fbc);
306310
init_eq_buf(eq);
307311

308312
inlen = MLX5_ST_SZ_BYTES(create_eq_in) +
309-
MLX5_FLD_SZ_BYTES(create_eq_in, pas[0]) * eq->buf.npages;
313+
MLX5_FLD_SZ_BYTES(create_eq_in, pas[0]) * eq->frag_buf.npages;
310314

311315
in = kvzalloc(inlen, GFP_KERNEL);
312316
if (!in) {
@@ -315,7 +319,7 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
315319
}
316320

317321
pas = (__be64 *)MLX5_ADDR_OF(create_eq_in, in, pas);
318-
mlx5_fill_page_array(&eq->buf, pas);
322+
mlx5_fill_page_frag_array(&eq->frag_buf, pas);
319323

320324
MLX5_SET(create_eq_in, in, opcode, MLX5_CMD_OP_CREATE_EQ);
321325
if (!param->mask[0] && MLX5_CAP_GEN(dev, log_max_uctx))
@@ -326,11 +330,11 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
326330
param->mask[i]);
327331

328332
eqc = MLX5_ADDR_OF(create_eq_in, in, eq_context_entry);
329-
MLX5_SET(eqc, eqc, log_eq_size, ilog2(eq->nent));
333+
MLX5_SET(eqc, eqc, log_eq_size, eq->fbc.log_sz);
330334
MLX5_SET(eqc, eqc, uar_page, priv->uar->index);
331335
MLX5_SET(eqc, eqc, intr, vecidx);
332336
MLX5_SET(eqc, eqc, log_page_size,
333-
eq->buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
337+
eq->frag_buf.page_shift - MLX5_ADAPTER_PAGE_SHIFT);
334338

335339
err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
336340
if (err)
@@ -356,7 +360,7 @@ create_map_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq,
356360
kvfree(in);
357361

358362
err_buf:
359-
mlx5_buf_free(dev, &eq->buf);
363+
mlx5_frag_buf_free(dev, &eq->frag_buf);
360364
return err;
361365
}
362366

@@ -413,7 +417,7 @@ static int destroy_unmap_eq(struct mlx5_core_dev *dev, struct mlx5_eq *eq)
413417
eq->eqn);
414418
synchronize_irq(eq->irqn);
415419

416-
mlx5_buf_free(dev, &eq->buf);
420+
mlx5_frag_buf_free(dev, &eq->frag_buf);
417421

418422
return err;
419423
}
@@ -764,10 +768,11 @@ EXPORT_SYMBOL(mlx5_eq_destroy_generic);
764768
struct mlx5_eqe *mlx5_eq_get_eqe(struct mlx5_eq *eq, u32 cc)
765769
{
766770
u32 ci = eq->cons_index + cc;
771+
u32 nent = eq_get_size(eq);
767772
struct mlx5_eqe *eqe;
768773

769-
eqe = get_eqe(eq, ci & (eq->nent - 1));
770-
eqe = ((eqe->owner & 1) ^ !!(ci & eq->nent)) ? NULL : eqe;
774+
eqe = get_eqe(eq, ci & (nent - 1));
775+
eqe = ((eqe->owner & 1) ^ !!(ci & nent)) ? NULL : eqe;
771776
/* Make sure we read EQ entry contents after we've
772777
* checked the ownership bit.
773778
*/

drivers/net/ethernet/mellanox/mlx5/core/lib/eq.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ struct mlx5_cq_table {
2222
};
2323

2424
struct mlx5_eq {
25+
struct mlx5_frag_buf_ctrl fbc;
26+
struct mlx5_frag_buf frag_buf;
2527
struct mlx5_core_dev *dev;
2628
struct mlx5_cq_table cq_table;
2729
__be32 __iomem *doorbell;
2830
u32 cons_index;
29-
struct mlx5_frag_buf buf;
3031
unsigned int vecidx;
3132
unsigned int irqn;
3233
u8 eqn;
33-
int nent;
3434
struct mlx5_rsc_debug *dbg;
3535
};
3636

@@ -47,16 +47,21 @@ struct mlx5_eq_comp {
4747
struct list_head list;
4848
};
4949

50+
static inline u32 eq_get_size(struct mlx5_eq *eq)
51+
{
52+
return eq->fbc.sz_m1 + 1;
53+
}
54+
5055
static inline struct mlx5_eqe *get_eqe(struct mlx5_eq *eq, u32 entry)
5156
{
52-
return mlx5_buf_offset(&eq->buf, entry * MLX5_EQE_SIZE);
57+
return mlx5_frag_buf_get_wqe(&eq->fbc, entry);
5358
}
5459

5560
static inline struct mlx5_eqe *next_eqe_sw(struct mlx5_eq *eq)
5661
{
57-
struct mlx5_eqe *eqe = get_eqe(eq, eq->cons_index & (eq->nent - 1));
62+
struct mlx5_eqe *eqe = get_eqe(eq, eq->cons_index & eq->fbc.sz_m1);
5863

59-
return ((eqe->owner & 1) ^ !!(eq->cons_index & eq->nent)) ? NULL : eqe;
64+
return (eqe->owner ^ (eq->cons_index >> eq->fbc.log_sz)) & 1 ? NULL : eqe;
6065
}
6166

6267
static inline void eq_update_ci(struct mlx5_eq *eq, int arm)

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

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,6 @@
3434
#include "wq.h"
3535
#include "mlx5_core.h"
3636

37-
static u32 wq_get_byte_sz(u8 log_sz, u8 log_stride)
38-
{
39-
return ((u32)1 << log_sz) << log_stride;
40-
}
41-
4237
int mlx5_wq_cyc_create(struct mlx5_core_dev *mdev, struct mlx5_wq_param *param,
4338
void *wqc, struct mlx5_wq_cyc *wq,
4439
struct mlx5_wq_ctrl *wq_ctrl)

include/linux/mlx5/driver.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,11 @@ static inline u32 mlx5_base_mkey(const u32 key)
873873
return key & 0xffffff00u;
874874
}
875875

876+
static inline u32 wq_get_byte_sz(u8 log_sz, u8 log_stride)
877+
{
878+
return ((u32)1 << log_sz) << log_stride;
879+
}
880+
876881
static inline void mlx5_init_fbc_offset(struct mlx5_buf_list *frags,
877882
u8 log_stride, u8 log_sz,
878883
u16 strides_offset,

0 commit comments

Comments
 (0)