| From: Yishai Hadas <yishaih@mellanox.com> |
| Date: Mon, 7 May 2018 10:20:01 +0300 |
| Subject: RDMA/mlx5: Don't assume that medium blueFlame register exists |
| |
| commit 18b0362e87dfa09e355093b897b9db854e360d28 upstream. |
| |
| User can leave system without medium BlueFlames registers, |
| however the code assumed that at least one such register exists. |
| |
| This patch fixes that assumption. |
| |
| Fixes: c1be5232d21d ("IB/mlx5: Fix micro UAR allocator") |
| Reported-by: Rohit Zambre <rzambre@uci.edu> |
| Signed-off-by: Yishai Hadas <yishaih@mellanox.com> |
| Signed-off-by: Leon Romanovsky <leonro@mellanox.com> |
| Signed-off-by: Doug Ledford <dledford@redhat.com> |
| [bwh: Backported to 3.16: |
| - s/bfreg/uuar/g |
| - Neither alloc_med_class_uuar() nor num_med_uuar() takes a mlx5_ib_dev |
| pointer, so first_med_uuar() doesn't need to take one |
| - Adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| drivers/infiniband/hw/mlx5/qp.c | 18 +++++++++++------- |
| 1 file changed, 11 insertions(+), 7 deletions(-) |
| |
| --- a/drivers/infiniband/hw/mlx5/qp.c |
| +++ b/drivers/infiniband/hw/mlx5/qp.c |
| @@ -356,11 +356,6 @@ static int qp_has_rq(struct ib_qp_init_a |
| return 1; |
| } |
| |
| -static int first_med_uuar(void) |
| -{ |
| - return 1; |
| -} |
| - |
| static int next_uuar(int n) |
| { |
| n++; |
| @@ -395,6 +390,11 @@ static int max_uuari(struct mlx5_uuar_in |
| return uuari->num_uars * 4; |
| } |
| |
| +static int first_med_uuar(struct mlx5_uuar_info *uuari) |
| +{ |
| + return num_med_uuar(uuari) ? 1 : -ENOMEM; |
| +} |
| + |
| static int first_hi_uuar(struct mlx5_uuar_info *uuari) |
| { |
| int med; |
| @@ -420,10 +420,13 @@ static int alloc_high_class_uuar(struct |
| |
| static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari) |
| { |
| - int minidx = first_med_uuar(); |
| + int minidx = first_med_uuar(uuari); |
| int i; |
| |
| - for (i = first_med_uuar(); i < first_hi_uuar(uuari); i = next_uuar(i)) { |
| + if (minidx < 0) |
| + return minidx; |
| + |
| + for (i = minidx; i < first_hi_uuar(uuari); i = next_uuar(i)) { |
| if (uuari->count[i] < uuari->count[minidx]) |
| minidx = i; |
| if (!uuari->count[minidx]) |