-
Notifications
You must be signed in to change notification settings - Fork 434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UCP: add support fixed address for mmap #1329
Conversation
@MattBBaker please share ORNL failures |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure that I checked all relevant commits, but tried to look thru UCP related
src/ucp/api/ucp.h
Outdated
UCP_MEM_MAP_ALLOCATE = UCS_BIT(2) /**< Identify requirement for allocation, | ||
if passed address is not a null-pointer | ||
then it will be used as a hint or direct | ||
address for allocation depend */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like incomplete sentence
src/ucp/core/ucp_mm.c
Outdated
@@ -142,14 +143,18 @@ static ucs_status_t ucp_mem_alloc(ucp_context_h context, size_t length, | |||
* name specified in the configuration. | |||
*/ | |||
num_mds = 0; | |||
if (method == UCT_ALLOC_METHOD_MD) { | |||
if ((method == UCT_ALLOC_METHOD_MD)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for extra brackets
return flags; | ||
} | ||
|
||
/* Matrix of behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks cool as a comment!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it better to have this matrix in the ucp.h ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alex-mikheev I've added such kind of the table to ucp.h as a markdown table. It's unreadable in the code but should look fine in the browser. I decided to keep this one "as is" for development needs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might use @verbatim
clause for this type of comments. Please look into uct_def.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I understand verbatim
does not support hyperlinks, doesn't it? The resulting table includes links to all actual fields and flags.
src/ucp/core/ucp_mm.c
Outdated
|
||
/* Now, lets check all erroneous cases from the matrix */ | ||
if (params->address == NULL) { | ||
if (params->flags == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these checks can be reduced to smth like this:
if ((params->flags & UCP_MEM_MAP_FIXED) ||
!(params->flags & UCP_MEM_MAP_ALLOCATE)) {
return UCS_ERR_INVALID_PARAM;
}
src/ucp/core/ucp_mm.c
Outdated
(params->flags & UCP_MEM_MAP_FIXED)) { | ||
return UCS_ERR_INVALID_PARAM; | ||
} | ||
} else if (!(params->flags & UCP_MEM_MAP_ALLOCATE) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this an invalid param case?
test/gtest/ucp/test_ucp_memheap.cc
Outdated
@@ -170,6 +173,10 @@ void test_ucp_memheap::test_blocking_xfer(blocking_send_func_t send, | |||
goto out; | |||
} | |||
|
|||
if (!malloc_allocate) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can set it in the check above at line 162 (though flags needs to be initialized before that check)
It's because memheap doesn't get set until line 172, but in line 166 there is a 'goto out;' statement that will lead to a code path that passes memheap to free(), so at that point memheap won't be initialized. Setting memheap = NULL at initialization in line 151 will fix this. |
12969b6
to
ef88b59
Compare
@MattBBaker Thanks! This is a new error, the same as Mellanox testing shows, It should be fixed now. Yesterday's PR has something else (https://pod9.ccs.ornl.gov/job/UCX/865/) |
ef88b59
to
6119655
Compare
src/ucp/api/ucp.h
Outdated
* @param [out] params Defined @ref ucp_mem_map_params_t configurations | ||
* for the @ref ucp_mem_h "UCP memory handle". | ||
*/ | ||
ucs_status_t ucp_mem_query(const ucp_mem_h memh, ucp_mem_map_params_t *params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the query function should return a new structure (not ucp_mem_map_params_t), according to the convention it would be ucp_mem_attr_t
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this function ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add @return
src/ucp/core/ucp_mm.c
Outdated
|
||
static inline int ucp_mem_map_is_allocate(ucp_mem_map_params_t *params) | ||
{ | ||
ucs_assert(params != NULL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don;t think this assert is needed
src/ucp/core/ucp_mm.c
Outdated
@@ -178,20 +178,96 @@ static ucs_status_t ucp_mem_alloc(ucp_context_h context, size_t length, | |||
} | |||
|
|||
|
|||
static inline unsigned uct_flags(ucp_mem_map_params_t *params) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls rename the function
src/ucp/core/ucp_mm.c
Outdated
{ | ||
unsigned flags = 0; | ||
|
||
if (params && (params->field_mask & UCP_MEM_MAP_PARAM_FIELD_FLAGS)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to check for params!=NULL
src/ucp/core/ucp_mm.c
Outdated
*/ | ||
static inline ucs_status_t ucp_mem_map_check_and_adjust_params(ucp_mem_map_params_t *params) | ||
{ | ||
if (!params) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to check this
src/ucp/api/ucp.h
Outdated
UCP_MEM_MAP_FIXED = UCS_BIT(1), /**< Don't interpret addr as a hint: | ||
place the mapping at exactly that | ||
address. See man mmap for details */ | ||
UCP_MEM_MAP_ALLOCATE = UCS_BIT(2) /**< Identify requirement for allocation, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls reverse order, ALLOCATE flag should come before FIXED
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear how UCP_MEM_MAP_NONBLOCK interacts with the UCP_MEM_MAP_ALLOCATE. You need to clarify if nonblock is good for mapping (registration), for allocation or for both
src/ucp/api/ucp.h
Outdated
address. See man mmap for details */ | ||
UCP_MEM_MAP_ALLOCATE = UCS_BIT(2) /**< Identify requirement for allocation, | ||
if passed address is not a null-pointer | ||
then it will be used as a hint or direct |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC address-as-a-hint is not implemented by UCT today, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's implemented, we added address
argument to uct_mem_alloc
function for that
|
||
/* First of all, define all fields */ | ||
if (!(params->field_mask & UCP_MEM_MAP_PARAM_FIELD_ADDRESS)) { | ||
params->field_mask |= UCP_MEM_MAP_PARAM_FIELD_ADDRESS; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls avoid changing the structure passed by user. Need to make the parameter to ucp_mem_map() a const*.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, now the copy user's structure is changing to simplify definition of default and erroneous cases
src/ucp/core/ucp_mm.c
Outdated
} | ||
} else if (!(params->flags & UCP_MEM_MAP_ALLOCATE) && | ||
(params->flags & UCP_MEM_MAP_FIXED)) { | ||
return UCS_ERR_INVALID_PARAM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indentation
src/ucp/core/ucp_mm.c
Outdated
} | ||
|
||
params->field_mask = 0; | ||
return UCS_ERR_INVALID_PARAM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this function should not return UCS_ERR_INVALID_PARAM
src/ucp/api/ucp.h
Outdated
up-front, and mapping them later when | ||
they are accessed by communication | ||
routines. */ | ||
UCP_MEM_MAP_FIXED = UCS_BIT(1), /**< Don't interpret addr as a hint: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^addr^address
src/ucp/api/ucp.h
Outdated
* @param [out] params Defined @ref ucp_mem_map_params_t configurations | ||
* for the @ref ucp_mem_h "UCP memory handle". | ||
*/ | ||
ucs_status_t ucp_mem_query(const ucp_mem_h memh, ucp_mem_map_params_t *params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this function ?
src/ucp/api/ucp.h
Outdated
* @brief query mapped memory segment | ||
* | ||
* This routine returns valid address and length of memory segment mapped with | ||
* @ref ucp_mem_map "ucp_mem_map()" routine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove 'valid'
src/ucp/api/ucp.h
Outdated
* @param [out] params Defined @ref ucp_mem_map_params_t configurations | ||
* for the @ref ucp_mem_h "UCP memory handle". | ||
*/ | ||
ucs_status_t ucp_mem_query(const ucp_mem_h memh, ucp_mem_map_params_t *params); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add @return
return flags; | ||
} | ||
|
||
/* Matrix of behavior |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't it better to have this matrix in the ucp.h ?
src/ucp/api/ucp.h
Outdated
UCP_MEM_MAP_FIXED = UCS_BIT(1), /**< Don't interpret addr as a hint: | ||
place the mapping at exactly that | ||
address. See man mmap for details */ | ||
UCP_MEM_MAP_ALLOCATE = UCS_BIT(2) /**< Identify requirement for allocation, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not clear how UCP_MEM_MAP_NONBLOCK interacts with the UCP_MEM_MAP_ALLOCATE. You need to clarify if nonblock is good for mapping (registration), for allocation or for both
@evgeny-leksikov @yosefe
Is it OK to free handles in the reverse order ? |
@alex-mikheev in general there is no need to map a memory which was allocated by ucp. |
The docs in this PR suggest that allocated memory is not mapped |
@evgeny-leksikov need to explicitly specify that memory allocated by ucp_mem_map() is available for RMAs and AMOs |
@evgeny-leksikov It is not clear if the allocated memory is also mapped. In fact based on the table in the comment one has a reason to think that allocated memory is not mapped/registered |
@alex-mikheev I see your point. This table is a comment for internal function, not API, so it should not be considered as a user's documentation. Any way, I'll fix alloc -> alloc/reg int the table, that's OK? |
@evgeny-leksikov we need to put a more comprehensive explanation in the UCP level, can be a similar table (but something which looks good on doxygen), or something else which clearly explains what are the valid combinations of flags, and what would happen for each. |
PR is updated to cover the most of comments and especially API, I'm going to update ucp_mem_map docs a bit later |
4200681
to
0ce81f9
Compare
src/tools/perf/libperf.c
Outdated
|
||
status = ucp_mem_map(perf->ucp.context, &mem_map_params, | ||
&perf->ucp.send_memh); | ||
if (status != UCS_OK) { | ||
goto err; | ||
} | ||
perf->send_buffer = mem_map_params.address; | ||
status = ucp_mem_query(perf->ucp.send_memh, &mem_attr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls add space line
src/ucp/core/ucp_mm.c
Outdated
ucs_status_t ucp_mem_query(const ucp_mem_h memh, ucp_mem_attr_t *attr) | ||
{ | ||
if (memh->address) { | ||
attr->field_mask = UCP_MEM_ATTR_FIELD_ADDRESS | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the field mask is an input parameter, specifying which fields should be filled by the structure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i.e. attr should be in/out parameter?
This looks more flexible but requires a bit more actions from user.
And what the function should return if requested field, for example, is not available? UCS_ERR_UNSUPPORTED
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, see ucp_worker_query for example.
if not available - currently it's not handled correctly (good catch)
I guess we need to return ERR_INVALID_PARAM if any unexpected bit is received in attr.field_mask. but let's do it in another PR, and for all ucp_*_query() functions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but I like UNSUPPORTED more from perspective that field_flags introduced for backward compatibility. This might be actual for ucp*params functions as well
src/ucp/api/ucp_def.h
Outdated
uint64_t field_mask; | ||
|
||
/** | ||
* A virtual address. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Address of the memory segment
src/ucp/api/ucp_def.h
Outdated
@@ -115,6 +115,44 @@ typedef struct ucp_mem *ucp_mem_h; | |||
|
|||
|
|||
/** | |||
* @ingroup UCP_MEM | |||
* @brief Attributes of the @ref ucp_mem_h "UCP Memory handle", might be |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"might be requested by" -> "filled by"
src/ucp/core/ucp_mm.c
Outdated
/* Now, lets check the rest of erroneous cases from the matrix */ | ||
if (params->address == NULL) { | ||
if (!(params->flags & UCP_MEM_MAP_ALLOCATE)) { | ||
return UCS_ERR_INVALID_PARAM; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shall we add error message, as in line 233?
src/ucp/core/ucp_mm.c
Outdated
ucp_mem_h memh; | ||
ucp_mem_map_params_t mem_params; | ||
|
||
if (!params) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO no need to check for params==NULL since we don't check it in any other function
src/ucp/core/ucp_mm.c
Outdated
if (params->address == NULL) { | ||
status = ucp_mem_alloc(context, params->length, uct_flags, "user allocation", memh); | ||
if (ucp_mem_map_is_allocate(&mem_params)) { | ||
status = ucp_mem_alloc(context, mem_params.length, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's add debug message like in line 303
src/ucs/sys/sys.h
Outdated
@@ -237,6 +237,12 @@ size_t ucs_get_page_size(); | |||
|
|||
|
|||
/** | |||
* @return 1 if ptr is aligned to page size on the system, otherwise 0 | |||
*/ | |||
int ucs_is_page_aligned(void *ptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to remove
test/gtest/ucp/test_ucp_fence.cc
Outdated
EXPECT_TRUE(mem_attr.field_mask & (UCP_MEM_ATTR_FIELD_ADDRESS | | ||
UCP_MEM_ATTR_FIELD_LENGTH)); | ||
EXPECT_LE(memheap_size, mem_attr.length); | ||
if (!memheap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not memheap = mem_attr.address
unconditionally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because if memheap
allocated by malloc
then mem_attr.address
may different in common case, I'm not sure that the test will work fine everywhere :) Are you suggesting to remove the check?
test/gtest/ucp/test_ucp_fence.cc
Outdated
ASSERT_UCS_OK(status); | ||
|
||
free(memheap); | ||
if (!(params.flags & UCP_MEM_MAP_ALLOCATE)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO would be better to use GetParam().variant than params.flags
@evgeny-leksikov can you please also squash the commits? |
0ce81f9
to
3e51640
Compare
Test PASSed. |
Test PASSed. |
All comments are addressed. @yosefe , @alex-mikheev , pls review |
@shamisp @bbenton @alex-mikheev pls review as well |
src/ucp/api/ucp.h
Outdated
* <td>@ref anch_alloc_hint_reg "alloc+register,hint" | ||
* <td>@ref anch_err "error" | ||
* <td>@ref anch_alloc_fixed_reg "alloc+register,fixed" | ||
* </table> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When converted to pdf, this table has some formatting and alignment issues. Maybe using shorter names to print in the references to the parameter flags will help. If it could look more like the ASCII matrix in ucp_mm.c, I think that would help for readability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bbenton formatting for PDF is a pain.
The table is too wide without abbreviations even in ASCII and it doesn't support hyperlinks to provide good description and navigation.
I've prepared 3 different variants of the table, please take patch here and choose the best one from your point of view. If you would play with it and provide better formatting, it would be very appreciated!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for re-working the table and providing the 3 options. I prefer the 2nd option; I think it is much cleaner in the pdf. I have a couple of minor suggested modifications:
-
change the NONBLOCK column text from
affects only\n registration/mapping\n phase
to
only affects the\n register/map\n phase
this keeps the text from overflowing the column width -
for the "address" column, modify the "1" value to "defined", as in table 3.
if ((params->flags & UCP_MEM_MAP_FIXED) && | ||
(!params->address || | ||
((uintptr_t)params->address % ucs_get_page_size()))) { | ||
ucs_error("UCP_MEM_MAP_FIXED flag requires page aligned address"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The requirement for fix address page alignment has to be explicitly document in UCP API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed
/* TODO: pass addr */ | ||
status = uct_mem_alloc(NULL, length, uct_flags, &method, 1, mds, num_mds, | ||
name, &mem); | ||
status = uct_mem_alloc(memh->address, length, uct_flags, &method, 1, mds, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mmap does not guarantee allocation with user defined address. Do we have an error code to propagate it to UCP later. The fact that we can't guarantee such allocation has to be explicitly mentioned in UCP documentation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shamisp I'm not sure I see you point
man mmap for MAP_FIXED flag says me a bit different things: it's less portable, overlapped parts will be discarded, etc. but it does. If the addr can't be used, mmap will fail, so ucp_mem_map should return NO_MEMORY.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@shamisp the API doc says "use address as a hint". If the memory is allocated in a different address - user can find this using ucp_mem_query(), it is not considered an error situation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return NO_MEMORY - answers the question
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but the memory allocation did succeed, just not in address provided as hint..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay...how we notify user about this ? We don't want a user to invoke the query every single allocation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like there are 2 options:
- return error code
- return success, user does mem_query
I think (2) is better because:
- similar behavior to system mmap
- error status usually means no side effect happened, but here memory was allocated
- user who wants to force specific address can use FIXED flag. otherwise, he has to query anyway to discover the real address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the idea of following mmap semantics. If UCP_MEM_MAP_FIXED was specified UCP should fail and return an error.
Test PASSed. |
Test PASSed. |
Test PASSed. |
@shamisp looks like all issues are resolved. Do you have other comments? |
src/ucp/api/ucp.h
Outdated
@@ -262,7 +262,8 @@ enum { | |||
address for allocation. */ | |||
UCP_MEM_MAP_FIXED = UCS_BIT(2) /**< Don't interpret address as a hint: | |||
place the mapping at exactly that | |||
address. */ | |||
address. Address must be a multiple |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The address
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@evgeny-leksikov once you make the chance consider that it is auto-approved by me :) but you have to get approval from @bbenton as well.
@evgeny-leksikov - just one minor comment and we may call it done. |
👍 for doc/api |
Signed-off-by:Evgeny Leksikov <evgenylek@mellanox.com>
f21bde4
to
dd323f3
Compare
Rebased on master to resolve conflicts |
Test PASSed. |
Test FAILed. |
bot:mlx:retest |
Test PASSed. |
Fixes #1273
Do not merge before #1323
@shssf , @brminich pls review, note that several commits (UCT part) are already reviewed in #1323