- Notifications
You must be signed in to change notification settings - Fork 771
Check memory segment ownership on downcall #22675
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
base: master
Are you sure you want to change the base?
Conversation
79a4f0d
to 7f35e22
Compare jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
try { | ||
return (long) originalFilter.invokeExact(seg); | ||
} finally { | ||
sessionImpl.release0(); |
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 wont work as you are releasing ownership of the memory segment before the call is made.
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 think the way to solve this is to add a new field to HeapArgInfo
called something like MemorySessionImpl[] sessions
.
In the memSegmtToLongArg
you can acquire the session and also add it to the active info.sessions[]
. In runNativeMethod
after the native has been called and before info.clear()
is called, you can iterate thorugh all the sessions and release them.
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.
Thank you @tajila . I hadn't removed the acquire0 call in SetDependency, I guess thats why the tests passed.
As there is already a call to acquire0 in SetDependency(), can we just call CheckValidState()
here to ensure the confined MemorySegment is only accessed by the owner thread?
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.
Thank you @tajila . I hadn't removed the acquire0 call in SetDependency, I guess thats why the tests passed. As there is already a call to acquire0 in SetDependency(), can we just call
CheckValidState()
here to ensure the confined MemorySegment is only accessed by the owner thread?
I think this could just be a call to CheckValidState or similar since the fields are already being acquired in SetDependency.
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.
Ya good point. I think SetDependency
already does the required access/release checks. The one issue with the way its currently done is that memArgScopeSet
is not thread local. Perhaps this is the only thing that needs to be changed.
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 session for the native call and the session for the args arent guaranteed to be the same.
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.
acquire0 for GlobalSession (the scope that can't be closed) does not do anything.
There is also ImplicitSession which doesnt explicitly close.
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.
acquire0 for GlobalSession (the scope that can't be closed) does not do anything.
My concern is that session
(the native call session) can be global, but memArgSession
can be confined. Currently the if ((owner == Thread.currentThread()) || (owner == null)) {
check is against the memArgSession
, but then the closeable action is on the native call session. Unless I've missed something it seems like its possible a confined session on an arg would never be closed unless the arg sessions are explcitly closed after the call.
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.
In runNativeMethod
, I see that the downcall is always wrapped in a confined Arena (https://github.com/eclipse-openj9/openj9/blob/master/jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java#L932) so I think the native call session is never global. Are there other contexts where the native call session could be global or implicit?
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.
Right, then my previous concern is not valid. But memArgSession still needs to be thread local.
efc1e05
to 982049a
Compare 982049a
to 67f6393
Compare private long[] offsets; | ||
private int index; | ||
private final int size; | ||
private MemorySessionImpl[] sessions; |
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 realized, this can actually be an array list List<MemorySessionImpl>
because we dont actually care about the position.We just need to keep track of all of them.
} | ||
| ||
void addSession(MemorySessionImpl session) { | ||
sessions[index - 1] = session; |
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 can just add to the array list.
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
67f6393
to 278cbc0
Compare jenkins test sanity alinux64 jdk25 |
864edbf
to a3796ec
Compare jenkins test sanity alinux64 jdk25 |
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
@TobiAjila PR builds may be a little premature; the code as is will not compile for Java 21. See #22675 (comment). |
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
*/ | ||
/*[IF JAVA_SPEC_VERSION >= 21]*/ | ||
private Set<Scope> memArgScopeSet; | ||
private final ThreadLocal<Set<Scope>> memArgScopeSet = ThreadLocal.withInitial(HashSet::new); |
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'll have the same problem here as last time with recursive calls. This should be added to HeapArgInfo.
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.
Currently, HeapArgInfo
is used only for Java versions 22 and above, while memArgScopeSet
exists for Java versions 21 and above. If we move memArgScopeSet
inside HeapArgInfo
, could this cause issues? (Tried the change for Java 25 and it worked)
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 can include HeapArgInfo
in jdk21 but exlude all the fields that arent used and just keep memArgScopeSet
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
26465e4
to a346b4c
Compare jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
jcl/src/java.base/share/classes/openj9/internal/foreign/abi/InternalDowncallHandler.java Outdated Show resolved Hide resolved
Fixes: eclipse-openj9#22573 Ensure that checkValidState is called for memory segments which are passed as arguments to the native call when argValue.address is invoked. Make memArgScopeSet thread local.
Please add a test to validate change. |
Tested the change with the test case mentioned in the issue. It throws the required |
A manual test is fine, but we should have test code in this repository that automatically checks that the issue does not return. |
Fixes: #22573
Ensure that checkValidState() is called for confined
memory segments which are passed as arguments to
the native call when argValue.address is invoked.
Make memArgScopeSet thread local.
With the following change, this is the error produced for the issue: