diff options
author | Eli Cohen <eli@dev.mellanox.co.il> | 2014-01-14 10:45:12 -0500 |
---|---|---|
committer | Roland Dreier <roland@purestorage.com> | 2014-01-14 16:54:23 -0500 |
commit | c1be5232d21de68f46637e617225b9b7c586451a (patch) | |
tree | ca552be072b1ec232a4ca7b1d3154fd6b5f4946f /drivers/infiniband/hw/mlx5 | |
parent | 24e42754f676d34e5c26d6b7b30f36df8004ec08 (diff) |
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 <eli@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband/hw/mlx5')
-rw-r--r-- | drivers/infiniband/hw/mlx5/main.c | 13 | ||||
-rw-r--r-- | drivers/infiniband/hw/mlx5/qp.c | 77 |
2 files changed, 66 insertions, 24 deletions
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c index 306534109627..9660d093f8cf 100644 --- a/drivers/infiniband/hw/mlx5/main.c +++ b/drivers/infiniband/hw/mlx5/main.c | |||
@@ -541,6 +541,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
541 | struct mlx5_ib_ucontext *context; | 541 | struct mlx5_ib_ucontext *context; |
542 | struct mlx5_uuar_info *uuari; | 542 | struct mlx5_uuar_info *uuari; |
543 | struct mlx5_uar *uars; | 543 | struct mlx5_uar *uars; |
544 | int gross_uuars; | ||
544 | int num_uars; | 545 | int num_uars; |
545 | int uuarn; | 546 | int uuarn; |
546 | int err; | 547 | int err; |
@@ -559,11 +560,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
559 | if (req.total_num_uuars == 0) | 560 | if (req.total_num_uuars == 0) |
560 | return ERR_PTR(-EINVAL); | 561 | return ERR_PTR(-EINVAL); |
561 | 562 | ||
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); | ||
563 | if (req.num_low_latency_uuars > req.total_num_uuars - 1) | 565 | if (req.num_low_latency_uuars > req.total_num_uuars - 1) |
564 | return ERR_PTR(-EINVAL); | 566 | return ERR_PTR(-EINVAL); |
565 | 567 | ||
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; | ||
567 | resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp; | 570 | resp.qp_tab_size = 1 << dev->mdev.caps.log_max_qp; |
568 | resp.bf_reg_size = dev->mdev.caps.bf_reg_size; | 571 | resp.bf_reg_size = dev->mdev.caps.bf_reg_size; |
569 | resp.cache_line_size = L1_CACHE_BYTES; | 572 | resp.cache_line_size = L1_CACHE_BYTES; |
@@ -585,7 +588,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
585 | goto out_ctx; | 588 | goto out_ctx; |
586 | } | 589 | } |
587 | 590 | ||
588 | uuari->bitmap = kcalloc(BITS_TO_LONGS(req.total_num_uuars), | 591 | uuari->bitmap = kcalloc(BITS_TO_LONGS(gross_uuars), |
589 | sizeof(*uuari->bitmap), | 592 | sizeof(*uuari->bitmap), |
590 | GFP_KERNEL); | 593 | GFP_KERNEL); |
591 | if (!uuari->bitmap) { | 594 | if (!uuari->bitmap) { |
@@ -595,13 +598,13 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev, | |||
595 | /* | 598 | /* |
596 | * clear all fast path uuars | 599 | * clear all fast path uuars |
597 | */ | 600 | */ |
598 | for (i = 0; i < req.total_num_uuars; i++) { | 601 | for (i = 0; i < gross_uuars; i++) { |
599 | uuarn = i & 3; | 602 | uuarn = i & 3; |
600 | if (uuarn == 2 || uuarn == 3) | 603 | if (uuarn == 2 || uuarn == 3) |
601 | set_bit(i, uuari->bitmap); | 604 | set_bit(i, uuari->bitmap); |
602 | } | 605 | } |
603 | 606 | ||
604 | uuari->count = kcalloc(req.total_num_uuars, sizeof(*uuari->count), GFP_KERNEL); | 607 | uuari->count = kcalloc(gross_uuars, sizeof(*uuari->count), GFP_KERNEL); |
605 | if (!uuari->count) { | 608 | if (!uuari->count) { |
606 | err = -ENOMEM; | 609 | err = -ENOMEM; |
607 | goto out_bitmap; | 610 | goto out_bitmap; |
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index 7c6b4ba49bec..a056c243ddcd 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c | |||
@@ -340,14 +340,57 @@ static int qp_has_rq(struct ib_qp_init_attr *attr) | |||
340 | return 1; | 340 | return 1; |
341 | } | 341 | } |
342 | 342 | ||
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 | |||
343 | static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari) | 389 | static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari) |
344 | { | 390 | { |
345 | int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE; | ||
346 | int start_uuar; | ||
347 | int i; | 391 | int i; |
348 | 392 | ||
349 | start_uuar = nuuars - uuari->num_low_latency_uuars; | 393 | for (i = first_hi_uuar(uuari); i < max_uuari(uuari); i = next_uuar(i)) { |
350 | for (i = start_uuar; i < nuuars; i++) { | ||
351 | if (!test_bit(i, uuari->bitmap)) { | 394 | if (!test_bit(i, uuari->bitmap)) { |
352 | set_bit(i, uuari->bitmap); | 395 | set_bit(i, uuari->bitmap); |
353 | uuari->count[i]++; | 396 | uuari->count[i]++; |
@@ -360,19 +403,10 @@ static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari) | |||
360 | 403 | ||
361 | static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari) | 404 | static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari) |
362 | { | 405 | { |
363 | int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE; | 406 | int minidx = first_med_uuar(); |
364 | int minidx = 1; | ||
365 | int uuarn; | ||
366 | int end; | ||
367 | int i; | 407 | int i; |
368 | 408 | ||
369 | end = nuuars - uuari->num_low_latency_uuars; | 409 | for (i = first_med_uuar(); i < first_hi_uuar(uuari); i = next_uuar(i)) { |
370 | |||
371 | for (i = 1; i < end; i++) { | ||
372 | uuarn = i & 3; | ||
373 | if (uuarn == 2 || uuarn == 3) | ||
374 | continue; | ||
375 | |||
376 | if (uuari->count[i] < uuari->count[minidx]) | 410 | if (uuari->count[i] < uuari->count[minidx]) |
377 | minidx = i; | 411 | minidx = i; |
378 | } | 412 | } |
@@ -510,11 +544,16 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd, | |||
510 | uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH); | 544 | uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH); |
511 | if (uuarn < 0) { | 545 | if (uuarn < 0) { |
512 | mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n"); | 546 | mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n"); |
513 | mlx5_ib_dbg(dev, "reverting to high latency\n"); | 547 | mlx5_ib_dbg(dev, "reverting to medium latency\n"); |
514 | uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW); | 548 | uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM); |
515 | if (uuarn < 0) { | 549 | if (uuarn < 0) { |
516 | mlx5_ib_dbg(dev, "uuar allocation failed\n"); | 550 | mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n"); |
517 | return uuarn; | 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 | } | ||
518 | } | 557 | } |
519 | } | 558 | } |
520 | 559 | ||