-
Notifications
You must be signed in to change notification settings - Fork 309
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
DAOS-16931 container: fix oid iv race with using invalid on_update ptr #15714
Conversation
the src pointer for on_update() callback is on the stack and should not be saved beyond that call to detect the same current request, because in some cases we can end up with 2 different requests sharing getting the same pointer value. Use the private pointer allocated by the oid iv on_alloc operation instead. Signed-off-by: Mohamad Chaarawi <[email protected]>
Ticket title is 'oid IV assertion on server with mutex unlock' |
@@ -133,10 +134,10 @@ oid_iv_ent_update(struct ds_iv_entry *ns_entry, struct ds_iv_key *iv_key, | |||
entry = ns_entry->iv_value.sg_iovs[0].iov_buf; | |||
rc = ABT_mutex_trylock(entry->lock); | |||
/** For retry requests, from _iv_op(), the lock may not be released in some cases. */ | |||
if (rc == ABT_ERR_MUTEX_LOCKED && entry->current_req != src) | |||
if (rc == ABT_ERR_MUTEX_LOCKED && entry->current_req != priv) |
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.
Just to double-check -- does on_get() implementation always return a valid priv or are there cases when priv returned can be NULL? (iv framework just passes whatever priv was filled with, we dont enforce it to be non-null). if latter, then two requests might have same null priv causing issues with this logic.
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.
for the oid iv, the on get returns a valid ptr always. see here:
https://github.com/daos-stack/daos/pull/15714/files#diff-9396dfee0370217c952706fe6a29b126a7ec9f73f9d23078a7b82659bc94df41R214
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 the "entry->current_req == priv" can never be true, as every time it will allocate a new one though oid_iv_ent_get(). So why need this check in the original place?
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 am not sure TBH. @wangdi1 had added this one a while back. according to wangdi's comment, on an IV retry operation, we can re-enter the on-update call. but are you saying on a retry, we are calling on_get() again and so we have a new priv pointer allocated?
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.
If the "retry" you mean here -
static int
_iv_op()'s
retry:
rc = iv_op_internal(ns, key, value, sync, shortcut, opc);
Then yes, I think the retry of iv_op_internal() -> crt_iv_update()/crt_iv_fetch(), it will cause the oid_iv_ent_get() be called in the path and provide a new priv pointer.
So the check "entry->current_req != priv" will be always true.
@wangdi1 is above correct?
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.
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.
using src is just wrong.. it causes assertions. check the ticket.
src value is on the stack. a totally different request can get the same src pointer value.
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.
hmm perhaps you may want to use "entry->current_req = src->sg_iovs[0].iov_buf"
while 'src' (temp iv value) can be on the stack, depending where iv calls it from, the underlying iov buffer will be provided by on_get(), so should remain valid until a corresponding on_put()
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.
yea that was my thought as well. thanks Alex, i'll post a follow on PR.
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.
"while 'src' (temp iv value) can be on the stack, depending where iv calls it from, the underlying iov buffer will be provided by on_get(),"
I think it is not true. let's discuss it more on the new PR #15727
@@ -133,10 +134,10 @@ oid_iv_ent_update(struct ds_iv_entry *ns_entry, struct ds_iv_key *iv_key, | |||
entry = ns_entry->iv_value.sg_iovs[0].iov_buf; | |||
rc = ABT_mutex_trylock(entry->lock); | |||
/** For retry requests, from _iv_op(), the lock may not be released in some cases. */ |
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.
is it guaranteed that priv going to be the same for retry requests? i am not sure what daos stores in it or how it manages it across requests
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 i believe so. the priv is allocated on the on-get CB. so it will not change on retry afaik.
Test stage Functional Hardware Medium completed with status FAILURE. https://build.hpdd.intel.com//job/daos-stack/job/daos/view/change-requests/job/PR-15714/1/execution/node/1420/log |
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.
good catch!
#15714) the src pointer for on_update() callback is on the stack and should not be saved beyond that call to detect the same request, because in some cases we can end up with 2 different requests sharing getting the same pointer value. Use the private pointer allocated by the oid iv on_get operation instead. Signed-off-by: Mohamad Chaarawi <[email protected]>
#15714) the src pointer for on_update() callback is on the stack and should not be saved beyond that call to detect the same request, because in some cases we can end up with 2 different requests sharing getting the same pointer value. Use the private pointer allocated by the oid iv on_get operation instead. Signed-off-by: Mohamad Chaarawi <[email protected]>
the src pointer for on_update() callback is on the stack and should not be saved beyond that call to detect the same current request, because in some cases we can end up with 2 different requests sharing getting the same pointer value. Use the private pointer allocated by the oid iv on_alloc operation instead.
Before requesting gatekeeper:
Features:
(orTest-tag*
) commit pragma was used or there is a reason documented that there are no appropriate tags for this PR.Gatekeeper: