From 215e32169e2dc9b82afde7b403226f4c4a7c89a6 Mon Sep 17 00:00:00 2001 From: Jianxin Xiong Date: Sun, 18 Aug 2024 16:53:34 -0700 Subject: [PATCH] core: Introduce MR with dynamic keys Memory registration consists of two parts: map/pin the memory for local access and export with a key for remote access. The first part is usually heavyweight and requries kernel involvement. The second part is less expensive and can be further separated into key allocation and key assignment. Key allocation may needs kernel involvement, but key assignment can be done in user space. This leads to the concept of MR with dynamic key. Dynamic key allows an MR be exported as different keys for different target, with the option to expose different address range and access rights, all without the overhead of registering the MR multiple times in the standard way. A new flag FI_MR_DYNAMIC_KEY is introduces to be used with memory registration calls. This flag also serves as a secondary capbility. New API functions are added to allocate / assign / revoke keys. Another flag FI_MR_SINGLE_USE is added for single use key assignment. Signed-off-by: Jianxin Xiong --- include/rdma/fabric.h | 5 +++ include/rdma/fi_domain.h | 47 ++++++++++++++++++++++++ man/fi_getinfo.3.md | 7 +++- man/fi_mr.3.md | 77 ++++++++++++++++++++++++++++++++++++++-- 4 files changed, 133 insertions(+), 3 deletions(-) diff --git a/include/rdma/fabric.h b/include/rdma/fabric.h index ceaf9f81daa..5a7704a87a1 100644 --- a/include/rdma/fabric.h +++ b/include/rdma/fabric.h @@ -158,6 +158,8 @@ typedef struct fid *fid_t; #define FI_MATCH_COMPLETE (1ULL << 31) #define FI_PEER_TRANSFER (1ULL << 36) +#define FI_MR_SINGLE_USE (1ULL << 38) +#define FI_MR_DYNAMIC_KEY (1ULL << 39) #define FI_MR_DMABUF (1ULL << 40) #define FI_AV_USER_ID (1ULL << 41) #define FI_PEER (1ULL << 43) @@ -687,6 +689,9 @@ enum { FI_GET_VAL, /* struct fi_fid_var */ FI_SET_VAL, /* struct fi_fid_var */ FI_EXPORT_FID, /* struct fi_fid_export */ + FI_ALLOC_KEYS, /* struct fi_mr_alloc_keys */ + FI_ASSIGN_KEY, /* struct fi_mr_assign_key */ + FI_REVOKE_KEY, /* uint64_t key */ }; static inline int fi_control(struct fid *fid, int command, void *arg) diff --git a/include/rdma/fi_domain.h b/include/rdma/fi_domain.h index 548e4b6ad3e..ce967f1f44f 100644 --- a/include/rdma/fi_domain.h +++ b/include/rdma/fi_domain.h @@ -183,6 +183,21 @@ struct fi_mr_modify { struct fi_mr_attr attr; }; +struct fi_mr_alloc_keys { + size_t count; + uint64_t *keys; +}; + +struct fi_mr_assign_key { + uint64_t offset; + size_t len; + uint64_t access; + size_t auth_key_size; + uint8_t *auth_key; + uint64_t key; + uint64_t flags; +}; + #define FI_SET_OPS_HMEM_OVERRIDE "hmem_override_ops" struct fi_hmem_override_ops { @@ -489,6 +504,38 @@ static inline int fi_mr_enable(struct fid_mr *mr) return mr->fid.ops->control(&mr->fid, FI_ENABLE, NULL); } +static inline int +fi_mr_alloc_keys(struct fid_mr *mr, size_t count, uint64_t *keys) +{ + struct fi_mr_alloc_keys alloc = { + .count = count, + .keys = keys, + }; + return mr->fid.ops->control(&mr->fid, FI_ALLOC_KEYS, &alloc); +} + +static inline int +fi_mr_assign_key(struct fid_mr *mr, uint64_t offset, size_t len, + uint64_t access, size_t auth_key_size, uint8_t *auth_key, + uint64_t key, uint64_t flags) +{ + struct fi_mr_assign_key assign = { + .offset = offset, + .len = len, + .access = access, + .auth_key_size = auth_key_size, + .auth_key = auth_key, + .key = key, + .flags = flags, + }; + return mr->fid.ops->control(&mr->fid, FI_ASSIGN_KEY, &assign); +} + +static inline int fi_mr_revoke_key(struct fid_mr *mr, uint64_t key) +{ + return mr->fid.ops->control(&mr->fid, FI_REVOKE_KEY, &key); +} + static inline int fi_av_open(struct fid_domain *domain, struct fi_av_attr *attr, struct fid_av **av, void *context) diff --git a/man/fi_getinfo.3.md b/man/fi_getinfo.3.md index 347123415f1..3d5442abf54 100644 --- a/man/fi_getinfo.3.md +++ b/man/fi_getinfo.3.md @@ -312,6 +312,10 @@ additional optimizations. a shared memory provider, may only be used to communication between processes on the same system. +*FI_MR_DYNAMIC_KEY* +: Requests that the provider support the use of dynamic keys for memory + regions. See [`fi_mr`(3)](fi_mr.3.html) for more details. + *FI_MSG* : Specifies that an endpoint should support sending and receiving messages or datagrams. Message capabilities imply support for send @@ -463,7 +467,8 @@ Primary modifiers: FI_READ, FI_WRITE, FI_RECV, FI_SEND, FI_REMOTE_READ, FI_REMOTE_WRITE Secondary capabilities: FI_MULTI_RECV, FI_SOURCE, FI_RMA_EVENT, FI_SHARED_AV, -FI_TRIGGER, FI_FENCE, FI_LOCAL_COMM, FI_REMOTE_COMM, FI_SOURCE_ERR, FI_RMA_PMEM. +FI_TRIGGER, FI_FENCE, FI_LOCAL_COMM, FI_REMOTE_COMM, FI_SOURCE_ERR, FI_RMA_PMEM, +FI_MR_DYNAMIC_KEY. # MODE diff --git a/man/fi_mr.3.md b/man/fi_mr.3.md index 3a8e1fcd554..9309b854a65 100644 --- a/man/fi_mr.3.md +++ b/man/fi_mr.3.md @@ -40,6 +40,18 @@ fi_mr_refresh fi_mr_enable : Enables a memory region for use. +fi_mr_alloc_keys +: Allocate a set of keys to be used with a memory region opened with + FI_MR_DYNAMIC_KEY flag. + +fi_mr_assign_key +: Assign a key to a memory region (or part of it) opened with FI_MR_DYNAMIC_KEY + flag + +fi_mr_revoke_key +: Revoke a key previously assigned to a memory region (or part of it) opened + with FI_MR_DYNAMIC_KEY flag. + fi_hmem_ze_device : Returns an hmem device identifier for a level zero driver and device. @@ -80,6 +92,14 @@ int fi_mr_refresh(struct fid_mr *mr, const struct iovec *iov, int fi_mr_enable(struct fid_mr *mr); +int fi_mr_alloc_keys(struct fid_mr *mr, size_t count, uint64_t *keys); + +int fi_mr_assign_key(struct fid_mr *mr, uint64_t offset, size_t len, + uint64_t access, size_t auth_key_size, uint8_t *auth_key, uint64_t key, + uint64_t flags); + +int fi_mr_revoke_key(struct fid_mr *mr, uint64_t key); + int fi_hmem_ze_device(int driver_index, int device_index); ``` @@ -107,14 +127,17 @@ int fi_hmem_ze_device(int driver_index, int device_index); : Vectored memory buffer. *count* -: Count of vectored buffer entries. +: Count of vectored buffer entries. For fi_mr_alloc_keys, it is the number + of keys to allocate. *access* : Memory access permissions associated with registration *offset* : Optional specified offset for accessing specified registered buffers. - This parameter is reserved for future use and must be 0. + For fi_mr_assign_key, offset is the offset into the memory region that + combined with len defines the sub-region to assign the key to. For + other calls, this parameter is reserved for future use and must be 0. *requested_key* : Requested remote key associated with registered buffers. Parameter @@ -126,6 +149,19 @@ int fi_hmem_ze_device(int driver_index, int device_index); *flags* : Additional flags to apply to the operation. +*auth_key_size* +: The size of authorization_key. + +*auth_key* +: The authorization key to associate with the key to be assigned to the + memory region. + +*keys* +: Array of keys to be allocated. + +*key* +: Key to assign to or to remove from the memory region. + # DESCRIPTION Registered memory regions associate memory buffers with permissions @@ -565,6 +601,35 @@ must be explicitly enabled after being fully configured by the application. Any resource bindings to the MR must be done prior to enabling the MR. +## fi_mr_alloc_keys + +The fi_mr_alloc_keys call is used to allocate a set of keys to be used with +the memory region. The memory region must be opened with the FI_MR_DYNAMIC_KEY +flag. The number of keys to allocate is specified by the count parameter. +The allocated keys are stored in the keys array. + +## fi_mr_assign_key + +The fi_mr_assign_key call is used to assign a key to a memory region (or part +of it). The memory region must be opened with the FI_MR_DYNAMIC_KEY flag. +The key to assign is specified by the key parameter. The offset and len +parameters define the sub-region to assign the key to. The access parameter +specifies the access permissions associated with the key. The auth_key_size +and auth_key parameters are used to specify the authorization key associated +with the key. + +The operation accepts bitwise OR of the following flags. + +*FI_MR_SINGLE_USE* +: The key is valid for a single use. After the key is used, it is + automatically revoked. + +## fi_mr_revoke_key + +The fi_mr_revoke_key call is used to revoke a key previously assigned to a +memory region (or part of it). The memory region must be opened with the +FI_MR_DYNAMIC_KEY flag. The key to revoke is specified by the key parameter. + # MEMORY REGION ATTRIBUTES Memory regions are created using the following attributes. The struct @@ -900,6 +965,14 @@ The follow flag may be specified to any memory registration call. fi_mr_attr structure. This flag is only usable for domains opened with FI_HMEM capability support. +*FI_MR_DYNAMIC_KEY* +: This flag indicated that the memory region will be associated with dynamic + keys. A key is assigned to the memory region using fi_mr_assign_key and is + removed from the memory region fi_mr_revoke__key. Valid keys are allocated + in advance using fi_mr_alloc_keys. A memory region can have multiple keys + assigned to it, each with a different access permission, authorization key + and address range. + *FI_AUTH_KEY* : Only valid with domains configured with FI_AV_AUTH_KEY. When used with fi_mr_regattr, this flag denotes that the fi_mr_auth_key::src_addr field