Skip to content

Commit c1be523

Browse files
Eli Cohenrolandd
authored andcommitted
IB/mlx5: Fix micro UAR allocator
The micro UAR (uuar) allocator had a bug which resulted from the fact that in each UAR we only have two micro UARs avaialable, those at index 0 and 1. This patch defines iterators to aid in traversing the list of available micro UARs when allocating a uuar. In addition, change the logic in create_user_qp() so that if high class allocation fails (high class means lower latency), we revert to medium class and not to the low class. Signed-off-by: Eli Cohen <[email protected]> Signed-off-by: Roland Dreier <[email protected]>
1 parent 24e4275 commit c1be523

File tree

3 files changed

+70
-27
lines changed

3 files changed

+70
-27
lines changed

drivers/infiniband/hw/mlx5/main.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
541541
struct mlx5_ib_ucontext *context;
542542
struct mlx5_uuar_info *uuari;
543543
struct mlx5_uar *uars;
544+
int gross_uuars;
544545
int num_uars;
545546
int uuarn;
546547
int err;
@@ -559,11 +560,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
559560
if (req.total_num_uuars == 0)
560561
return ERR_PTR(-EINVAL);
561562

562-
req.total_num_uuars = ALIGN(req.total_num_uuars, MLX5_BF_REGS_PER_PAGE);
563+
req.total_num_uuars = ALIGN(req.total_num_uuars,
564+
MLX5_NON_FP_BF_REGS_PER_PAGE);
563565
if (req.num_low_latency_uuars > req.total_num_uuars - 1)
564566
return ERR_PTR(-EINVAL);
565567

566-
num_uars = req.total_num_uuars / MLX5_BF_REGS_PER_PAGE;
568+
num_uars = req.total_num_uuars / MLX5_NON_FP_BF_REGS_PER_PAGE;
569+
gross_uuars = num_uars * MLX5_BF_REGS_PER_PAGE;
567570
resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp;
568571
resp.bf_reg_size = dev->mdev.caps.bf_reg_size;
569572
resp.cache_line_size = L1_CACHE_BYTES;
@@ -585,7 +588,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
585588
goto out_ctx;
586589
}
587590

588-
uuari->bitmap = kcalloc(BITS_TO_LONGS(req.total_num_uuars),
591+
uuari->bitmap = kcalloc(BITS_TO_LONGS(gross_uuars),
589592
sizeof(*uuari->bitmap),
590593
GFP_KERNEL);
591594
if (!uuari->bitmap) {
@@ -595,13 +598,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
595598
/*
596599
* clear all fast path uuars
597600
*/
598-
for (i = 0; i < req.total_num_uuars; i++) {
601+
for (i = 0; i < gross_uuars; i++) {
599602
uuarn = i & 3;
600603
if (uuarn == 2 || uuarn == 3)
601604
set_bit(i, uuari->bitmap);
602605
}
603606

604-
uuari->count = kcalloc(req.total_num_uuars, sizeof(*uuari->count), GFP_KERNEL);
607+
uuari->count = kcalloc(gross_uuars, sizeof(*uuari->count), GFP_KERNEL);
605608
if (!uuari->count) {
606609
err = -ENOMEM;
607610
goto out_bitmap;

drivers/infiniband/hw/mlx5/qp.c

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -340,14 +340,57 @@ static int qp_has_rq(struct ib_qp_init_attr *attr)
340340
return 1;
341341
}
342342

343+
static int first_med_uuar(void)
344+
{
345+
return 1;
346+
}
347+
348+
static int next_uuar(int n)
349+
{
350+
n++;
351+
352+
while (((n % 4) & 2))
353+
n++;
354+
355+
return n;
356+
}
357+
358+
static int num_med_uuar(struct mlx5_uuar_info *uuari)
359+
{
360+
int n;
361+
362+
n = uuari->num_uars * MLX5_NON_FP_BF_REGS_PER_PAGE -
363+
uuari->num_low_latency_uuars - 1;
364+
365+
return n >= 0 ? n : 0;
366+
}
367+
368+
static int max_uuari(struct mlx5_uuar_info *uuari)
369+
{
370+
return uuari->num_uars * 4;
371+
}
372+
373+
static int first_hi_uuar(struct mlx5_uuar_info *uuari)
374+
{
375+
int med;
376+
int i;
377+
int t;
378+
379+
med = num_med_uuar(uuari);
380+
for (t = 0, i = first_med_uuar();; i = next_uuar(i)) {
381+
t++;
382+
if (t == med)
383+
return next_uuar(i);
384+
}
385+
386+
return 0;
387+
}
388+
343389
static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
344390
{
345-
int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
346-
int start_uuar;
347391
int i;
348392

349-
start_uuar = nuuars - uuari->num_low_latency_uuars;
350-
for (i = start_uuar; i < nuuars; i++) {
393+
for (i = first_hi_uuar(uuari); i < max_uuari(uuari); i = next_uuar(i)) {
351394
if (!test_bit(i, uuari->bitmap)) {
352395
set_bit(i, uuari->bitmap);
353396
uuari->count[i]++;
@@ -360,19 +403,10 @@ static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
360403

361404
static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari)
362405
{
363-
int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
364-
int minidx = 1;
365-
int uuarn;
366-
int end;
406+
int minidx = first_med_uuar();
367407
int i;
368408

369-
end = nuuars - uuari->num_low_latency_uuars;
370-
371-
for (i = 1; i < end; i++) {
372-
uuarn = i & 3;
373-
if (uuarn == 2 || uuarn == 3)
374-
continue;
375-
409+
for (i = first_med_uuar(); i < first_hi_uuar(uuari); i = next_uuar(i)) {
376410
if (uuari->count[i] < uuari->count[minidx])
377411
minidx = i;
378412
}
@@ -510,11 +544,16 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
510544
uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
511545
if (uuarn < 0) {
512546
mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
513-
mlx5_ib_dbg(dev, "reverting to high latency\n");
514-
uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
547+
mlx5_ib_dbg(dev, "reverting to medium latency\n");
548+
uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM);
515549
if (uuarn < 0) {
516-
mlx5_ib_dbg(dev, "uuar allocation failed\n");
517-
return uuarn;
550+
mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n");
551+
mlx5_ib_dbg(dev, "reverting to high latency\n");
552+
uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
553+
if (uuarn < 0) {
554+
mlx5_ib_warn(dev, "uuar allocation failed\n");
555+
return uuarn;
556+
}
518557
}
519558
}
520559

include/linux/mlx5/device.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ enum {
104104
};
105105

106106
enum {
107-
MLX5_BF_REGS_PER_PAGE = 4,
108-
MLX5_MAX_UAR_PAGES = 1 << 8,
109-
MLX5_MAX_UUARS = MLX5_MAX_UAR_PAGES * MLX5_BF_REGS_PER_PAGE,
107+
MLX5_BF_REGS_PER_PAGE = 4,
108+
MLX5_MAX_UAR_PAGES = 1 << 8,
109+
MLX5_NON_FP_BF_REGS_PER_PAGE = 2,
110+
MLX5_MAX_UUARS = MLX5_MAX_UAR_PAGES * MLX5_NON_FP_BF_REGS_PER_PAGE,
110111
};
111112

112113
enum {

0 commit comments

Comments
 (0)