]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/infiniband/hw/mlx5/qp.c
IB/mlx5: Allow future extension of libmlx5 input data
[mirror_ubuntu-bionic-kernel.git] / drivers / infiniband / hw / mlx5 / qp.c
index a1b3125f0a6eb3a312539a32414202cefc877df8..6a83fb32599dc8dfe8ac5dfe6eb3c2dd02906f43 100644 (file)
@@ -475,60 +475,53 @@ static int qp_has_rq(struct ib_qp_init_attr *attr)
        return 1;
 }
 
-static int first_med_uuar(void)
+static int first_med_bfreg(void)
 {
        return 1;
 }
 
-static int next_uuar(int n)
-{
-       n++;
-
-       while (((n % 4) & 2))
-               n++;
+enum {
+       /* this is the first blue flame register in the array of bfregs assigned
+        * to a processes. Since we do not use it for blue flame but rather
+        * regular 64 bit doorbells, we do not need a lock for maintaiing
+        * "odd/even" order
+        */
+       NUM_NON_BLUE_FLAME_BFREGS = 1,
+};
 
-       return n;
+static int max_bfregs(struct mlx5_ib_dev *dev, struct mlx5_bfreg_info *bfregi)
+{
+       return get_num_uars(dev, bfregi) * MLX5_NON_FP_BFREGS_PER_UAR;
 }
 
-static int num_med_uuar(struct mlx5_uuar_info *uuari)
+static int num_med_bfreg(struct mlx5_ib_dev *dev,
+                        struct mlx5_bfreg_info *bfregi)
 {
        int n;
 
-       n = uuari->num_uars * MLX5_NON_FP_BF_REGS_PER_PAGE -
-               uuari->num_low_latency_uuars - 1;
+       n = max_bfregs(dev, bfregi) - bfregi->num_low_latency_bfregs -
+           NUM_NON_BLUE_FLAME_BFREGS;
 
        return n >= 0 ? n : 0;
 }
 
-static int max_uuari(struct mlx5_uuar_info *uuari)
-{
-       return uuari->num_uars * 4;
-}
-
-static int first_hi_uuar(struct mlx5_uuar_info *uuari)
+static int first_hi_bfreg(struct mlx5_ib_dev *dev,
+                         struct mlx5_bfreg_info *bfregi)
 {
        int med;
-       int i;
-       int t;
-
-       med = num_med_uuar(uuari);
-       for (t = 0, i = first_med_uuar();; i = next_uuar(i)) {
-               t++;
-               if (t == med)
-                       return next_uuar(i);
-       }
 
-       return 0;
+       med = num_med_bfreg(dev, bfregi);
+       return ++med;
 }
 
-static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
+static int alloc_high_class_bfreg(struct mlx5_ib_dev *dev,
+                                 struct mlx5_bfreg_info *bfregi)
 {
        int i;
 
-       for (i = first_hi_uuar(uuari); i < max_uuari(uuari); i = next_uuar(i)) {
-               if (!test_bit(i, uuari->bitmap)) {
-                       set_bit(i, uuari->bitmap);
-                       uuari->count[i]++;
+       for (i = first_hi_bfreg(dev, bfregi); i < max_bfregs(dev, bfregi); i++) {
+               if (!bfregi->count[i]) {
+                       bfregi->count[i]++;
                        return i;
                }
        }
@@ -536,87 +529,61 @@ static int alloc_high_class_uuar(struct mlx5_uuar_info *uuari)
        return -ENOMEM;
 }
 
-static int alloc_med_class_uuar(struct mlx5_uuar_info *uuari)
+static int alloc_med_class_bfreg(struct mlx5_ib_dev *dev,
+                                struct mlx5_bfreg_info *bfregi)
 {
-       int minidx = first_med_uuar();
+       int minidx = first_med_bfreg();
        int i;
 
-       for (i = first_med_uuar(); i < first_hi_uuar(uuari); i = next_uuar(i)) {
-               if (uuari->count[i] < uuari->count[minidx])
+       for (i = first_med_bfreg(); i < first_hi_bfreg(dev, bfregi); i++) {
+               if (bfregi->count[i] < bfregi->count[minidx])
                        minidx = i;
+               if (!bfregi->count[minidx])
+                       break;
        }
 
-       uuari->count[minidx]++;
+       bfregi->count[minidx]++;
        return minidx;
 }
 
-static int alloc_uuar(struct mlx5_uuar_info *uuari,
-                     enum mlx5_ib_latency_class lat)
+static int alloc_bfreg(struct mlx5_ib_dev *dev,
+                      struct mlx5_bfreg_info *bfregi,
+                      enum mlx5_ib_latency_class lat)
 {
-       int uuarn = -EINVAL;
+       int bfregn = -EINVAL;
 
-       mutex_lock(&uuari->lock);
+       mutex_lock(&bfregi->lock);
        switch (lat) {
        case MLX5_IB_LATENCY_CLASS_LOW:
-               uuarn = 0;
-               uuari->count[uuarn]++;
+               BUILD_BUG_ON(NUM_NON_BLUE_FLAME_BFREGS != 1);
+               bfregn = 0;
+               bfregi->count[bfregn]++;
                break;
 
        case MLX5_IB_LATENCY_CLASS_MEDIUM:
-               if (uuari->ver < 2)
-                       uuarn = -ENOMEM;
+               if (bfregi->ver < 2)
+                       bfregn = -ENOMEM;
                else
-                       uuarn = alloc_med_class_uuar(uuari);
+                       bfregn = alloc_med_class_bfreg(dev, bfregi);
                break;
 
        case MLX5_IB_LATENCY_CLASS_HIGH:
-               if (uuari->ver < 2)
-                       uuarn = -ENOMEM;
+               if (bfregi->ver < 2)
+                       bfregn = -ENOMEM;
                else
-                       uuarn = alloc_high_class_uuar(uuari);
-               break;
-
-       case MLX5_IB_LATENCY_CLASS_FAST_PATH:
-               uuarn = 2;
+                       bfregn = alloc_high_class_bfreg(dev, bfregi);
                break;
        }
-       mutex_unlock(&uuari->lock);
-
-       return uuarn;
-}
+       mutex_unlock(&bfregi->lock);
 
-static void free_med_class_uuar(struct mlx5_uuar_info *uuari, int uuarn)
-{
-       clear_bit(uuarn, uuari->bitmap);
-       --uuari->count[uuarn];
-}
-
-static void free_high_class_uuar(struct mlx5_uuar_info *uuari, int uuarn)
-{
-       clear_bit(uuarn, uuari->bitmap);
-       --uuari->count[uuarn];
+       return bfregn;
 }
 
-static void free_uuar(struct mlx5_uuar_info *uuari, int uuarn)
+static void free_bfreg(struct mlx5_ib_dev *dev, struct mlx5_bfreg_info *bfregi, int bfregn)
 {
-       int nuuars = uuari->num_uars * MLX5_BF_REGS_PER_PAGE;
-       int high_uuar = nuuars - uuari->num_low_latency_uuars;
-
-       mutex_lock(&uuari->lock);
-       if (uuarn == 0) {
-               --uuari->count[uuarn];
-               goto out;
-       }
-
-       if (uuarn < high_uuar) {
-               free_med_class_uuar(uuari, uuarn);
-               goto out;
-       }
-
-       free_high_class_uuar(uuari, uuarn);
-
-out:
-       mutex_unlock(&uuari->lock);
+       mutex_lock(&bfregi->lock);
+       bfregi->count[bfregn]--;
+       mutex_unlock(&bfregi->lock);
 }
 
 static enum mlx5_qp_state to_mlx5_state(enum ib_qp_state state)
@@ -657,9 +624,20 @@ static void mlx5_ib_lock_cqs(struct mlx5_ib_cq *send_cq,
 static void mlx5_ib_unlock_cqs(struct mlx5_ib_cq *send_cq,
                               struct mlx5_ib_cq *recv_cq);
 
-static int uuarn_to_uar_index(struct mlx5_uuar_info *uuari, int uuarn)
+static int bfregn_to_uar_index(struct mlx5_ib_dev *dev,
+                              struct mlx5_bfreg_info *bfregi, int bfregn)
 {
-       return uuari->uars[uuarn / MLX5_BF_REGS_PER_PAGE].index;
+       int bfregs_per_sys_page;
+       int index_of_sys_page;
+       int offset;
+
+       bfregs_per_sys_page = get_uars_per_sys_page(dev, bfregi->lib_uar_4k) *
+                               MLX5_NON_FP_BFREGS_PER_UAR;
+       index_of_sys_page = bfregn / bfregs_per_sys_page;
+
+       offset = bfregn % bfregs_per_sys_page / MLX5_NON_FP_BFREGS_PER_UAR;
+
+       return bfregi->sys_pages[index_of_sys_page] + offset;
 }
 
 static int mlx5_ib_umem_get(struct mlx5_ib_dev *dev,
@@ -762,6 +740,13 @@ err_umem:
        return err;
 }
 
+static int adjust_bfregn(struct mlx5_ib_dev *dev,
+                        struct mlx5_bfreg_info *bfregi, int bfregn)
+{
+       return bfregn / MLX5_NON_FP_BFREGS_PER_UAR * MLX5_BFREGS_PER_UAR +
+                               bfregn % MLX5_NON_FP_BFREGS_PER_UAR;
+}
+
 static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                          struct mlx5_ib_qp *qp, struct ib_udata *udata,
                          struct ib_qp_init_attr *attr,
@@ -776,7 +761,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        int uar_index;
        int npages;
        u32 offset = 0;
-       int uuarn;
+       int bfregn;
        int ncont = 0;
        __be64 *pas;
        void *qpc;
@@ -794,27 +779,27 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
         */
        if (qp->flags & MLX5_IB_QP_CROSS_CHANNEL)
                /* In CROSS_CHANNEL CQ and QP must use the same UAR */
-               uuarn = MLX5_CROSS_CHANNEL_UUAR;
+               bfregn = MLX5_CROSS_CHANNEL_BFREG;
        else {
-               uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_HIGH);
-               if (uuarn < 0) {
-                       mlx5_ib_dbg(dev, "failed to allocate low latency UUAR\n");
+               bfregn = alloc_bfreg(dev, &context->bfregi, MLX5_IB_LATENCY_CLASS_HIGH);
+               if (bfregn < 0) {
+                       mlx5_ib_dbg(dev, "failed to allocate low latency BFREG\n");
                        mlx5_ib_dbg(dev, "reverting to medium latency\n");
-                       uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_MEDIUM);
-                       if (uuarn < 0) {
-                               mlx5_ib_dbg(dev, "failed to allocate medium latency UUAR\n");
+                       bfregn = alloc_bfreg(dev, &context->bfregi, MLX5_IB_LATENCY_CLASS_MEDIUM);
+                       if (bfregn < 0) {
+                               mlx5_ib_dbg(dev, "failed to allocate medium latency BFREG\n");
                                mlx5_ib_dbg(dev, "reverting to high latency\n");
-                               uuarn = alloc_uuar(&context->uuari, MLX5_IB_LATENCY_CLASS_LOW);
-                               if (uuarn < 0) {
-                                       mlx5_ib_warn(dev, "uuar allocation failed\n");
-                                       return uuarn;
+                               bfregn = alloc_bfreg(dev, &context->bfregi, MLX5_IB_LATENCY_CLASS_LOW);
+                               if (bfregn < 0) {
+                                       mlx5_ib_warn(dev, "bfreg allocation failed\n");
+                                       return bfregn;
                                }
                        }
                }
        }
 
-       uar_index = uuarn_to_uar_index(&context->uuari, uuarn);
-       mlx5_ib_dbg(dev, "uuarn 0x%x, uar_index 0x%x\n", uuarn, uar_index);
+       uar_index = bfregn_to_uar_index(dev, &context->bfregi, bfregn);
+       mlx5_ib_dbg(dev, "bfregn 0x%x, uar_index 0x%x\n", bfregn, uar_index);
 
        qp->rq.offset = 0;
        qp->sq.wqe_shift = ilog2(MLX5_SEND_WQE_BB);
@@ -822,7 +807,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
 
        err = set_user_buf_size(dev, qp, &ucmd, base, attr);
        if (err)
-               goto err_uuar;
+               goto err_bfreg;
 
        if (ucmd.buf_addr && ubuffer->buf_size) {
                ubuffer->buf_addr = ucmd.buf_addr;
@@ -831,7 +816,7 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
                                       &ubuffer->umem, &npages, &page_shift,
                                       &ncont, &offset);
                if (err)
-                       goto err_uuar;
+                       goto err_bfreg;
        } else {
                ubuffer->umem = NULL;
        }
@@ -854,8 +839,8 @@ static int create_user_qp(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        MLX5_SET(qpc, qpc, page_offset, offset);
 
        MLX5_SET(qpc, qpc, uar_page, uar_index);
-       resp->uuar_index = uuarn;
-       qp->uuarn = uuarn;
+       resp->bfreg_index = adjust_bfregn(dev, &context->bfregi, bfregn);
+       qp->bfregn = bfregn;
 
        err = mlx5_ib_db_map_user(context, ucmd.db_addr, &qp->db);
        if (err) {
@@ -882,13 +867,13 @@ err_umem:
        if (ubuffer->umem)
                ib_umem_release(ubuffer->umem);
 
-err_uuar:
-       free_uuar(&context->uuari, uuarn);
+err_bfreg:
+       free_bfreg(dev, &context->bfregi, bfregn);
        return err;
 }
 
-static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp,
-                           struct mlx5_ib_qp_base *base)
+static void destroy_qp_user(struct mlx5_ib_dev *dev, struct ib_pd *pd,
+                           struct mlx5_ib_qp *qp, struct mlx5_ib_qp_base *base)
 {
        struct mlx5_ib_ucontext *context;
 
@@ -896,7 +881,7 @@ static void destroy_qp_user(struct ib_pd *pd, struct mlx5_ib_qp *qp,
        mlx5_ib_db_unmap_user(context, &qp->db);
        if (base->ubuffer.umem)
                ib_umem_release(base->ubuffer.umem);
-       free_uuar(&context->uuari, qp->uuarn);
+       free_bfreg(dev, &context->bfregi, qp->bfregn);
 }
 
 static int create_kernel_qp(struct mlx5_ib_dev *dev,
@@ -905,14 +890,10 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
                            u32 **in, int *inlen,
                            struct mlx5_ib_qp_base *base)
 {
-       enum mlx5_ib_latency_class lc = MLX5_IB_LATENCY_CLASS_LOW;
-       struct mlx5_uuar_info *uuari;
        int uar_index;
        void *qpc;
-       int uuarn;
        int err;
 
-       uuari = &dev->mdev->priv.uuari;
        if (init_attr->create_flags & ~(IB_QP_CREATE_SIGNATURE_EN |
                                        IB_QP_CREATE_BLOCK_MULTICAST_LOOPBACK |
                                        IB_QP_CREATE_IPOIB_UD_LSO |
@@ -920,21 +901,17 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
                return -EINVAL;
 
        if (init_attr->qp_type == MLX5_IB_QPT_REG_UMR)
-               lc = MLX5_IB_LATENCY_CLASS_FAST_PATH;
-
-       uuarn = alloc_uuar(uuari, lc);
-       if (uuarn < 0) {
-               mlx5_ib_dbg(dev, "\n");
-               return -ENOMEM;
-       }
+               qp->bf.bfreg = &dev->fp_bfreg;
+       else
+               qp->bf.bfreg = &dev->bfreg;
 
-       qp->bf = &uuari->bfs[uuarn];
-       uar_index = qp->bf->uar->index;
+       qp->bf.buf_size = 1 << MLX5_CAP_GEN(dev->mdev, log_bf_reg_size);
+       uar_index = qp->bf.bfreg->index;
 
        err = calc_sq_size(dev, init_attr, qp);
        if (err < 0) {
                mlx5_ib_dbg(dev, "err %d\n", err);
-               goto err_uuar;
+               return err;
        }
 
        qp->rq.offset = 0;
@@ -944,7 +921,7 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        err = mlx5_buf_alloc(dev->mdev, base->ubuffer.buf_size, &qp->buf);
        if (err) {
                mlx5_ib_dbg(dev, "err %d\n", err);
-               goto err_uuar;
+               return err;
        }
 
        qp->sq.qend = mlx5_get_send_wqe(qp, qp->sq.wqe_cnt);
@@ -994,34 +971,30 @@ static int create_kernel_qp(struct mlx5_ib_dev *dev,
        return 0;
 
 err_wrid:
-       mlx5_db_free(dev->mdev, &qp->db);
        kfree(qp->sq.wqe_head);
        kfree(qp->sq.w_list);
        kfree(qp->sq.wrid);
        kfree(qp->sq.wr_data);
        kfree(qp->rq.wrid);
+       mlx5_db_free(dev->mdev, &qp->db);
 
 err_free:
        kvfree(*in);
 
 err_buf:
        mlx5_buf_free(dev->mdev, &qp->buf);
-
-err_uuar:
-       free_uuar(&dev->mdev->priv.uuari, uuarn);
        return err;
 }
 
 static void destroy_qp_kernel(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 {
-       mlx5_db_free(dev->mdev, &qp->db);
        kfree(qp->sq.wqe_head);
        kfree(qp->sq.w_list);
        kfree(qp->sq.wrid);
        kfree(qp->sq.wr_data);
        kfree(qp->rq.wrid);
+       mlx5_db_free(dev->mdev, &qp->db);
        mlx5_buf_free(dev->mdev, &qp->buf);
-       free_uuar(&dev->mdev->priv.uuari, qp->bf->uuarn);
 }
 
 static u32 get_rx_type(struct mlx5_ib_qp *qp, struct ib_qp_init_attr *attr)
@@ -1353,7 +1326,7 @@ static int create_rss_raw_qp_tir(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        if (init_attr->create_flags || init_attr->send_cq)
                return -EINVAL;
 
-       min_resp_len = offsetof(typeof(resp), uuar_index) + sizeof(resp.uuar_index);
+       min_resp_len = offsetof(typeof(resp), bfreg_index) + sizeof(resp.bfreg_index);
        if (udata->outlen < min_resp_len)
                return -EINVAL;
 
@@ -1526,9 +1499,6 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
               &qp->raw_packet_qp.rq.base :
               &qp->trans_qp.base;
 
-       if (init_attr->qp_type != IB_QPT_RAW_PACKET)
-               mlx5_ib_odp_create_qp(qp);
-
        mutex_init(&qp->mutex);
        spin_lock_init(&qp->sq.lock);
        spin_lock_init(&qp->rq.lock);
@@ -1795,7 +1765,7 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
 
 err_create:
        if (qp->create_type == MLX5_QP_USER)
-               destroy_qp_user(pd, qp, base);
+               destroy_qp_user(dev, pd, qp, base);
        else if (qp->create_type == MLX5_QP_KERNEL)
                destroy_qp_kernel(dev, qp);
 
@@ -1923,7 +1893,6 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
 
        if (qp->state != IB_QPS_RESET) {
                if (qp->ibqp.qp_type != IB_QPT_RAW_PACKET) {
-                       mlx5_ib_qp_disable_pagefaults(qp);
                        err = mlx5_core_qp_modify(dev->mdev,
                                                  MLX5_CMD_OP_2RST_QP, 0,
                                                  NULL, &base->mqp);
@@ -1974,7 +1943,7 @@ static void destroy_qp_common(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp)
        if (qp->create_type == MLX5_QP_KERNEL)
                destroy_qp_kernel(dev, qp);
        else if (qp->create_type == MLX5_QP_USER)
-               destroy_qp_user(&get_pd(qp)->ibpd, qp, base);
+               destroy_qp_user(dev, &get_pd(qp)->ibpd, qp, base);
 }
 
 static const char *ib_qp_type_str(enum ib_qp_type type)
@@ -2823,16 +2792,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        if (mlx5_st < 0)
                goto out;
 
-       /* If moving to a reset or error state, we must disable page faults on
-        * this QP and flush all current page faults. Otherwise a stale page
-        * fault may attempt to work on this QP after it is reset and moved
-        * again to RTS, and may cause the driver and the device to get out of
-        * sync. */
-       if (cur_state != IB_QPS_RESET && cur_state != IB_QPS_ERR &&
-           (new_state == IB_QPS_RESET || new_state == IB_QPS_ERR) &&
-           (qp->ibqp.qp_type != IB_QPT_RAW_PACKET))
-               mlx5_ib_qp_disable_pagefaults(qp);
-
        if (mlx5_cur >= MLX5_QP_NUM_STATE || mlx5_new >= MLX5_QP_NUM_STATE ||
            !optab[mlx5_cur][mlx5_new])
                goto out;
@@ -2864,10 +2823,6 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp,
        if (err)
                goto out;
 
-       if (cur_state == IB_QPS_RESET && new_state == IB_QPS_INIT &&
-           (qp->ibqp.qp_type != IB_QPT_RAW_PACKET))
-               mlx5_ib_qp_enable_pagefaults(qp);
-
        qp->state = new_state;
 
        if (attr_mask & IB_QP_ACCESS_FLAGS)
@@ -3080,9 +3035,10 @@ static void set_data_ptr_seg(struct mlx5_wqe_data_seg *dseg, struct ib_sge *sg)
        dseg->addr       = cpu_to_be64(sg->addr);
 }
 
-static __be16 get_klm_octo(int npages)
+static u64 get_xlt_octo(u64 bytes)
 {
-       return cpu_to_be16(ALIGN(npages, 8) / 2);
+       return ALIGN(bytes, MLX5_IB_UMR_XLT_ALIGNMENT) /
+              MLX5_IB_UMR_OCTOWORD;
 }
 
 static __be64 frwr_mkey_mask(void)
@@ -3127,18 +3083,14 @@ static __be64 sig_mkey_mask(void)
 }
 
 static void set_reg_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr,
-                               struct mlx5_ib_mr *mr)
+                           struct mlx5_ib_mr *mr)
 {
-       int ndescs = mr->ndescs;
+       int size = mr->ndescs * mr->desc_size;
 
        memset(umr, 0, sizeof(*umr));
 
-       if (mr->access_mode == MLX5_MKC_ACCESS_MODE_KLMS)
-               /* KLMs take twice the size of MTTs */
-               ndescs *= 2;
-
        umr->flags = MLX5_UMR_CHECK_NOT_FREE;
-       umr->klm_octowords = get_klm_octo(ndescs);
+       umr->xlt_octowords = cpu_to_be16(get_xlt_octo(size));
        umr->mkey_mask = frwr_mkey_mask();
 }
 
@@ -3149,37 +3101,17 @@ static void set_linv_umr_seg(struct mlx5_wqe_umr_ctrl_seg *umr)
        umr->flags = MLX5_UMR_INLINE;
 }
 
-static __be64 get_umr_reg_mr_mask(int atomic)
+static __be64 get_umr_enable_mr_mask(void)
 {
        u64 result;
 
-       result = MLX5_MKEY_MASK_LEN             |
-                MLX5_MKEY_MASK_PAGE_SIZE       |
-                MLX5_MKEY_MASK_START_ADDR      |
-                MLX5_MKEY_MASK_PD              |
-                MLX5_MKEY_MASK_LR              |
-                MLX5_MKEY_MASK_LW              |
-                MLX5_MKEY_MASK_KEY             |
-                MLX5_MKEY_MASK_RR              |
-                MLX5_MKEY_MASK_RW              |
+       result = MLX5_MKEY_MASK_KEY |
                 MLX5_MKEY_MASK_FREE;
 
-       if (atomic)
-               result |= MLX5_MKEY_MASK_A;
-
        return cpu_to_be64(result);
 }
 
-static __be64 get_umr_unreg_mr_mask(void)
-{
-       u64 result;
-
-       result = MLX5_MKEY_MASK_FREE;
-
-       return cpu_to_be64(result);
-}
-
-static __be64 get_umr_update_mtt_mask(void)
+static __be64 get_umr_disable_mr_mask(void)
 {
        u64 result;
 
@@ -3194,23 +3126,22 @@ static __be64 get_umr_update_translation_mask(void)
 
        result = MLX5_MKEY_MASK_LEN |
                 MLX5_MKEY_MASK_PAGE_SIZE |
-                MLX5_MKEY_MASK_START_ADDR |
-                MLX5_MKEY_MASK_KEY |
-                MLX5_MKEY_MASK_FREE;
+                MLX5_MKEY_MASK_START_ADDR;
 
        return cpu_to_be64(result);
 }
 
-static __be64 get_umr_update_access_mask(void)
+static __be64 get_umr_update_access_mask(int atomic)
 {
        u64 result;
 
-       result = MLX5_MKEY_MASK_LW |
+       result = MLX5_MKEY_MASK_LR |
+                MLX5_MKEY_MASK_LW |
                 MLX5_MKEY_MASK_RR |
-                MLX5_MKEY_MASK_RW |
-                MLX5_MKEY_MASK_A |
-                MLX5_MKEY_MASK_KEY |
-                MLX5_MKEY_MASK_FREE;
+                MLX5_MKEY_MASK_RW;
+
+       if (atomic)
+               result |= MLX5_MKEY_MASK_A;
 
        return cpu_to_be64(result);
 }
@@ -3219,9 +3150,7 @@ static __be64 get_umr_update_pd_mask(void)
 {
        u64 result;
 
-       result = MLX5_MKEY_MASK_PD |
-                MLX5_MKEY_MASK_KEY |
-                MLX5_MKEY_MASK_FREE;
+       result = MLX5_MKEY_MASK_PD;
 
        return cpu_to_be64(result);
 }
@@ -3238,24 +3167,24 @@ static void set_reg_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
        else
                umr->flags = MLX5_UMR_CHECK_NOT_FREE; /* fail if not free */
 
-       if (!(wr->send_flags & MLX5_IB_SEND_UMR_UNREG)) {
-               umr->klm_octowords = get_klm_octo(umrwr->npages);
-               if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT) {
-                       umr->mkey_mask = get_umr_update_mtt_mask();
-                       umr->bsf_octowords = get_klm_octo(umrwr->target.offset);
-                       umr->flags |= MLX5_UMR_TRANSLATION_OFFSET_EN;
-               }
-               if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION)
-                       umr->mkey_mask |= get_umr_update_translation_mask();
-               if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_ACCESS)
-                       umr->mkey_mask |= get_umr_update_access_mask();
-               if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_PD)
-                       umr->mkey_mask |= get_umr_update_pd_mask();
-               if (!umr->mkey_mask)
-                       umr->mkey_mask = get_umr_reg_mr_mask(atomic);
-       } else {
-               umr->mkey_mask = get_umr_unreg_mr_mask();
+       umr->xlt_octowords = cpu_to_be16(get_xlt_octo(umrwr->xlt_size));
+       if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_XLT) {
+               u64 offset = get_xlt_octo(umrwr->offset);
+
+               umr->xlt_offset = cpu_to_be16(offset & 0xffff);
+               umr->xlt_offset_47_16 = cpu_to_be32(offset >> 16);
+               umr->flags |= MLX5_UMR_TRANSLATION_OFFSET_EN;
+       }
+       if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION)
+               umr->mkey_mask |= get_umr_update_translation_mask();
+       if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_PD_ACCESS) {
+               umr->mkey_mask |= get_umr_update_access_mask(atomic);
+               umr->mkey_mask |= get_umr_update_pd_mask();
        }
+       if (wr->send_flags & MLX5_IB_SEND_UMR_ENABLE_MR)
+               umr->mkey_mask |= get_umr_enable_mr_mask();
+       if (wr->send_flags & MLX5_IB_SEND_UMR_DISABLE_MR)
+               umr->mkey_mask |= get_umr_disable_mr_mask();
 
        if (!wr->num_sge)
                umr->flags |= MLX5_UMR_INLINE;
@@ -3303,17 +3232,17 @@ static void set_reg_mkey_segment(struct mlx5_mkey_seg *seg, struct ib_send_wr *w
        struct mlx5_umr_wr *umrwr = umr_wr(wr);
 
        memset(seg, 0, sizeof(*seg));
-       if (wr->send_flags & MLX5_IB_SEND_UMR_UNREG) {
+       if (wr->send_flags & MLX5_IB_SEND_UMR_DISABLE_MR)
                seg->status = MLX5_MKEY_STATUS_FREE;
-               return;
-       }
 
        seg->flags = convert_access(umrwr->access_flags);
-       if (!(wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_MTT)) {
-               if (umrwr->pd)
-                       seg->flags_pd = cpu_to_be32(to_mpd(umrwr->pd)->pdn);
-               seg->start_addr = cpu_to_be64(umrwr->target.virt_addr);
-       }
+       if (umrwr->pd)
+               seg->flags_pd = cpu_to_be32(to_mpd(umrwr->pd)->pdn);
+       if (wr->send_flags & MLX5_IB_SEND_UMR_UPDATE_TRANSLATION &&
+           !umrwr->length)
+               seg->flags_pd |= cpu_to_be32(MLX5_MKEY_LEN64);
+
+       seg->start_addr = cpu_to_be64(umrwr->virt_addr);
        seg->len = cpu_to_be64(umrwr->length);
        seg->log2_page_size = umrwr->page_shift;
        seg->qpn_mkey7_0 = cpu_to_be32(0xffffff00 |
@@ -3611,7 +3540,7 @@ static int set_sig_data_segment(struct ib_sig_handover_wr *wr,
 }
 
 static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
-                                struct ib_sig_handover_wr *wr, u32 nelements,
+                                struct ib_sig_handover_wr *wr, u32 size,
                                 u32 length, u32 pdn)
 {
        struct ib_mr *sig_mr = wr->sig_mr;
@@ -3626,17 +3555,17 @@ static void set_sig_mkey_segment(struct mlx5_mkey_seg *seg,
        seg->flags_pd = cpu_to_be32(MLX5_MKEY_REMOTE_INVAL | sigerr << 26 |
                                    MLX5_MKEY_BSF_EN | pdn);
        seg->len = cpu_to_be64(length);
-       seg->xlt_oct_size = cpu_to_be32(be16_to_cpu(get_klm_octo(nelements)));
+       seg->xlt_oct_size = cpu_to_be32(get_xlt_octo(size));
        seg->bsfs_octo_size = cpu_to_be32(MLX5_MKEY_BSF_OCTO_SIZE);
 }
 
 static void set_sig_umr_segment(struct mlx5_wqe_umr_ctrl_seg *umr,
-                               u32 nelements)
+                               u32 size)
 {
        memset(umr, 0, sizeof(*umr));
 
        umr->flags = MLX5_FLAGS_INLINE | MLX5_FLAGS_CHECK_FREE;
-       umr->klm_octowords = get_klm_octo(nelements);
+       umr->xlt_octowords = cpu_to_be16(get_xlt_octo(size));
        umr->bsf_octowords = cpu_to_be16(MLX5_MKEY_BSF_OCTO_SIZE);
        umr->mkey_mask = sig_mkey_mask();
 }
@@ -3648,7 +3577,7 @@ static int set_sig_umr_wr(struct ib_send_wr *send_wr, struct mlx5_ib_qp *qp,
        struct ib_sig_handover_wr *wr = sig_handover_wr(send_wr);
        struct mlx5_ib_mr *sig_mr = to_mmr(wr->sig_mr);
        u32 pdn = get_pd(qp)->pdn;
-       u32 klm_oct_size;
+       u32 xlt_size;
        int region_len, ret;
 
        if (unlikely(wr->wr.num_sge != 1) ||
@@ -3670,15 +3599,15 @@ static int set_sig_umr_wr(struct ib_send_wr *send_wr, struct mlx5_ib_qp *qp,
         * then we use strided block format (3 octowords),
         * else we use single KLM (1 octoword)
         **/
-       klm_oct_size = wr->prot ? 3 : 1;
+       xlt_size = wr->prot ? 0x30 : sizeof(struct mlx5_klm);
 
-       set_sig_umr_segment(*seg, klm_oct_size);
+       set_sig_umr_segment(*seg, xlt_size);
        *seg += sizeof(struct mlx5_wqe_umr_ctrl_seg);
        *size += sizeof(struct mlx5_wqe_umr_ctrl_seg) / 16;
        if (unlikely((*seg == qp->sq.qend)))
                *seg = mlx5_get_send_wqe(qp, 0);
 
-       set_sig_mkey_segment(*seg, wr, klm_oct_size, region_len, pdn);
+       set_sig_mkey_segment(*seg, wr, xlt_size, region_len, pdn);
        *seg += sizeof(struct mlx5_mkey_seg);
        *size += sizeof(struct mlx5_mkey_seg) / 16;
        if (unlikely((*seg == qp->sq.qend)))
@@ -3784,24 +3713,6 @@ static void dump_wqe(struct mlx5_ib_qp *qp, int idx, int size_16)
        }
 }
 
-static void mlx5_bf_copy(u64 __iomem *dst, u64 *src,
-                        unsigned bytecnt, struct mlx5_ib_qp *qp)
-{
-       while (bytecnt > 0) {
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               __iowrite64_copy(dst++, src++, 8);
-               bytecnt -= 64;
-               if (unlikely(src == qp->sq.qend))
-                       src = mlx5_get_send_wqe(qp, 0);
-       }
-}
-
 static u8 get_fence(u8 fence, struct ib_send_wr *wr)
 {
        if (unlikely(wr->opcode == IB_WR_LOCAL_INV &&
@@ -3897,7 +3808,7 @@ int mlx5_ib_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
                return mlx5_ib_gsi_post_send(ibqp, wr, bad_wr);
 
        qp = to_mqp(ibqp);
-       bf = qp->bf;
+       bf = &qp->bf;
        qend = qp->sq.qend;
 
        spin_lock_irqsave(&qp->sq.lock, flags);
@@ -4170,28 +4081,13 @@ out:
                 * we hit doorbell */
                wmb();
 
-               if (bf->need_lock)
-                       spin_lock(&bf->lock);
-               else
-                       __acquire(&bf->lock);
-
-               /* TBD enable WC */
-               if (0 && nreq == 1 && bf->uuarn && inl && size > 1 && size <= bf->buf_size / 16) {
-                       mlx5_bf_copy(bf->reg + bf->offset, (u64 *)ctrl, ALIGN(size * 16, 64), qp);
-                       /* wc_wmb(); */
-               } else {
-                       mlx5_write64((__be32 *)ctrl, bf->regreg + bf->offset,
-                                    MLX5_GET_DOORBELL_LOCK(&bf->lock32));
-                       /* Make sure doorbells don't leak out of SQ spinlock
-                        * and reach the HCA out of order.
-                        */
-                       mmiowb();
-               }
+               /* currently we support only regular doorbells */
+               mlx5_write64((__be32 *)ctrl, bf->bfreg->map + bf->offset, NULL);
+               /* Make sure doorbells don't leak out of SQ spinlock
+                * and reach the HCA out of order.
+                */
+               mmiowb();
                bf->offset ^= bf->buf_size;
-               if (bf->need_lock)
-                       spin_unlock(&bf->lock);
-               else
-                       __release(&bf->lock);
        }
 
        spin_unlock_irqrestore(&qp->sq.lock, flags);
@@ -4559,14 +4455,6 @@ int mlx5_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr,
                return mlx5_ib_gsi_query_qp(ibqp, qp_attr, qp_attr_mask,
                                            qp_init_attr);
 
-#ifdef CONFIG_INFINIBAND_ON_DEMAND_PAGING
-       /*
-        * Wait for any outstanding page faults, in case the user frees memory
-        * based upon this query's result.
-        */
-       flush_workqueue(mlx5_ib_page_fault_wq);
-#endif
-
        mutex_lock(&qp->mutex);
 
        if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {