aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/mlx5
diff options
context:
space:
mode:
authorEli Cohen <eli@dev.mellanox.co.il>2014-01-14 10:45:12 -0500
committerRoland Dreier <roland@purestorage.com>2014-01-14 16:54:23 -0500
commitc1be5232d21de68f46637e617225b9b7c586451a (patch)
treeca552be072b1ec232a4ca7b1d3154fd6b5f4946f /drivers/infiniband/hw/mlx5
parent24e42754f676d34e5c26d6b7b30f36df8004ec08 (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.c13
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c77
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
343static int first_med_uuar(void)
344{
345 return 1;
346}
347
348static int next_uuar(int n)
349{
350 n++;
351
352 while (((n % 4) & 2))
353 n++;
354
355 return n;
356}
357
358static 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
368static int max_uuari(struct mlx5_uuar_info *uuari)
369{
370 return uuari->num_uars * 4;
371}
372
373static 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
343static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari) 389static 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
361static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari) 404static 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