IB/uverbs: Add support to advise_mr

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>
This commit is contained in:
Moni Shoua 2018-12-11 13:37:52 +02:00 committed by Jason Gunthorpe
parent cbfdd442c4
commit ad8a449675
4 changed files with 76 additions and 1 deletions

View File

@ -39,6 +39,42 @@ static int uverbs_free_mr(struct ib_uobject *uobject,
return ib_dereg_mr((struct ib_mr *)uobject->object); 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)( static int UVERBS_HANDLER(UVERBS_METHOD_DM_MR_REG)(
struct uverbs_attr_bundle *attrs) struct uverbs_attr_bundle *attrs)
{ {
@ -114,6 +150,23 @@ err_dereg:
return ret; return ret;
} }
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( DECLARE_UVERBS_NAMED_METHOD(
UVERBS_METHOD_DM_MR_REG, UVERBS_METHOD_DM_MR_REG,
UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE, UVERBS_ATTR_IDR(UVERBS_ATTR_REG_DM_MR_HANDLE,
@ -154,7 +207,8 @@ DECLARE_UVERBS_NAMED_OBJECT(
UVERBS_OBJECT_MR, UVERBS_OBJECT_MR,
UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr), UVERBS_TYPE_ALLOC_IDR(uverbs_free_mr),
&UVERBS_METHOD(UVERBS_METHOD_DM_MR_REG), &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[] = { const struct uapi_definition uverbs_def_obj_mr[] = {
UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR, UAPI_DEF_CHAIN_OBJ_TREE_NAMED(UVERBS_OBJECT_MR,

View File

@ -2415,6 +2415,10 @@ struct ib_device_ops {
int (*dereg_mr)(struct ib_mr *mr); int (*dereg_mr)(struct ib_mr *mr);
struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type, struct ib_mr *(*alloc_mr)(struct ib_pd *pd, enum ib_mr_type mr_type,
u32 max_num_sg); 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, int (*map_mr_sg)(struct ib_mr *mr, struct scatterlist *sg, int sg_nents,
unsigned int *sg_offset); unsigned int *sg_offset);
int (*check_mr_status)(struct ib_mr *mr, u32 check_mask, int (*check_mr_status)(struct ib_mr *mr, u32 check_mask,

View File

@ -147,12 +147,20 @@ enum uverbs_attrs_reg_dm_mr_cmd_attr_ids {
enum uverbs_methods_mr { enum uverbs_methods_mr {
UVERBS_METHOD_DM_MR_REG, UVERBS_METHOD_DM_MR_REG,
UVERBS_METHOD_MR_DESTROY, UVERBS_METHOD_MR_DESTROY,
UVERBS_METHOD_ADVISE_MR,
}; };
enum uverbs_attrs_mr_destroy_ids { enum uverbs_attrs_mr_destroy_ids {
UVERBS_ATTR_DESTROY_MR_HANDLE, 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 { enum uverbs_attrs_create_counters_cmd_attr_ids {
UVERBS_ATTR_CREATE_COUNTERS_HANDLE, UVERBS_ATTR_CREATE_COUNTERS_HANDLE,
}; };

View File

@ -157,4 +157,13 @@ enum ib_uverbs_read_counters_flags {
IB_UVERBS_READ_COUNTERS_PREFER_CACHED = 1 << 0, 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 #endif