IB/uverbs: Add support to advise_mr
authorMoni Shoua <monis@mellanox.com>
Tue, 11 Dec 2018 11:37:52 +0000 (13:37 +0200)
committerJason Gunthorpe <jgg@mellanox.com>
Tue, 18 Dec 2018 22:19:46 +0000 (15:19 -0700)
Add new ioctl method for the MR object - ADVISE_MR.

This command can be used by users to give an advice or directions to the
kernel about an address range that belongs to memory regions.

A new ib_device callback, advise_mr(), is introduced here to suupport the
new command. This command takes the following arguments:

- pd: The protection domain to which all memory regions belong
- advice:  The type of the advice
   * IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH - Pre-fetch a range of
an on-demand paging MR
   * IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH_WRITE - Pre-fetch a range
of an on-demand paging MR with write intention
- flags: The properties of the advice
* IB_UVERBS_ADVISE_MR_FLAG_FLUSH - Operation must end before
return to the caller
- sg_list: The list of memory ranges
- num_sge: The number of memory ranges in the list
- attrs: More attributes to be parsed by the provider

Signed-off-by: Moni Shoua <monis@mellanox.com>
Reviewed-by: Guy Levi <guyle@mellanox.com>
Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/uverbs_std_types_mr.c
include/rdma/ib_verbs.h
include/uapi/rdma/ib_user_ioctl_cmds.h
include/uapi/rdma/ib_user_ioctl_verbs.h

index a034352..71dfa5e 100644 (file)
@@ -39,6 +39,42 @@ static int uverbs_free_mr(struct ib_uobject *uobject,
        return ib_dereg_mr((struct ib_mr *)uobject->object);
 }
 
+static int UVERBS_HANDLER(UVERBS_METHOD_ADVISE_MR)(
+       struct uverbs_attr_bundle *attrs)
+{
+       struct ib_pd *pd =
+               uverbs_attr_get_obj(attrs, UVERBS_ATTR_ADVISE_MR_PD_HANDLE);
+       enum ib_uverbs_advise_mr_advice advice;
+       struct ib_device *ib_dev = pd->device;
+       struct ib_sge *sg_list;
+       u32 num_sge;
+       u32 flags;
+       int ret;
+
+       /* FIXME: Extend the UAPI_DEF_OBJ_NEEDS_FN stuff.. */
+       if (!ib_dev->ops.advise_mr)
+               return -EOPNOTSUPP;
+
+       ret = uverbs_get_const(&advice, attrs, UVERBS_ATTR_ADVISE_MR_ADVICE);
+       if (ret)
+               return ret;
+
+       ret = uverbs_get_flags32(&flags, attrs, UVERBS_ATTR_ADVISE_MR_FLAGS,
+                                IB_UVERBS_ADVISE_MR_FLAG_FLUSH);
+       if (ret)
+               return ret;
+
+       num_sge = uverbs_attr_ptr_get_array_size(
+               attrs, UVERBS_ATTR_ADVISE_MR_SGE_LIST, sizeof(struct ib_sge));
+       if (num_sge < 0)
+               return num_sge;
+
+       sg_list = uverbs_attr_get_alloced_ptr(attrs,
+                                             UVERBS_ATTR_ADVISE_MR_SGE_LIST);
+       return ib_dev->ops.advise_mr(pd, advice, flags, sg_list, num_sge,
+                                    attrs);
+}
+
 static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(
        struct uverbs_attr_bundle *attrs)
 {
@@ -115,6 +151,23 @@ err_dereg:
 }
 
 DECLARE_UVERBS_NAMED_METHOD(
+       UVERBS_METHOD_ADVISE_MR,
+       UVERBS_ATTR_IDR(UVERBS_ATTR_ADVISE_MR_PD_HANDLE,
+                       UVERBS_OBJECT_PD,
+                       UVERBS_ACCESS_READ,
+                       UA_MANDATORY),
+       UVERBS_ATTR_CONST_IN(UVERBS_ATTR_ADVISE_MR_ADVICE,
+                            enum ib_uverbs_advise_mr_advice,
+                            UA_MANDATORY),
+       UVERBS_ATTR_FLAGS_IN(UVERBS_ATTR_ADVISE_MR_FLAGS,
+                            enum ib_uverbs_advise_mr_flag,
+                            UA_MANDATORY),
+       UVERBS_ATTR_PTR_IN(UVERBS_ATTR_ADVISE_MR_SGE_LIST,
+                          UVERBS_ATTR_MIN_SIZE(sizeof(struct ib_uverbs_sge)),
+                          UA_MANDATORY,
+                          UA_ALLOC_AND_COPY));
+
+DECLARE_UVERBS_NAMED_METHOD(
        UVERBS_METHOD_DM_MR_REG,
        UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE,
                        UVERBS_OBJECT_MR,
@@ -154,7 +207,8 @@ DECLARE_UVERBS_NAMED_OBJECT(
        UVERBS_OBJECT_MR,
        UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr),
        &UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG),
-       &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY));
+       &UVERBS_METHOD(UVERBS_METHOD_MR_DESTROY),
+       &UVERBS_METHOD(UVERBS_METHOD_ADVISE_MR));
 
 const struct uapi_definition uverbs_def_obj_mr[] = {
        UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR,
index 5b3b51f..0ec15d6 100644 (file)
@@ -2415,6 +2415,10 @@ struct ib_device_ops {
        int (*dereg_mr)(struct ib_mr *mr);
        struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type,
                                  u32 max_num_sg);
+       int (*advise_mr)(struct ib_pd *pd,
+                        enum ib_uverbs_advise_mr_advice advice, u32 flags,
+                        struct ib_sge *sg_list, u32 num_sge,
+                        struct uverbs_attr_bundle *attrs);
        int (*map_mr_sg)(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
                         unsigned int *sg_offset);
        int (*check_mr_status)(struct ib_mr *mr, u32 check_mask,
index fbc92d0..f046478 100644 (file)
@@ -147,12 +147,20 @@ enum uverbs_attrs_reg_dm_mr_cmd_attr_ids {
 enum uverbs_methods_mr {
        UVERBS_METHOD_DM_MR_REG,
        UVERBS_METHOD_MR_DESTROY,
+       UVERBS_METHOD_ADVISE_MR,
 };
 
 enum uverbs_attrs_mr_destroy_ids {
        UVERBS_ATTR_DESTROY_MR_HANDLE,
 };
 
+enum uverbs_attrs_advise_mr_cmd_attr_ids {
+       UVERBS_ATTR_ADVISE_MR_PD_HANDLE,
+       UVERBS_ATTR_ADVISE_MR_ADVICE,
+       UVERBS_ATTR_ADVISE_MR_FLAGS,
+       UVERBS_ATTR_ADVISE_MR_SGE_LIST,
+};
+
 enum uverbs_attrs_create_counters_cmd_attr_ids {
        UVERBS_ATTR_CREATE_COUNTERS_HANDLE,
 };
index 6cdf192..9dcd345 100644 (file)
@@ -157,4 +157,13 @@ enum ib_uverbs_read_counters_flags {
        IB_UVERBS_READ_COUNTERS_PREFER_CACHED = 1 << 0,
 };
 
+enum ib_uverbs_advise_mr_advice {
+       IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH,
+       IB_UVERBS_ADVISE_MR_ADVICE_PREFETCH_WRITE,
+};
+
+enum ib_uverbs_advise_mr_flag {
+       IB_UVERBS_ADVISE_MR_FLAG_FLUSH = 1 << 0,
+};
+
 #endif