Merge branch 'mlx5_tx_steering' into rdma.git for-next
[linux-block.git] / drivers / infiniband / hw / mlx5 / main.c
index 96dcaecf69f2839b1625c5fbc9bdd0570bbf3269..bc9d7a99ef4b24847de81831e512d1c803bcfc5c 100644 (file)
@@ -39,9 +39,6 @@
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
 #include <linux/bitmap.h>
-#if defined(CONFIG_X86)
-#include <asm/memtype.h>
-#endif
 #include <linux/sched.h>
 #include <linux/sched/mm.h>
 #include <linux/sched/task.h>
@@ -898,7 +895,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                        props->raw_packet_caps |=
                                IB_RAW_PACKET_CAP_CVLAN_STRIPPING;
 
-               if (field_avail(typeof(resp), tso_caps, uhw_outlen)) {
+               if (offsetofend(typeof(resp), tso_caps) <= uhw_outlen) {
                        max_tso = MLX5_CAP_ETH(mdev, max_lso_cap);
                        if (max_tso) {
                                resp.tso_caps.max_tso = 1 << max_tso;
@@ -908,7 +905,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                        }
                }
 
-               if (field_avail(typeof(resp), rss_caps, uhw_outlen)) {
+               if (offsetofend(typeof(resp), rss_caps) <= uhw_outlen) {
                        resp.rss_caps.rx_hash_function =
                                                MLX5_RX_HASH_FUNC_TOEPLITZ;
                        resp.rss_caps.rx_hash_fields_mask =
@@ -928,9 +925,9 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                        resp.response_length += sizeof(resp.rss_caps);
                }
        } else {
-               if (field_avail(typeof(resp), tso_caps, uhw_outlen))
+               if (offsetofend(typeof(resp), tso_caps) <= uhw_outlen)
                        resp.response_length += sizeof(resp.tso_caps);
-               if (field_avail(typeof(resp), rss_caps, uhw_outlen))
+               if (offsetofend(typeof(resp), rss_caps) <= uhw_outlen)
                        resp.response_length += sizeof(resp.rss_caps);
        }
 
@@ -1072,7 +1069,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                                                MLX5_MAX_CQ_PERIOD;
        }
 
-       if (field_avail(typeof(resp), cqe_comp_caps, uhw_outlen)) {
+       if (offsetofend(typeof(resp), cqe_comp_caps) <= uhw_outlen) {
                resp.response_length += sizeof(resp.cqe_comp_caps);
 
                if (MLX5_CAP_GEN(dev->mdev, cqe_compression)) {
@@ -1090,7 +1087,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                }
        }
 
-       if (field_avail(typeof(resp), packet_pacing_caps, uhw_outlen) &&
+       if (offsetofend(typeof(resp), packet_pacing_caps) <= uhw_outlen &&
            raw_support) {
                if (MLX5_CAP_QOS(mdev, packet_pacing) &&
                    MLX5_CAP_GEN(mdev, qos)) {
@@ -1108,8 +1105,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                resp.response_length += sizeof(resp.packet_pacing_caps);
        }
 
-       if (field_avail(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes,
-                       uhw_outlen)) {
+       if (offsetofend(typeof(resp), mlx5_ib_support_multi_pkt_send_wqes) <=
+           uhw_outlen) {
                if (MLX5_CAP_ETH(mdev, multi_pkt_send_wqe))
                        resp.mlx5_ib_support_multi_pkt_send_wqes =
                                MLX5_IB_ALLOW_MPW;
@@ -1122,7 +1119,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                        sizeof(resp.mlx5_ib_support_multi_pkt_send_wqes);
        }
 
-       if (field_avail(typeof(resp), flags, uhw_outlen)) {
+       if (offsetofend(typeof(resp), flags) <= uhw_outlen) {
                resp.response_length += sizeof(resp.flags);
 
                if (MLX5_CAP_GEN(mdev, cqe_compression_128))
@@ -1138,7 +1135,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                resp.flags |= MLX5_IB_QUERY_DEV_RESP_FLAGS_SCAT2CQE_DCT;
        }
 
-       if (field_avail(typeof(resp), sw_parsing_caps, uhw_outlen)) {
+       if (offsetofend(typeof(resp), sw_parsing_caps) <= uhw_outlen) {
                resp.response_length += sizeof(resp.sw_parsing_caps);
                if (MLX5_CAP_ETH(mdev, swp)) {
                        resp.sw_parsing_caps.sw_parsing_offloads |=
@@ -1158,7 +1155,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                }
        }
 
-       if (field_avail(typeof(resp), striding_rq_caps, uhw_outlen) &&
+       if (offsetofend(typeof(resp), striding_rq_caps) <= uhw_outlen &&
            raw_support) {
                resp.response_length += sizeof(resp.striding_rq_caps);
                if (MLX5_CAP_GEN(mdev, striding_rq)) {
@@ -1181,7 +1178,7 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                }
        }
 
-       if (field_avail(typeof(resp), tunnel_offloads_caps, uhw_outlen)) {
+       if (offsetofend(typeof(resp), tunnel_offloads_caps) <= uhw_outlen) {
                resp.response_length += sizeof(resp.tunnel_offloads_caps);
                if (MLX5_CAP_ETH(mdev, tunnel_stateless_vxlan))
                        resp.tunnel_offloads_caps |=
@@ -1192,12 +1189,10 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
                if (MLX5_CAP_ETH(mdev, tunnel_stateless_gre))
                        resp.tunnel_offloads_caps |=
                                MLX5_IB_TUNNELED_OFFLOADS_GRE;
-               if (MLX5_CAP_GEN(mdev, flex_parser_protocols) &
-                   MLX5_FLEX_PROTO_CW_MPLS_GRE)
+               if (MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_gre))
                        resp.tunnel_offloads_caps |=
                                MLX5_IB_TUNNELED_OFFLOADS_MPLS_GRE;
-               if (MLX5_CAP_GEN(mdev, flex_parser_protocols) &
-                   MLX5_FLEX_PROTO_CW_MPLS_UDP)
+               if (MLX5_CAP_ETH(mdev, tunnel_stateless_mpls_over_udp))
                        resp.tunnel_offloads_caps |=
                                MLX5_IB_TUNNELED_OFFLOADS_MPLS_UDP;
        }
@@ -1791,6 +1786,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
                                     max_cqe_version);
        u32 dump_fill_mkey;
        bool lib_uar_4k;
+       bool lib_uar_dyn;
 
        if (!dev->ib_active)
                return -EAGAIN;
@@ -1849,8 +1845,14 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
        }
 
        lib_uar_4k = req.lib_caps & MLX5_LIB_CAP_4K_UAR;
+       lib_uar_dyn = req.lib_caps & MLX5_LIB_CAP_DYN_UAR;
        bfregi = &context->bfregi;
 
+       if (lib_uar_dyn) {
+               bfregi->lib_uar_dyn = lib_uar_dyn;
+               goto uar_done;
+       }
+
        /* updates req->total_num_bfregs */
        err = calc_total_bfregs(dev, lib_uar_4k, &req, bfregi);
        if (err)
@@ -1877,6 +1879,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
        if (err)
                goto out_sys_pages;
 
+uar_done:
        if (req.flags & MLX5_IB_ALLOC_UCTX_DEVX) {
                err = mlx5_ib_devx_create(dev, true);
                if (err < 0)
@@ -1898,19 +1901,19 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
        INIT_LIST_HEAD(&context->db_page_list);
        mutex_init(&context->db_page_mutex);
 
-       resp.tot_bfregs = req.total_num_bfregs;
+       resp.tot_bfregs = lib_uar_dyn ? 0 : req.total_num_bfregs;
        resp.num_ports = dev->num_ports;
 
-       if (field_avail(typeof(resp), cqe_version, udata->outlen))
+       if (offsetofend(typeof(resp), cqe_version) <= udata->outlen)
                resp.response_length += sizeof(resp.cqe_version);
 
-       if (field_avail(typeof(resp), cmds_supp_uhw, udata->outlen)) {
+       if (offsetofend(typeof(resp), cmds_supp_uhw) <= udata->outlen) {
                resp.cmds_supp_uhw |= MLX5_USER_CMDS_SUPP_UHW_QUERY_DEVICE |
                                      MLX5_USER_CMDS_SUPP_UHW_CREATE_AH;
                resp.response_length += sizeof(resp.cmds_supp_uhw);
        }
 
-       if (field_avail(typeof(resp), eth_min_inline, udata->outlen)) {
+       if (offsetofend(typeof(resp), eth_min_inline) <= udata->outlen) {
                if (mlx5_ib_port_link_layer(ibdev, 1) == IB_LINK_LAYER_ETHERNET) {
                        mlx5_query_min_inline(dev->mdev, &resp.eth_min_inline);
                        resp.eth_min_inline++;
@@ -1918,7 +1921,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
                resp.response_length += sizeof(resp.eth_min_inline);
        }
 
-       if (field_avail(typeof(resp), clock_info_versions, udata->outlen)) {
+       if (offsetofend(typeof(resp), clock_info_versions) <= udata->outlen) {
                if (mdev->clock_info)
                        resp.clock_info_versions = BIT(MLX5_IB_CLOCK_INFO_V1);
                resp.response_length += sizeof(resp.clock_info_versions);
@@ -1930,7 +1933,7 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
         * pretend we don't support reading the HCA's core clock. This is also
         * forced by mmap function.
         */
-       if (field_avail(typeof(resp), hca_core_clock_offset, udata->outlen)) {
+       if (offsetofend(typeof(resp), hca_core_clock_offset) <= udata->outlen) {
                if (PAGE_SIZE <= 4096) {
                        resp.comp_mask |=
                                MLX5_IB_ALLOC_UCONTEXT_RESP_MASK_CORE_CLOCK_OFFSET;
@@ -1940,18 +1943,18 @@ static int mlx5_ib_alloc_ucontext(struct ib_ucontext *uctx,
                resp.response_length += sizeof(resp.hca_core_clock_offset);
        }
 
-       if (field_avail(typeof(resp), log_uar_size, udata->outlen))
+       if (offsetofend(typeof(resp), log_uar_size) <= udata->outlen)
                resp.response_length += sizeof(resp.log_uar_size);
 
-       if (field_avail(typeof(resp), num_uars_per_page, udata->outlen))
+       if (offsetofend(typeof(resp), num_uars_per_page) <= udata->outlen)
                resp.response_length += sizeof(resp.num_uars_per_page);
 
-       if (field_avail(typeof(resp), num_dyn_bfregs, udata->outlen)) {
+       if (offsetofend(typeof(resp), num_dyn_bfregs) <= udata->outlen) {
                resp.num_dyn_bfregs = bfregi->num_dyn_bfregs;
                resp.response_length += sizeof(resp.num_dyn_bfregs);
        }
 
-       if (field_avail(typeof(resp), dump_fill_mkey, udata->outlen)) {
+       if (offsetofend(typeof(resp), dump_fill_mkey) <= udata->outlen) {
                if (MLX5_CAP_GEN(dev->mdev, dump_fill_mkey)) {
                        resp.dump_fill_mkey = dump_fill_mkey;
                        resp.comp_mask |=
@@ -2026,6 +2029,17 @@ static phys_addr_t uar_index2pfn(struct mlx5_ib_dev *dev,
        return (dev->mdev->bar_addr >> PAGE_SHIFT) + uar_idx / fw_uars_per_page;
 }
 
+static u64 uar_index2paddress(struct mlx5_ib_dev *dev,
+                                int uar_idx)
+{
+       unsigned int fw_uars_per_page;
+
+       fw_uars_per_page = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
+                               MLX5_UARS_IN_PAGE : 1;
+
+       return (dev->mdev->bar_addr + (uar_idx / fw_uars_per_page) * PAGE_SIZE);
+}
+
 static int get_command(unsigned long offset)
 {
        return (offset >> MLX5_IB_MMAP_CMD_SHIFT) & MLX5_IB_MMAP_CMD_MASK;
@@ -2110,6 +2124,11 @@ static void mlx5_ib_mmap_free(struct rdma_user_mmap_entry *entry)
                mutex_unlock(&var_table->bitmap_lock);
                kfree(mentry);
                break;
+       case MLX5_IB_MMAP_TYPE_UAR_WC:
+       case MLX5_IB_MMAP_TYPE_UAR_NC:
+               mlx5_cmd_free_uar(dev->mdev, mentry->page_idx);
+               kfree(mentry);
+               break;
        default:
                WARN_ON(true);
        }
@@ -2130,6 +2149,9 @@ static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
        int max_valid_idx = dyn_uar ? bfregi->num_sys_pages :
                                bfregi->num_static_sys_pages;
 
+       if (bfregi->lib_uar_dyn)
+               return -EINVAL;
+
        if (vma->vm_end - vma->vm_start != PAGE_SIZE)
                return -EINVAL;
 
@@ -2147,14 +2169,6 @@ static int uar_mmap(struct mlx5_ib_dev *dev, enum mlx5_ib_mmap_cmd cmd,
        switch (cmd) {
        case MLX5_IB_MMAP_WC_PAGE:
        case MLX5_IB_MMAP_ALLOC_WC:
-/* Some architectures don't support WC memory */
-#if defined(CONFIG_X86)
-               if (!pat_enabled())
-                       return -EPERM;
-#elif !(defined(CONFIG_PPC) || (defined(CONFIG_ARM) && defined(CONFIG_MMU)))
-                       return -EPERM;
-#endif
-       /* fall through */
        case MLX5_IB_MMAP_REGULAR_PAGE:
                /* For MLX5_IB_MMAP_REGULAR_PAGE do the best effort to get WC */
                prot = pgprot_writecombine(vma->vm_page_prot);
@@ -2269,7 +2283,8 @@ static int mlx5_ib_mmap_offset(struct mlx5_ib_dev *dev,
 
        mentry = to_mmmap(entry);
        pfn = (mentry->address >> PAGE_SHIFT);
-       if (mentry->mmap_flag == MLX5_IB_MMAP_TYPE_VAR)
+       if (mentry->mmap_flag == MLX5_IB_MMAP_TYPE_VAR ||
+           mentry->mmap_flag == MLX5_IB_MMAP_TYPE_UAR_NC)
                prot = pgprot_noncached(vma->vm_page_prot);
        else
                prot = pgprot_writecombine(vma->vm_page_prot);
@@ -2300,9 +2315,12 @@ static int mlx5_ib_mmap(struct ib_ucontext *ibcontext, struct vm_area_struct *vm
        command = get_command(vma->vm_pgoff);
        switch (command) {
        case MLX5_IB_MMAP_WC_PAGE:
+       case MLX5_IB_MMAP_ALLOC_WC:
+               if (!dev->wc_support)
+                       return -EPERM;
+               fallthrough;
        case MLX5_IB_MMAP_NC_PAGE:
        case MLX5_IB_MMAP_REGULAR_PAGE:
-       case MLX5_IB_MMAP_ALLOC_WC:
                return uar_mmap(dev, command, vma, context);
 
        case MLX5_IB_MMAP_GET_CONTIGUOUS_PAGES:
@@ -6095,9 +6113,9 @@ static void mlx5_ib_cleanup_multiport_master(struct mlx5_ib_dev *dev)
        mlx5_nic_vport_disable_roce(dev->mdev);
 }
 
-static int var_obj_cleanup(struct ib_uobject *uobject,
-                          enum rdma_remove_reason why,
-                          struct uverbs_attr_bundle *attrs)
+static int mmap_obj_cleanup(struct ib_uobject *uobject,
+                           enum rdma_remove_reason why,
+                           struct uverbs_attr_bundle *attrs)
 {
        struct mlx5_user_mmap_entry *obj = uobject->object;
 
@@ -6105,6 +6123,16 @@ static int var_obj_cleanup(struct ib_uobject *uobject,
        return 0;
 }
 
+static int mlx5_rdma_user_mmap_entry_insert(struct mlx5_ib_ucontext *c,
+                                           struct mlx5_user_mmap_entry *entry,
+                                           size_t length)
+{
+       return rdma_user_mmap_entry_insert_range(
+               &c->ibucontext, &entry->rdma_entry, length,
+               (MLX5_IB_MMAP_OFFSET_START << 16),
+               ((MLX5_IB_MMAP_OFFSET_END << 16) + (1UL << 16) - 1));
+}
+
 static struct mlx5_user_mmap_entry *
 alloc_var_entry(struct mlx5_ib_ucontext *c)
 {
@@ -6135,10 +6163,8 @@ alloc_var_entry(struct mlx5_ib_ucontext *c)
        entry->page_idx = page_idx;
        entry->mmap_flag = MLX5_IB_MMAP_TYPE_VAR;
 
-       err = rdma_user_mmap_entry_insert_range(
-               &c->ibucontext, &entry->rdma_entry, var_table->stride_size,
-               MLX5_IB_MMAP_OFFSET_START << 16,
-               (MLX5_IB_MMAP_OFFSET_END << 16) + (1UL << 16) - 1);
+       err = mlx5_rdma_user_mmap_entry_insert(c, entry,
+                                              var_table->stride_size);
        if (err)
                goto err_insert;
 
@@ -6222,7 +6248,7 @@ DECLARE_UVERBS_NAMED_METHOD_DESTROY(
                        UA_MANDATORY));
 
 DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_VAR,
-                           UVERBS_TYPE_ALLOC_IDR(var_obj_cleanup),
+                           UVERBS_TYPE_ALLOC_IDR(mmap_obj_cleanup),
                            &UVERBS_METHOD(MLX5_IB_METHOD_VAR_OBJ_ALLOC),
                            &UVERBS_METHOD(MLX5_IB_METHOD_VAR_OBJ_DESTROY));
 
@@ -6234,6 +6260,134 @@ static bool var_is_supported(struct ib_device *device)
                        MLX5_GENERAL_OBJ_TYPES_CAP_VIRTIO_NET_Q);
 }
 
+static struct mlx5_user_mmap_entry *
+alloc_uar_entry(struct mlx5_ib_ucontext *c,
+               enum mlx5_ib_uapi_uar_alloc_type alloc_type)
+{
+       struct mlx5_user_mmap_entry *entry;
+       struct mlx5_ib_dev *dev;
+       u32 uar_index;
+       int err;
+
+       entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+       if (!entry)
+               return ERR_PTR(-ENOMEM);
+
+       dev = to_mdev(c->ibucontext.device);
+       err = mlx5_cmd_alloc_uar(dev->mdev, &uar_index);
+       if (err)
+               goto end;
+
+       entry->page_idx = uar_index;
+       entry->address = uar_index2paddress(dev, uar_index);
+       if (alloc_type == MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF)
+               entry->mmap_flag = MLX5_IB_MMAP_TYPE_UAR_WC;
+       else
+               entry->mmap_flag = MLX5_IB_MMAP_TYPE_UAR_NC;
+
+       err = mlx5_rdma_user_mmap_entry_insert(c, entry, PAGE_SIZE);
+       if (err)
+               goto err_insert;
+
+       return entry;
+
+err_insert:
+       mlx5_cmd_free_uar(dev->mdev, uar_index);
+end:
+       kfree(entry);
+       return ERR_PTR(err);
+}
+
+static int UVERBS_HANDLER(MLX5_IB_METHOD_UAR_OBJ_ALLOC)(
+       struct uverbs_attr_bundle *attrs)
+{
+       struct ib_uobject *uobj = uverbs_attr_get_uobject(
+               attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_HANDLE);
+       enum mlx5_ib_uapi_uar_alloc_type alloc_type;
+       struct mlx5_ib_ucontext *c;
+       struct mlx5_user_mmap_entry *entry;
+       u64 mmap_offset;
+       u32 length;
+       int err;
+
+       c = to_mucontext(ib_uverbs_get_ucontext(attrs));
+       if (IS_ERR(c))
+               return PTR_ERR(c);
+
+       err = uverbs_get_const(&alloc_type, attrs,
+                              MLX5_IB_ATTR_UAR_OBJ_ALLOC_TYPE);
+       if (err)
+               return err;
+
+       if (alloc_type != MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF &&
+           alloc_type != MLX5_IB_UAPI_UAR_ALLOC_TYPE_NC)
+               return -EOPNOTSUPP;
+
+       if (!to_mdev(c->ibucontext.device)->wc_support &&
+           alloc_type == MLX5_IB_UAPI_UAR_ALLOC_TYPE_BF)
+               return -EOPNOTSUPP;
+
+       entry = alloc_uar_entry(c, alloc_type);
+       if (IS_ERR(entry))
+               return PTR_ERR(entry);
+
+       mmap_offset = mlx5_entry_to_mmap_offset(entry);
+       length = entry->rdma_entry.npages * PAGE_SIZE;
+       uobj->object = entry;
+
+       err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_OFFSET,
+                            &mmap_offset, sizeof(mmap_offset));
+       if (err)
+               goto err;
+
+       err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_PAGE_ID,
+                            &entry->page_idx, sizeof(entry->page_idx));
+       if (err)
+               goto err;
+
+       err = uverbs_copy_to(attrs, MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_LENGTH,
+                            &length, sizeof(length));
+       if (err)
+               goto err;
+
+       return 0;
+
+err:
+       rdma_user_mmap_entry_remove(&entry->rdma_entry);
+       return err;
+}
+
+DECLARE_UVERBS_NAMED_METHOD(
+       MLX5_IB_METHOD_UAR_OBJ_ALLOC,
+       UVERBS_ATTR_IDR(MLX5_IB_ATTR_UAR_OBJ_ALLOC_HANDLE,
+                       MLX5_IB_OBJECT_UAR,
+                       UVERBS_ACCESS_NEW,
+                       UA_MANDATORY),
+       UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_UAR_OBJ_ALLOC_TYPE,
+                            enum mlx5_ib_uapi_uar_alloc_type,
+                            UA_MANDATORY),
+       UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_UAR_OBJ_ALLOC_PAGE_ID,
+                          UVERBS_ATTR_TYPE(u32),
+                          UA_MANDATORY),
+       UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_LENGTH,
+                          UVERBS_ATTR_TYPE(u32),
+                          UA_MANDATORY),
+       UVERBS_ATTR_PTR_OUT(MLX5_IB_ATTR_UAR_OBJ_ALLOC_MMAP_OFFSET,
+                           UVERBS_ATTR_TYPE(u64),
+                           UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_METHOD_DESTROY(
+       MLX5_IB_METHOD_UAR_OBJ_DESTROY,
+       UVERBS_ATTR_IDR(MLX5_IB_ATTR_UAR_OBJ_DESTROY_HANDLE,
+                       MLX5_IB_OBJECT_UAR,
+                       UVERBS_ACCESS_DESTROY,
+                       UA_MANDATORY));
+
+DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_UAR,
+                           UVERBS_TYPE_ALLOC_IDR(mmap_obj_cleanup),
+                           &UVERBS_METHOD(MLX5_IB_METHOD_UAR_OBJ_ALLOC),
+                           &UVERBS_METHOD(MLX5_IB_METHOD_UAR_OBJ_DESTROY));
+
 ADD_UVERBS_ATTRIBUTES_SIMPLE(
        mlx5_ib_dm,
        UVERBS_OBJECT_DM,
@@ -6258,12 +6412,14 @@ ADD_UVERBS_ATTRIBUTES_SIMPLE(
 static const struct uapi_definition mlx5_ib_defs[] = {
        UAPI_DEF_CHAIN(mlx5_ib_devx_defs),
        UAPI_DEF_CHAIN(mlx5_ib_flow_defs),
+       UAPI_DEF_CHAIN(mlx5_ib_qos_defs),
 
        UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION,
                                &mlx5_ib_flow_action),
        UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_DM, &mlx5_ib_dm),
        UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_VAR,
                                UAPI_DEF_IS_OBJ_SUPPORTED(var_is_supported)),
+       UAPI_DEF_CHAIN_OBJ_TREE_NAMED(MLX5_IB_OBJECT_UAR),
        {}
 };
 
@@ -6397,7 +6553,7 @@ static int mlx5_ib_stage_init_init(struct mlx5_ib_dev *dev)
        spin_lock_init(&dev->reset_flow_resource_lock);
        xa_init(&dev->odp_mkeys);
        xa_init(&dev->sig_mrs);
-       spin_lock_init(&dev->mkey_lock);
+       atomic_set(&dev->mkey_var, 0);
 
        spin_lock_init(&dev->dm.lock);
        dev->dm.dev = mdev;
@@ -6553,7 +6709,8 @@ static int mlx5_ib_init_var_table(struct mlx5_ib_dev *dev)
                                        doorbell_bar_offset);
        bar_size = (1ULL << log_doorbell_bar_size) * 4096;
        var_table->stride_size = 1ULL << log_doorbell_stride;
-       var_table->num_var_hw_entries = div64_u64(bar_size, var_table->stride_size);
+       var_table->num_var_hw_entries = div_u64(bar_size,
+                                               var_table->stride_size);
        mutex_init(&var_table->bitmap_lock);
        var_table->bitmap = bitmap_zalloc(var_table->num_var_hw_entries,
                                          GFP_KERNEL);
@@ -7085,6 +7242,9 @@ const struct mlx5_ib_profile raw_eth_profile = {
        STAGE_CREATE(MLX5_IB_STAGE_COUNTERS,
                     mlx5_ib_stage_counters_init,
                     mlx5_ib_stage_counters_cleanup),
+       STAGE_CREATE(MLX5_IB_STAGE_CONG_DEBUGFS,
+                    mlx5_ib_stage_cong_debugfs_init,
+                    mlx5_ib_stage_cong_debugfs_cleanup),
        STAGE_CREATE(MLX5_IB_STAGE_UAR,
                     mlx5_ib_stage_uar_init,
                     mlx5_ib_stage_uar_cleanup),