Skip to content
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

UCS/CONFIG/PARSER: Handle NULL entries in sparse arrays #10305

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

michal-shalev
Copy link
Contributor

@michal-shalev michal-shalev commented Nov 15, 2024

What?

Following #10172
Introduced UCS_CONFIG_TYPE_FLAGS to support sparse parsing of configuration flags.
Removed unnecessary flags from UCX_EXTRA_OP_ATTR_FLAGS.

Why?

UCS_CONFIG_TYPE_BITMAP required contiguous indices, leading to core dumps when NULL values were accessed due to gaps in the array.
UCS_CONFIG_TYPE_FLAGS enables sparse arrays for flags, eliminating the need for unnecessary placeholders and simplifying the flag configuration.

How?

Implemented UCS_CONFIG_TYPE_FLAGS to loop until the specified number of arguments instead of relying on NULL-terminated arrays.

{
size_t i;

/* Ingnores NULL entries */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

*
* @param str String to search for.
* @param string_list Array of strings.
* @param num_of_args Number of strings in the array.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would propose to name this arg similar to array, eg str_array and str_array_size

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

src/ucp/core/ucp_context.c Outdated Show resolved Hide resolved
@@ -544,7 +546,7 @@ static ucs_config_field_t ucp_context_config_table[] = {
"in addition to what is set explicitly by the user. \n"
"Possible values are: no_imm_cmpl, fast_cmpl, force_imm_cmpl, multi_send.",
ucs_offsetof(ucp_context_config_t, extra_op_attr_flags),
UCS_CONFIG_TYPE_BITMAP(ucp_extra_op_attr_flags_names)},
UCS_CONFIG_TYPE_FLAGS((const void *)&ucp_extra_op_attr_flags_args)},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add few unit tests for this new option (test_config.cc)

break;
}

ucs_assertv(i < (sizeof(uint64_t) * 8), "bit %d overflows for '%s'", i,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe use CHAR_BIT const instead of 8

}

ret = 1;
*((uint64_t*)dest) = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would propose to create a variable to avoid repetitive casts:
uint64_t *flags = dest;


ret = 1;
*((uint64_t*)dest) = 0;
p = strtok_r(str, ",", &saveptr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider using ucs_string_split

Copy link
Contributor

@tvegas1 tvegas1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to fix UCS_CONFIG_TYPE_BITMAP for sparse, instead of introducing new UCS_CONFIG_TYPE_FLAGS?

ucs_config_flags_args_t *args = (ucs_config_flags_args_t*)arg;
int written = snprintf(buf, max, "comma-separated list of: ");

if (written < 0 || written >= max) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

() and ()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

}

/* Ingores NULL entries */
for (i = 0; i < num_of_args && ptr < end; ++i) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

() and (), everywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

src/ucp/core/ucp_context.c Show resolved Hide resolved
src/ucp/core/ucp_context.c Show resolved Hide resolved
@@ -384,6 +393,11 @@ void ucs_config_help_generic(char *buf, size_t max, const void *arg);
ucs_config_help_bitmap, ucs_config_doc_nop, \
t}

#define UCS_CONFIG_TYPE_FLAGS(t) {ucs_config_sscanf_flags, ucs_config_sprintf_bitmap, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#define UCS_CONFIG_TYPE_FLAGS(t) {ucs_config_sscanf_flags, ucs_config_sprintf_bitmap, \
#define UCS_CONFIG_TYPE_FLAGS(t) {ucs_config_sscanf_flags, ucs_config_sprintf_flags, \

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch, fixed

continue;
}

if (ptr > buf + 1 && ptr < end) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (ptr > buf + 1 && ptr < end) {
if ((ptr > (buf + 1)) && (ptr < end)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, done

ucs_config_flags_args_t *args = (ucs_config_flags_args_t*)arg;
int written = snprintf(buf, max, "comma-separated list of: ");

if (written < 0 || written >= max) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (written < 0 || written >= max) {
if ((written < 0) || (written >= max)) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@michal-shalev
Copy link
Contributor Author

is it possible to fix UCS_CONFIG_TYPE_BITMAP for sparse, instead of introducing new UCS_CONFIG_TYPE_FLAGS?

@tvegas1
The alternative is to change UCS_CONFIG_TYPE_BITMAP instances unrelated to the flags, but it is not critical for me.

@yosefe
Copy link
Contributor

yosefe commented Nov 18, 2024

is it possible to fix UCS_CONFIG_TYPE_BITMAP for sparse, instead of introducing new UCS_CONFIG_TYPE_FLAGS?

We could do it nicely by adding another "unsigned long" field to ucs_config_parser_t to hold the count, something like

typedef struct ucs_config_parser {
    ...
    void                     (*help)(char *buf, size_t max, const void *arg);
    void                     (*doc)(ucs_string_buffer_t *strb, const void *arg);
    const void               *arg_ptr;
    unsigned long            arg_ulong;
};

And setting arg_ulong by ucs_static_array_size

@michal-shalev
Copy link
Contributor Author

michal-shalev commented Nov 18, 2024

is it possible to fix UCS_CONFIG_TYPE_BITMAP for sparse, instead of introducing new UCS_CONFIG_TYPE_FLAGS?

We could do it nicely by adding another "unsigned long" field to ucs_config_parser_t to hold the count, something like

typedef struct ucs_config_parser {
    ...
    void                     (*help)(char *buf, size_t max, const void *arg);
    void                     (*doc)(ucs_string_buffer_t *strb, const void *arg);
    const void               *arg_ptr;
    unsigned long            arg_ulong;
};

And setting arg_ulong by ucs_static_array_size

We could but it will require changes in all the parsers, which is more than the scope of the flags, LMK WDYT @yosefe

* Find a string in an array of strings with NULL entries.
*
* @param str String to search for.
* @param string_list Array of strings.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'd call it str_array to be consistent with str_array_size

@yosefe
Copy link
Contributor

yosefe commented Nov 18, 2024

is it possible to fix UCS_CONFIG_TYPE_BITMAP for sparse, instead of introducing new UCS_CONFIG_TYPE_FLAGS?

We could do it nicely by adding another "unsigned long" field to ucs_config_parser_t to hold the count, something like

typedef struct ucs_config_parser {
    ...
    void                     (*help)(char *buf, size_t max, const void *arg);
    void                     (*doc)(ucs_string_buffer_t *strb, const void *arg);
    const void               *arg_ptr;
    unsigned long            arg_ulong;
};

And setting arg_ulong by ucs_static_array_size

We could but it will require changes in all the parsers, which is more than the scope of the flags, LMK WDYT @yosefe

I think it's worth it , but would appreciate @gleon99 @brminich @tvegas1 opinions

@tvegas1
Copy link
Contributor

tvegas1 commented Nov 20, 2024

We could but it will require changes in all the parsers, which is more than the scope of the flags, LMK WDYT @yosefe

I think it's worth it , but would appreciate @gleon99 @brminich @tvegas1 opinions

I would try to have only one UCS_CONFIG_TYPE_BITMAP that supports holes because _TYPE_FLAGS seems to be more or less the same, if that's possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants