From cea4f8c0fdea9fc7edf189dc8e327e42995cba66 Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Tue, 19 Sep 2023 12:16:55 -0500 Subject: [PATCH 1/6] core: Support multiple auth keys per EP fi_domain_attr::max_ep_auth_key is used to reported the number of authorization keys supported by an endpoint. If this value is non-zero, connectionless endpoints must implement FI_AV_AUTH_KEY. FI_AV_AUTH_KEY is set by libfabric users via fi_domain_attr:::auth_key_size to denoted if MR and EP authorization keys from the AV instead of MR and EP attrs. When set, providers will ignore fi_ep_attr::auth_key during endpoint enable. From MRs, fi_mr_regattr() must be used with fi_mr_attr::auth_key pointing to a struct fi_mr_auth_key and fi_mr_attr:auth_key_size equal to sizeof(struct fi_mr_auth_key). fi_mr_auth_key::av should point to the AV the MR authorization keys should come from. If the domain is configured with FI_DIRECTED_RECV, fi_mr_auth_key::src_addr is used to restrict the MR to a specific fi_addr_t including authorization key fi_addr_t's. fi_av_insert_auth_key() output is an fi_addr_t handle specific to this authorization key. All operations, including AV operations data transfer operations, which may accept an auth_key fi_addr_t are required to pass in the FI_AUTH_KEY flag. If the EP is configured with FI_DIRECTED_RECV, this auth_key fi_addr_t can be used to match all EP addrs associated with this authorization key. Calling fi_av_remove() with this fi_addr_t will delete the authorization key. -FI_EBUSY will be returned from fi_av_remove() should this key still be used by en EP. In other words, all EPs using this authorization key need to be closed for fi_av_remove() to succeed. Once the AV is bound to an EP and the EP is successfully enabled, the EP will be configured to support all auth keys in the AV at that point in time. Users must provide an authorization key fi_addr_t with fi_av_insert_{addr, svc, sym}. This is done by using the fi_addr as input and setting the FI_AUTH_KEY flag. For fi_av_insert_{addr, sym}, since fi_addr may be an array, authorization key fi_addr_t's need to be specified for each index. The output of fi_av_insert_{addr, svc, sym} is an fi_addr_t mapping to a specific tuple. For FI_EADDRNOTAVAIL CQ errors, fi_cq_err_entry::src_addr will return the authorization key handle associated with the incoming data transfer. This, combined with the existing behavior of fi_cq_err_entry::err_data enables users to generate a fi_addr_t mapping to the specific tuple which triggered the FI_EADDRNOTAVAIL event. Signed-off-by: Ian Ziemba --- include/rdma/fabric.h | 3 ++- include/rdma/fi_domain.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/rdma/fabric.h b/include/rdma/fabric.h index ec37ba51128..a705ba6e200 100644 --- a/include/rdma/fabric.h +++ b/include/rdma/fabric.h @@ -190,7 +190,7 @@ typedef struct fid *fid_t; /* Tagged messages, buffered receives, CQ flags */ #define FI_CLAIM (1ULL << 59) #define FI_DISCARD (1ULL << 58) - +#define FI_AUTH_KEY (1ULL << 57) struct fi_ioc { void *addr; @@ -227,6 +227,7 @@ enum { #define FI_ADDR_NOTAVAIL ((uint64_t) -1) #define FI_KEY_NOTAVAIL ((uint64_t) -1) #define FI_SHARED_CONTEXT SIZE_MAX +#define FI_AV_AUTH_KEY SIZE_MAX typedef uint64_t fi_addr_t; enum fi_av_type { diff --git a/include/rdma/fi_domain.h b/include/rdma/fi_domain.h index 87d0bd36e06..224fd9c1ddc 100644 --- a/include/rdma/fi_domain.h +++ b/include/rdma/fi_domain.h @@ -102,6 +102,11 @@ struct fi_ops_av { char *buf, size_t *len); int (*av_set)(struct fid_av *av, struct fi_av_set_attr *attr, struct fid_av_set **av_set, void *context); + int (*insert_auth_key)(struct fid_av *av, const void *auth_key, + size_t auth_key_size, fi_addr_t *fi_addr, + uint64_t flags); + int (*lookup_auth_key)(struct fid_av *av, fi_addr_t fi_addr, + void *auth_key, size_t *auth_key_size); }; struct fid_av { @@ -142,6 +147,11 @@ struct fi_mr_dmabuf { void *base_addr; }; +struct fi_mr_auth_key { + struct fid_av *av; + fi_addr_t src_addr; +}; + struct fi_mr_attr { union { const struct iovec *mr_iov; @@ -533,6 +543,24 @@ fi_av_straddr(struct fid_av *av, const void *addr, char *buf, size_t *len) return av->ops->straddr(av, addr, buf, len); } +static inline int +fi_av_insert_auth_key(struct fid_av *av, const void *auth_key, + size_t auth_key_size, fi_addr_t *fi_addr, uint64_t flags) +{ + return FI_CHECK_OP(av->ops, struct fi_ops_av, insert_auth_key) ? + av->ops->insert_auth_key(av, auth_key, auth_key_size, fi_addr, + flags) : -FI_ENOSYS; +} + +static inline int +fi_av_lookup_auth_key(struct fid_av *av, fi_addr_t addr, void *auth_key, + size_t *auth_key_size) +{ + return FI_CHECK_OP(av->ops, struct fi_ops_av, lookup_auth_key) ? + av->ops->lookup_auth_key(av, addr, auth_key, auth_key_size) : + -FI_ENOSYS; +} + static inline fi_addr_t fi_rx_addr(fi_addr_t fi_addr, int rx_index, int rx_ctx_bits) { From d65b872fec5ab275f942cdca46d1a6f1c5c538a6 Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Tue, 19 Sep 2023 12:17:59 -0500 Subject: [PATCH 2/6] man: Doc FI_AV_AUTH_KEY FI_AV_AUTH_KEY is used to enable multiple auth keys per connectionless endpoint. Signed-off-by: Ian Ziemba --- man/fi_av.3.md | 134 ++++++++++++++++++++++++++++++++++++++----- man/fi_cq.3.md | 5 ++ man/fi_domain.3.md | 18 +++++- man/fi_endpoint.3.md | 4 ++ man/fi_mr.3.md | 39 +++++++++++++ man/fi_msg.3.md | 18 ++++-- man/fi_tagged.3.md | 18 ++++-- 7 files changed, 211 insertions(+), 25 deletions(-) diff --git a/man/fi_av.3.md b/man/fi_av.3.md index 2c9c3eb7453..ddea671de2a 100644 --- a/man/fi_av.3.md +++ b/man/fi_av.3.md @@ -24,6 +24,12 @@ fi_av_lookup fi_av_straddr : Convert an address into a printable string. +fi_av_insert_auth_key +: Insert an authorization key into the address vector. + +fi_av_lookup_auth_key +: Retrieve an authorization key stored in the address vector. + # SYNOPSIS ```c @@ -58,6 +64,12 @@ fi_addr_t fi_rx_addr(fi_addr_t fi_addr, int rx_index, const char * fi_av_straddr(struct fid_av *av, const void *addr, char *buf, size_t *len); + +int fi_av_insert_auth_key(struct fid_av *av, const void *auth_key, + size_t auth_key_size, fi_addr_t *fi_addr, uint64_t flags); + +int fi_av_lookup_auth_key(struct fid_av *av, fi_addr_t addr, + void *auth_key, size_t *auth_key_size); ``` # ARGUMENTS @@ -97,6 +109,14 @@ const char * fi_av_straddr(struct fid_av *av, const void *addr, *flags* : Additional flags to apply to the operation. +*auth_key* +: Buffer containing authorization key to be inserted into the address + vector. + +*auth_key_size* +: On input, specifies size of auth_key buffer. On output, stores number + of bytes written to auth_key buffer. + # DESCRIPTION Address vectors are used to map higher-level addresses, which may be @@ -328,6 +348,21 @@ that calls to fi_av_insert following a call to fi_av_remove always reference a valid buffer in the fi_addr parameter. Otherwise it may be difficult to determine what the next assigned index will be. +If the address vector is configured with authorization keys, the fi_addr +parameter may be used as input to define the authorization keys associated +with the endpoint addresses being inserted. This is done by setting the fi_addr to an +authorization key fi_addr_t generated from `fi_av_insert_auth_key` +and setting the FI_AUTH_KEY flag. If the FI_AUTH_KEY flag is not set, addresses +being inserted will not be associated with any authorization keys. Whether or not +an address can be disassociated with an authorization key is provider +specific. If a provider cannot support this disassociation, an error will be returned. +Upon successful insert with FI_AUTH_KEY flag, the returned fi_addr_t's will map to +endpoint address against the specified authorization keys. These fi_addr_t's can be +used as the target for local data transfer operations. + +If the endpoint supports `FI_DIRECTED_RECV`, these fi_addr_t's can be used to +restrict receive buffers to a specific endpoint address and authorization key. + *flags* : The following flag may be passed to AV insertion calls: fi_av_insert, fi_av_insertsvc, or fi_av_insertsym. @@ -354,6 +389,13 @@ determine what the next assigned index will be. - *FI_AV_USER_ID* : This flag associates a user-assigned identifier with each AV entry that is returned with any completion entry in place of the AV's address. + + This flag is invalid with FI_AV_AUTH_KEY. + +- *FI_AUTH_KEY* +: Denotes that the address being inserted should be associated with the + passed in authorization key fi_addr_t. + See the user ID section below. ## fi_av_insertsvc @@ -414,7 +456,17 @@ accessed. Inserted addresses are not required to be removed. fi_av_close will automatically cleanup any resources associated with addresses remaining in the AV when it is invoked. -Flags are reserved for future use and must be 0. +If the address being removed came from `fi_av_insert_auth_key`, the address +will only be removed if all endpoints, which have been enabled against the +corresponding authorization key, have been closed. If all endpoints are not +closed, -FI_EBUSY will be returned. In addition, the FI_AUTH_KEY flag must be +set when removing an authorization key fi_addr_t. + +*flags* +: The following flags may be used when removing an AV entry. + +- *FI_AUTH_KEY* +: Denotes that the fi_addr_t being removed is an authorization key fi_addr_t. ## fi_av_lookup @@ -450,6 +502,60 @@ size of the buffer needed to store the address. This size may be larger than the input len. If the provided buffer is too small, the results will be truncated. fi_av_straddr returns a pointer to buf. +## fi_av_insert_auth_key + +This function associates authorization keys with an address vector. This +requires the domain to be opened with `FI_AV_AUTH_KEY`. `FI_AV_AUTH_KEY` +enables endpoints and memory regions to be associated with authorization +keys from the address vector. This behavior enables a single endpoint +or memory region to be associated with multiple authorization keys. + +When endpoints or memory regions are enabled, they are configured with +address vector authorization keys at that point in time. Later authorization +key insertions will not propagate to already enabled endpoints and memory +regions. + +The `auth_key` and `auth_key_size` parameters are used to input the +authorization key into the address vector. The structure of the +authorization key is provider specific. If the `auth_key_size` does not align +with provider specific structure, -FI_EINVAL will be returned. + +The output of `fi_av_insert_auth_key` is an authorization key fi_addr_t +handle representing all endpoint addresses against this specific +authorization key. For all operations, including address vector, memory +registration, and data transfers, which may accept an authorization key +fi_addr_t as input, the FI_AUTH_KEY flag must be specified. Otherwise, +the fi_addr_t will be treated as an fi_addr_t returned from the `fi_av_insert` +and related functions. + +For endpoints enabled with FI_DIRECTED_RECV, authorization key fi_addr_t's +can be used to restrict incoming messages to only endpoint addresses +within the authorization key. This will require passing in the FI_AUTH_KEY +flag to `fi_recvmsg` and `fi_trecvmsg`. + +For domains enabled with FI_DIRECTED_RECV, authorization key fi_addr_t's can +be used to restrict memory region access to only endpoint addresses within the +authorization key. This will require passing in the FI_AUTH_KEY flag to +`fi_mr_regattr`. + +These authorization key fi_addr_t's can later be used an input for +endpoint address insertion functions to generate an fi_addr_t for a +specific endpoint address and authorization key. This will require passing in +the FI_AUTH_KEY flag to `fi_av_insert` and related functions. + +Flags are reserved for future use and must be 0. + +## fi_av_lookup_auth_key + +This functions returns the authorization key associated with a fi_addr_t. +Acceptable fi_addr_t's input are the output of `fi_av_insert_auth_key` and +AV address insertion functions. The returned authorization key is in a +provider specific format. On input, the auth_key_size parameter should +indicate the size of the auth_key buffer. If the actual authorization key +is larger than what can fit into the buffer, it will be truncated. On +output, auth_key_size is set to the size of the buffer needed to store the +authorization key, which may be larger than the input value. + # NOTES An AV should only store a single instance of an address. @@ -501,26 +607,24 @@ used for all data transfer operations. # RETURN VALUES -Insertion calls for an AV opened for synchronous operation will return -the number of addresses that were successfully inserted. In the case of -failure, the return value will be less than the number of addresses that -was specified. +Insertion calls, excluding `fi_av_insert_auth_key`, for an AV opened for +synchronous operation will return the number of addresses that were +successfully inserted. In the case of failure, the return value will be +less than the number of addresses that was specified. -Insertion calls for an AV opened for asynchronous operation (with FI_EVENT -flag specified) will return 0 if the operation was successfully initiated. -In the case of failure, a negative fabric errno will be returned. Providers -are allowed to abort insertion operations in the case of an error. Addresses -that are not inserted because they were aborted will fail with an error code -of FI_ECANCELED. +Insertion calls, excluding `fi_av_insert_auth_key`, for an AV opened for +asynchronous operation (with FI_EVENT flag specified) will return FI_SUCCESS +if the operation was successfully initiated. In the case of failure, a +negative fabric errno will be returned. Providers are allowed to abort +insertion operations in the case of an error. Addresses that are not inserted +because they were aborted will fail with an error code of FI_ECANCELED. In both the synchronous and asynchronous modes of operation, the fi_addr buffer associated with a failed or aborted insertion will be set to FI_ADDR_NOTAVAIL. -All other calls return 0 on success, or a negative value corresponding to -fabric errno on error. -Fabric errno values are defined in -`rdma/fi_errno.h`. +All other calls return FI_SUCCESS on success, or a negative value corresponding +to fabric errno on error. Fabric errno values are defined in `rdma/fi_errno.h`. # SEE ALSO diff --git a/man/fi_cq.3.md b/man/fi_cq.3.md index a990142cb08..23cf4899a70 100644 --- a/man/fi_cq.3.md +++ b/man/fi_cq.3.md @@ -448,6 +448,11 @@ Notable completion error codes are given below. passed directly into an fi_av_insert call to add the source address to the address vector. + For API versions 1.20 and later, if the EP is configured with + FI_AV_AUTH_KEY, src_addr will be set to the fi_addr_t authorization key + handle corresponding to the incoming data transfer. Otherwise, the + value will be set to FI_ADDR_NOTAVAIL. + ## fi_cq_signal The fi_cq_signal call will unblock any thread waiting in fi_cq_sread diff --git a/man/fi_domain.3.md b/man/fi_domain.3.md index 63504651144..0f3d2199092 100644 --- a/man/fi_domain.3.md +++ b/man/fi_domain.3.md @@ -704,6 +704,13 @@ that a single memory registration operation may reference. Domain level capabilities. Domain capabilities indicate domain level features that are supported by the provider. +The following are support primary capabilities: +*FI_DIRECTED_RECV* +: When the domain is configured with FI_DIRECTED_RECV and FI_AV_AUTH_KEY, + memory regions can be limited to specific authorization keys. + +The following are supported secondary capabilities: + *FI_LOCAL_COMM* : At a conceptual level, this field indicates that the underlying device supports loopback communication. More specifically, this field @@ -725,8 +732,7 @@ level features that are supported by the provider. feature. See [`fi_getinfo`(3)](fi_getinfo.3.html) for a discussion on primary versus -secondary capabilities. All domain capabilities are considered secondary -capabilities. +secondary capabilities. ## mode @@ -743,6 +749,9 @@ The default authorization key to associate with endpoint and memory registrations created within the domain. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If domain auth_key_size is set to the value FI_AV_AUTH_KEY, auth_key must be +NULL. + ## Default authorization key length (auth_key_size) The length in bytes of the default authorization key for the domain. If set to 0, @@ -751,6 +760,11 @@ registrations created within the domain unless specified in the endpoint or memory registration attributes. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If the size is set to the value FI_AV_AUTH_KEY, all endpoints and memory +regions will be configured to use authorization keys associated with the AV. +Providers which support authorization keys and connectionless endpoint must +support this option. + ## Max Error Data Size (max_err_data) : The maximum amount of error data, in bytes, that may be returned as part of a completion or event queue error. This value corresponds to the diff --git a/man/fi_endpoint.3.md b/man/fi_endpoint.3.md index b57dba4bc12..6534e991211 100644 --- a/man/fi_endpoint.3.md +++ b/man/fi_endpoint.3.md @@ -911,6 +911,8 @@ The length of the authorization key in bytes. This field will be 0 if authorization keys are not available or used. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If the domain is opened with FI_AV_AUTH_KEY, auth_key_size must be 0. + ## auth_key - Authorization Key If supported by the fabric, an authorization key (a.k.a. job @@ -923,6 +925,8 @@ cross traffic. The domain authorization key will be used if auth_key_size is set to 0. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If the domain is opened with FI_AV_AUTH_KEY, auth_key is must be NULL. + # TRANSMIT CONTEXT ATTRIBUTES Attributes specific to the transmit capabilities of an endpoint are diff --git a/man/fi_mr.3.md b/man/fi_mr.3.md index 2a975778127..2bfce5e3d59 100644 --- a/man/fi_mr.3.md +++ b/man/fi_mr.3.md @@ -379,12 +379,18 @@ must remain valid until the registration operation completes. The context specified with the registration request is returned with the completion event. +For domains opened with FI_AV_AUTH_KEY, fi_mr_reg is not supported +and fi_mr_regattr must be used. + ## fi_mr_regv The fi_mr_regv call adds support for a scatter-gather list to fi_mr_reg. Multiple memory buffers are registered as a single memory region. Otherwise, the operation is the same. +For domains opened with FI_AV_AUTH_KEY, fi_mr_regv is not supported +and fi_mr_regattr must be used. + ## fi_mr_regattr The fi_mr_regattr call is a more generic, extensible registration call @@ -534,6 +540,11 @@ struct fi_mr_attr { } device; void *hmem_data; }; + +struct fi_mr_auth_key { + struct fid_av *av; + fi_addr_t src_addr; +}; ``` ## mr_iov @@ -657,6 +668,9 @@ The size of key referenced by the auth_key field in bytes, or 0 if no authorizat key is given. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If the domain is opened with FI_AV_AUTH_KEY, auth_key_size must equal +`sizeof(struct fi_mr_auth_key)`. + ## auth_key Indicates the key to associate with this memory registration. Authorization @@ -666,6 +680,9 @@ region. The domain authorization key will be used if the auth_key_size provided is 0. This field is ignored unless the fabric is opened with API version 1.5 or greater. +If the domain is opened with FI_AV_AUTH_KEY, auth_key must point to a +user-defined `struct fi_mr_auth_key`. + ## iface Indicates the software interfaces used by the application to allocate and manage the memory region. This field is ignored unless the application has @@ -725,6 +742,21 @@ FI_HMEM_ZE interfaces. The driver and device index values represent their 0-based positions in arrays returned from zeDriverGet and zeDeviceGet, respectively. +## av + +For memory registration being allocated against a domain configured with +FI_AV_AUTH_KEY, av is used to define the fid_av which contains the authorization +keys to be associated with the memory region. If the domain is also opened with +FI_MR_ENDPOINT, the specified AV must be the same AV bound to the endpoint. + +By default, the memory region will be associated with all authorization keys +in the AV. + +## addr + +If the domain was opened with FI_DIRECTED_RECV, addr can be used to limit the +memory region to a specific fi_addr_t, including fi_addr_t's return from `fi_av_insert_auth_key`. + # NOTES Direct access to an application's memory by a remote peer requires that @@ -792,6 +824,13 @@ 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_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 + contains an authorization key fi_addr_t (i.e. fi_addr_t returned from + fi_av_insert_auth_key) instead of an endpoint fi_addr_t (i.e. fi_addr_t + return from fi_av_insert / fi_av_insertsvc / fi_av_remove). + # MEMORY DOMAINS Memory domains identify the physical separation of memory which diff --git a/man/fi_msg.3.md b/man/fi_msg.3.md index 170c08b2217..0e98f4d6fe5 100644 --- a/man/fi_msg.3.md +++ b/man/fi_msg.3.md @@ -78,10 +78,14 @@ ssize_t fi_injectdata(struct fid_ep *ep, const void *buf, size_t len, connected endpoints. *src_addr* -: Source address to receive from for connectionless transfers. Applies - only to connectionless endpoints with the FI_DIRECTED_RECV capability - enabled, otherwise this field is ignored. If set to FI_ADDR_UNSPEC, - any source address may match. +: Applies only to connectionless endpoints configured with the FI_DIRECTED_RECV. + For all other endpoint configurations, src_addr is ignored. src_addr defines + the source address to receive from. By default, the src_addr is treated as a + source endpoint address (i.e. fi_addr_t returned from fi_av_insert / + fi_av_insertsvc / fi_av_remove). If the FI_AUTH_KEY flag is specified with + fi_recvmsg, src_addr is treated as a source authorization key (i.e. fi_addr_t + returned from fi_av_insert_auth_key). If set to FI_ADDR_UNSPEC, any source + address may match. *msg* : Message descriptor for send and receive operations. @@ -305,6 +309,12 @@ fi_sendmsg. be used in all multicast transfers, in conjunction with a multicast fi_addr_t. +*FI_AUTH_KEY* +: Only valid with domains configured with FI_AV_AUTH_KEY and connectionless + endpoints configured with FI_DIRECTED_RECV. When used with fi_recvmsg, this + flag denotes that the src_addr is an authorization key fi_addr_t instead of + an endpoint fi_addr_t. + # Buffered Receives Buffered receives indicate that the networking layer allocates and diff --git a/man/fi_tagged.3.md b/man/fi_tagged.3.md index 34378600ddc..fd90bb32327 100644 --- a/man/fi_tagged.3.md +++ b/man/fi_tagged.3.md @@ -86,10 +86,14 @@ ssize_t fi_tinjectdata(struct fid_ep *ep, const void *buf, size_t len, connected endpoints. *src_addr* -: Source address to receive from for connectionless transfers. Applies - only to connectionless endpoints with the FI_DIRECTED_RECV capability - enabled, otherwise this field is ignored. If set to FI_ADDR_UNSPEC, - any source address may match. +: Applies only to connectionless endpoints configured with the FI_DIRECTED_RECV. + For all other endpoint configurations, src_addr is ignored. src_addr defines + the source address to receive from. By default, the src_addr is treated as a + source endpoint address (i.e. fi_addr_t returned from fi_av_insert / + fi_av_insertsvc / fi_av_remove). If the FI_AUTH_KEY flag is specified with + fi_trecvmsg, src_addr is treated as a source authorization key (i.e. fi_addr_t + returned from fi_av_insert_auth_key). If set to FI_ADDR_UNSPEC, any source + address may match. *msg* : Message descriptor for send and receive operations. @@ -285,6 +289,12 @@ and/or fi_tsendmsg. operation (inclusive) to the posting of a subsequent fenced operation (exclusive) is controlled by the endpoint's ordering semantics. +*FI_AUTH_KEY* +: Only valid with domains configured with FI_AV_AUTH_KEY and connectionless + endpoints configured with FI_DIRECTED_RECV. When used with fi_trecvmsg, this + flag denotes that the src_addr is an authorization key fi_addr_t instead of + an endpoint fi_addr_t. + The following flags may be used with fi_trecvmsg. *FI_PEEK* From 6c239dd24758d15c506d014114d15f617795b394 Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Tue, 26 Sep 2023 13:35:34 -0500 Subject: [PATCH 3/6] core: Define fi_av_set_user_id fi_av_set_user_id() is used to set the user id when the AV is opened with FI_AV_USER_ID. Signed-off-by: Ian Ziemba --- include/rdma/fi_domain.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/rdma/fi_domain.h b/include/rdma/fi_domain.h index 224fd9c1ddc..d2575e79500 100644 --- a/include/rdma/fi_domain.h +++ b/include/rdma/fi_domain.h @@ -107,6 +107,8 @@ struct fi_ops_av { uint64_t flags); int (*lookup_auth_key)(struct fid_av *av, fi_addr_t fi_addr, void *auth_key, size_t *auth_key_size); + int (*set_user_id)(struct fid_av *av, fi_addr_t fi_addr, + fi_addr_t user_id, uint64_t flags); }; struct fid_av { @@ -561,6 +563,14 @@ fi_av_lookup_auth_key(struct fid_av *av, fi_addr_t addr, void *auth_key, -FI_ENOSYS; } +static inline int +fi_av_set_user_id(struct fid_av *av, fi_addr_t fi_addr, fi_addr_t user_id, + uint64_t flags) +{ + return FI_CHECK_OP(av->ops, struct fi_ops_av, set_user_id) ? + av->ops->set_user_id(av, fi_addr, user_id, flags) : -FI_ENOSYS; +} + static inline fi_addr_t fi_rx_addr(fi_addr_t fi_addr, int rx_index, int rx_ctx_bits) { From 7fd3627f5ea4dd1ca4c49dce6c352c87987bfbeb Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Tue, 26 Sep 2023 12:03:07 -0500 Subject: [PATCH 4/6] man: Doc FI_AV_USER_ID primary cap Document FI_AV_USER_ID as a primary cap. In addition, define FI_AV_USER_ID as a new domain primary cap. This enables AVs to be opened with FI_AV_USER_ID. Define AV opened with FI_AV_USER_ID behavior. In addition, document how the existing FI_AV_USER_ID behavior can be used if FI_AV_USER_ID is not requested as a capability. Signed-off-by: Ian Ziemba --- man/fi_av.3.md | 103 +++++++++++++++++++++++++++++++++++--------- man/fi_cq.3.md | 5 ++- man/fi_domain.3.md | 7 +++ man/fi_getinfo.3.md | 7 +-- 4 files changed, 96 insertions(+), 26 deletions(-) diff --git a/man/fi_av.3.md b/man/fi_av.3.md index ddea671de2a..9e606a41104 100644 --- a/man/fi_av.3.md +++ b/man/fi_av.3.md @@ -30,6 +30,9 @@ fi_av_insert_auth_key fi_av_lookup_auth_key : Retrieve an authorization key stored in the address vector. +fi_av_set_user_id +: Set the user-defined fi_addr_t for an inserted fi_addr_t. + # SYNOPSIS ```c @@ -70,6 +73,9 @@ int fi_av_insert_auth_key(struct fid_av *av, const void *auth_key, int fi_av_lookup_auth_key(struct fid_av *av, fi_addr_t addr, void *auth_key, size_t *auth_key_size); + +int fi_av_set_user_id(struct fid_av *av, fi_addr_t fi_addr, + fi_addr_t user_id, uint64_t flags); ``` # ARGUMENTS @@ -117,6 +123,10 @@ int fi_av_lookup_auth_key(struct fid_av *av, fi_addr_t addr, : On input, specifies size of auth_key buffer. On output, stores number of bytes written to auth_key buffer. +*user_id* +: For address vectors configured with FI_AV_USER_ID, this defines the + user ID to be associated with a specific fi_addr_t. + # DESCRIPTION Address vectors are used to map higher-level addresses, which may be @@ -285,6 +295,13 @@ struct fi_av_attr { targets distributed applications on large fabrics and allows for highly-optimized storage of remote endpoint addressing. +- *FI_AV_USER_ID* +: Indicates that the user will be associating user-defined IDs with + a address vector via fi_av_set_user_id. If the domain has been configured + with FI_AV_AUTH_KEY or the user requires FI_AV_USER_ID support, using the + FI_AV_USER_ID flag per fi_av_insert / fi_av_insertsvc / fi_av_remove is + not supported. fi_av_set_user_id must be used. + ## fi_close The fi_close call is used to release all resources associated with an @@ -363,6 +380,11 @@ used as the target for local data transfer operations. If the endpoint supports `FI_DIRECTED_RECV`, these fi_addr_t's can be used to restrict receive buffers to a specific endpoint address and authorization key. +For address vectors configured with FI_AV_USER_ID, all subsequent target events +corresponding to the address being inserted will return FI_ADDR_NOTAVAIL until +the user defines a user ID for this fi_addr_t. This is done by using +fi_av_set_user_id. + *flags* : The following flag may be passed to AV insertion calls: fi_av_insert, fi_av_insertsvc, or fi_av_insertsym. @@ -387,10 +409,18 @@ restrict receive buffers to a specific endpoint address and authorization key. will be updated to 0. Failures will contain a fabric errno code. - *FI_AV_USER_ID* -: This flag associates a user-assigned identifier with each AV entry - that is returned with any completion entry in place of the AV's address. +: For address vectors configured without FI_AV_USER_ID specified, this + flag associates a user-assigned identifier with each AV entry that is + returned with any completion entry in place of the AV's address. + If a provider does not support FI_AV_USER_ID with insert, requesting + this flag during insert will result runtime failure. - This flag is invalid with FI_AV_AUTH_KEY. + Using the FI_AV_USER_ID flag per insert is invalid if the AV was + opened with the FI_AV_USER_ID or if the corresponding domain was + configured with FI_AV_AUTH_KEY. + + With libfabric 1.20, users are encouraged to specify the FI_AV_USER_ID + when opening an AV and use fi_av_set_user_id. - *FI_AUTH_KEY* : Denotes that the address being inserted should be associated with the @@ -543,6 +573,15 @@ endpoint address insertion functions to generate an fi_addr_t for a specific endpoint address and authorization key. This will require passing in the FI_AUTH_KEY flag to `fi_av_insert` and related functions. +For address vectors configured with FI_AV_USER_ID and endpoints with +FI_SOURCE_ERR, all subsequent FI_EADDRNOTAVAIL error events will return +FI_ADDR_NOTAVAIL until the user defines a user ID for this authorization key +fi_addr_t. This is done by using fi_av_set_user_id. + +For address vectors configured without FI_AV_USER_ID and endpoints with +FI_SOURCE_ERR, all subsequent FI_EADDRNOTAVAIL error events will return the +authorization key fi_addr_t handle. + Flags are reserved for future use and must be 0. ## fi_av_lookup_auth_key @@ -556,6 +595,19 @@ is larger than what can fit into the buffer, it will be truncated. On output, auth_key_size is set to the size of the buffer needed to store the authorization key, which may be larger than the input value. +## fi_av_set_user_id + +If the address vector has been opened with FI_AV_USER_ID, this function +defines the user ID for a specific fi_addr_t. By default, all fi_addr_t's +will be assigned the user ID FI_ADDR_NOTAVAIL. + +*flags* +: The following flag may be passed to AV set user id. + +- *FI_AUTH_KEY* +: Denotes that the fi_addr fi_addr_t, for which the user ID is being set for, + is an authorization key fi_addr_t. + # NOTES An AV should only store a single instance of an address. @@ -576,15 +628,20 @@ resources from removed entries. # USER IDENTIFIERS FOR ADDRESSES -As described above, endpoint addresses that are inserted into an AV are -mapped to an fi_addr_t value. The fi_addr_t is used in data transfer APIs -to specify the destination of an outbound transfer, in receive APIs to -indicate the source for an inbound transfer, and also in completion events -to report the source address of inbound transfers. The FI_AV_USER_ID -capability bit and flag provide a mechanism by which the fi_addr_t value -reported by a completion event is replaced with a user-specified value -instead. This is useful for applications that need to map the source -address to their own data structure. +As described above, endpoint addresses authorization keys that are +inserted into an AV are mapped to an fi_addr_t value. The endpoint +address fi_addr_t is used in data transfer APIs to specify the +destination of an outbound transfer, in receive APIs to indicate +the source for an inbound transfer, and also in completion events to +report the source address of inbound transfers. The authorization key +fi_addr_t are used in receive and MR APIs to resource incoming +operations to a specific authorization key, and also in completion +error events if the endpoint is configured with FI_SOURCE_ERR. The +FI_AV_USER_ID capability bit and flag provide a mechanism by which the +fi_addr_t value reported by a completion success or error event is +replaced with a user-specified value instead. This is useful for +applications that need to map the source address to their own data +structure. Support for FI_AV_USER_ID is provider specific, as it may not be feasible for a provider to implement this support without significant overhead. @@ -595,15 +652,19 @@ providers that do not support FI_AV_USER_ID, users may be able to trade off lookup processing with protocol overhead, by carrying source identification within a message header. -User-specified fi_addr_t values are provided as part of address insertion -(e.g. fi_av_insert) through the fi_addr parameter. The fi_addr parameter -acts as input/output in this case. When the FI_AV_USER_ID flag is passed -to any of the insert calls, the caller must specify an fi_addr_t identifier -value to associate with each address. The provider will record that -identifier and use it where required as part of any completion event. Note -that the output from the AV insertion call is unchanged. The provider will -return an fi_addr_t value that maps to each address, and that value must be -used for all data transfer operations. +For address vectors opened without FI_AV_USER_ID, user-specified fi_addr_t +values are provided as part of address insertion (e.g. fi_av_insert) +through the fi_addr parameter. The fi_addr parameter acts as input/output +in this case. When the FI_AV_USER_ID flag is passed to any of the insert +calls, the caller must specify an fi_addr_t identifier value to associate +with each address. The provider will record that identifier and use it +where required as part of any completion event. Note that the output from +the AV insertion call is unchanged. The provider will return an fi_addr_t +value that maps to each address, and that value must be used for all data +transfer operations. + +For address vectors opened with FI_AV_USER_ID, fi_av_set_user_id is used +to defined the user-specified fi_addr_t. # RETURN VALUES diff --git a/man/fi_cq.3.md b/man/fi_cq.3.md index 23cf4899a70..15ac8091b2a 100644 --- a/man/fi_cq.3.md +++ b/man/fi_cq.3.md @@ -450,8 +450,9 @@ Notable completion error codes are given below. For API versions 1.20 and later, if the EP is configured with FI_AV_AUTH_KEY, src_addr will be set to the fi_addr_t authorization key - handle corresponding to the incoming data transfer. Otherwise, the - value will be set to FI_ADDR_NOTAVAIL. + handle or a user-define authorization key ID corresponding to the + incoming data transfer. Otherwise, the value will be set to + FI_ADDR_NOTAVAIL. ## fi_cq_signal diff --git a/man/fi_domain.3.md b/man/fi_domain.3.md index 0f3d2199092..e98b96d2c8c 100644 --- a/man/fi_domain.3.md +++ b/man/fi_domain.3.md @@ -709,6 +709,13 @@ The following are support primary capabilities: : When the domain is configured with FI_DIRECTED_RECV and FI_AV_AUTH_KEY, memory regions can be limited to specific authorization keys. +*FI_AV_USER_ID* +: Indicates that the domain supports the ability to open address vectors + with the FI_AV_USER_ID flag. If this domain capability is not set, + address vectors cannot be opened with FI_AV_USER_ID. Note that + FI_AV_USER_ID can still be supported through the AV insert calls without + this domain capability set. See [`fi_av`(3)](fi_av.3.html). + The following are supported secondary capabilities: *FI_LOCAL_COMM* diff --git a/man/fi_getinfo.3.md b/man/fi_getinfo.3.md index 7f3c78fec55..766c2e1033f 100644 --- a/man/fi_getinfo.3.md +++ b/man/fi_getinfo.3.md @@ -274,8 +274,9 @@ additional optimizations. *FI_AV_USER_ID* : Requests that the provider support the association of a user specified identifier with each address vector (AV) address. User identifiers are - returned with completion data in place of the AV address. See [`fi_av`(3)] - (fi_av.3.html) for more details. + returned with completion data in place of the AV address. See + [`fi_domain`(3)](fi_domain.3.html) and [`fi_av`(3)] (fi_av.3.html) for + more details. *FI_COLLECTIVE* : Requests support for collective operations. Endpoints that support @@ -466,7 +467,7 @@ would not compromise performance or security. Primary capabilities: FI_MSG, FI_RMA, FI_TAGGED, FI_ATOMIC, FI_MULTICAST, FI_NAMED_RX_CTX, FI_DIRECTED_RECV, FI_VARIABLE_MSG, FI_HMEM, FI_COLLECTIVE, -FI_XPU +FI_XPU, FI_AV_USER_ID Primary modifiers: FI_READ, FI_WRITE, FI_RECV, FI_SEND, FI_REMOTE_READ, FI_REMOTE_WRITE From c24eae7030323061aa09fd31b0054b50c05865a5 Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Thu, 26 Oct 2023 17:57:03 -0500 Subject: [PATCH 5/6] util: Define domain primary and secondary caps Signed-off-by: Ian Ziemba --- include/ofi.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/ofi.h b/include/ofi.h index 55bdb1f08bc..71203c3822e 100644 --- a/include/ofi.h +++ b/include/ofi.h @@ -104,12 +104,16 @@ extern "C" { (FI_MULTI_RECV | FI_TRIGGER | FI_RMA_PMEM | FI_SOURCE | \ FI_RMA_EVENT | FI_SOURCE_ERR) -#define OFI_PRIMARY_CAPS \ - (OFI_PRIMARY_TX_CAPS | OFI_PRIMARY_RX_CAPS) +#define OFI_DOMAIN_PRIMARY_CAPS FI_AV_USER_ID +#define OFI_DOMAIN_SECONDARY_CAPS \ + (FI_SHARED_AV | FI_REMOTE_COMM | FI_LOCAL_COMM) -#define OFI_SECONDARY_CAPS \ - (OFI_SECONDARY_TX_CAPS | OFI_SECONDARY_RX_CAPS | \ - FI_SHARED_AV | FI_REMOTE_COMM | FI_LOCAL_COMM) + #define OFI_PRIMARY_CAPS \ + (OFI_PRIMARY_TX_CAPS | OFI_PRIMARY_RX_CAPS | OFI_DOMAIN_PRIMARY_CAPS) + + #define OFI_SECONDARY_CAPS \ + (OFI_SECONDARY_TX_CAPS | OFI_SECONDARY_RX_CAPS | \ + OFI_DOMAIN_SECONDARY_CAPS) #define OFI_TX_MSG_CAPS (FI_MSG | FI_SEND) #define OFI_RX_MSG_CAPS (FI_MSG | FI_RECV) From 202876be57b24f857009ed7fdc1374b896e0bff7 Mon Sep 17 00:00:00 2001 From: Ian Ziemba Date: Thu, 12 Oct 2023 15:44:00 -0500 Subject: [PATCH 6/6] util: Update checks for FI_AV_AUTH_KEY When FI_AV_AUTH_KEY is used, domain_attr::auth_key and ep_attr::auth_key must be NULL. In addition, ep_attr::auth_key_size must be zero. Signed-off-by: Ian Ziemba --- prov/util/src/util_attr.c | 49 +++++++++++++++++++++++++++++++-------- 1 file changed, 39 insertions(+), 10 deletions(-) diff --git a/prov/util/src/util_attr.c b/prov/util/src/util_attr.c index 5829256ac9a..adc202aac49 100644 --- a/prov/util/src/util_attr.c +++ b/prov/util/src/util_attr.c @@ -654,11 +654,20 @@ int ofi_check_domain_attr(const struct fi_provider *prov, uint32_t api_version, return -FI_ENODATA; } - if (user_attr->auth_key && user_attr->auth_key_size && - (user_attr->auth_key_size != prov_attr->auth_key_size)) { - FI_INFO(prov, FI_LOG_CORE, "Unsupported authentication size\n"); - OFI_INFO_CHECK_SIZE(prov, prov_attr, user_attr, auth_key_size); - return -FI_ENODATA; + if (user_attr->auth_key_size == FI_AV_AUTH_KEY && + FI_VERSION_GE(api_version, FI_VERSION(1, 20))) { + if (user_attr->auth_key) { + FI_INFO(prov, FI_LOG_CORE, + "Authentication key must be NULL with FI_AV_AUTH_KEY\n");; + return -FI_ENODATA; + } + } else { + if (user_attr->auth_key_size && + (user_attr->auth_key_size != prov_attr->auth_key_size)) { + OFI_INFO_CHECK_SIZE(prov, prov_attr, user_attr, + auth_key_size); + return -FI_ENODATA; + } } if (FI_VERSION_GE(api_version, FI_VERSION(1, 20)) && @@ -693,11 +702,17 @@ int ofi_check_ep_attr(const struct util_prov *util_prov, uint32_t api_version, const struct fi_ep_attr *user_attr = user_info->ep_attr; const struct fi_provider *prov = util_prov->prov; int ret; + bool av_auth_key = false; ret = ofi_check_ep_type(prov, prov_attr, user_attr); if (ret) return ret; + if (FI_VERSION_GE(api_version, FI_VERSION(1, 20)) && + user_info->domain_attr) { + av_auth_key = user_info->domain_attr->auth_key_size == FI_AV_AUTH_KEY; + } + if ((user_attr->protocol != FI_PROTO_UNSPEC) && (user_attr->protocol != prov_attr->protocol)) { FI_INFO(prov, FI_LOG_CORE, "Unsupported protocol\n"); @@ -790,11 +805,25 @@ int ofi_check_ep_attr(const struct util_prov *util_prov, uint32_t api_version, } } - if (user_attr->auth_key && user_attr->auth_key_size && - (user_attr->auth_key_size != prov_attr->auth_key_size)) { - FI_INFO(prov, FI_LOG_CORE, "Unsupported authentication size."); - OFI_INFO_CHECK_SIZE(prov, prov_attr, user_attr, auth_key_size); - return -FI_ENODATA; + if (av_auth_key) { + if (user_attr->auth_key) { + FI_INFO(prov, FI_LOG_CORE, + "Authentication key must be NULL with FI_AV_AUTH_KEY\n");; + return -FI_ENODATA; + } + + if (user_attr->auth_key_size) { + FI_INFO(prov, FI_LOG_CORE, + "Authentication key must be 0 with FI_AV_AUTH_KEY\n");; + return -FI_ENODATA; + } + } else { + if (user_attr->auth_key_size && + (user_attr->auth_key_size != prov_attr->auth_key_size)) { + OFI_INFO_CHECK_SIZE(prov, prov_attr, user_attr, + auth_key_size); + return -FI_ENODATA; + } } if ((user_info->caps & FI_TAGGED) && user_attr->mem_tag_format &&