-
Notifications
You must be signed in to change notification settings - Fork 58
syncobj: Fix import_sync_file and add timeline exports/imports #226
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: develop
Are you sure you want to change the base?
Conversation
|
Can we maybe have a clearer standalone title? When looking at git log, I don't have a mapping to github issues. Will look at the code later. |
Changed the PR title and split the commits into smaller better described chunks. |
drm-ffi/src/syncobj.rs
Outdated
| Ok(args) | ||
| Ok(unsafe { OwnedFd::from_raw_fd(args.fd) }) |
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.
Could you make the same change to fn create() and maybe other functions?
OTOH it looks intended for the drm-ffi crate to not reason about which files may have been modified inside the ioctl struct, which is both a consistent pattern but also makes these functions a really weird abstraction in relation to the high-level drm crate.
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.
Yeah I am not sure, perhaps I should change them back to return the whole struct for consistency. Possibly we shouldn't even split things like fd_to_syncobj and sync_file_into_syncobj given they use the same ioctl. However then we have two Options and incorrect combinations, making correct usage much more difficult to address.
I am not opposed to change drm-ffi to use some more higher-level types including OwnedFd, but I don't really want to do this as part of this PR.
I guess the original idea for this abstraction was to make it possible to use the calls directly if further down the line new uses get added and/or existing padded-bytes re-used etc. This is an example of that not really working given point was added later.
Maybe @Slabity has some opinions on this?
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 that was the case, perhaps now is the time to call it on that experiment and unify things back into a single drm/drm-sys crate in a separate PR.
The only alternative I can see is also accepting the struct as an input, but that's already the API that ioctl::syncobj::xxx() takes :)
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 changed this PR to return the whole ioctl struct again and do the conversion in drm-rs. But I am happy to continue this discussion in a future PR or issue on the matter.
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.
So the original idea with the division of crates was to follow what was, at the time, best practices for interfacing with system libraries and calls.
- The
syscrate would be exclusively generated bindings to the raw C calls and structures. The only logic involved here would be the build scripts and how they clean things up. - The
fficrate would do the bare minimum to allow making the calls safely without doing any sort of logic involved. Such as setting up memory pointers/lengths for the various structures that use them. No assumptions other than the bare minimum required to make theioctlcalls are done here. - The
rscrate would do everything higher order and try to closely reflect whatlibdrmdoes, leveraging Rust's ability to divide things through traits and also provide a clean, well documented interface. Any sort of logic, dynamic allocation, or other non-trivial things would be done here.
To be honest, I don't know if that's considered best practice now. I do think a separate ffi crate makes things more flexible if someone doesn't like how a certain drm-rs call is. It's also pretty clear 90% of the code in ffi is basically zero cost as well. But I also don't know much about the syncobj API here to argue about it cleanly.
The concern about a stable interface is something that will need to be addressed eventually though. To be honest, I don't think it's possible to follow semantic versioning well in the sys or ffi crates.
- The
syscrate is obvious because we have no control over any changes in the userspace API and we rely on the promise that "We don't break userspace". - The
fficrate because technicallyioctlcalls can be extended and may require new arguments to be added, which is a breaking change.
As far as I know, it's normal to never really stabilize the sys or ffi crates. But I don't really know if the "best practice" here changed at all.
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 changed this PR to return the whole ioctl struct again and do the conversion in
drm-rs.
Note that you went out of your way to document the input arguments to these functions, but didn't document what return fields of the struct are expected to be relevant - I think that's where my main disconnect with this API design comes from.
- The
fficrate would do the bare minimum to allow making the calls safely without doing any sort of logic involved. Such as setting up memory pointers/lengths for the various structures that use them. No assumptions other than the bare minimum required to make theioctlcalls are done here.
Fair enough though it does all become cloudy when considering inout parameters, optional fields and such. The caller has a clear view of what goes into the function, not what comes out.
In other words, having this crate doesn't seem too bad, but returning the full ioctl() struct is what seems to be confusing perhaps?
As far as I know, it's normal to never really stabilize the
sysorfficrates. But I don't really know if the "best practice" here changed at all.
Not sure if this is standard, but most high-level crates might still utilize sys types in their public API for a variety of reasons. Assuming they're not always plain type aliases, any breaking change to the -sys crate automatically means a break to the high-level crate.
Though for the crates I work on (i.e. ndk) those breaking changes in the underlying C API are already "disallowed" as they would also break ABI. Certain cases like enums are exempt via #[non_exhaustive] tricks.
Assuming that is the case for the sys crate here as well (adding #[non_exhaustive] to all structs, ioctl()s should be aware of size for new/optional fields?) that could very well be "stabilizable". It leaves ffi as "the odd one out" when having to extend function parameter interfaces.
This addresses the broken api reported in #224 and also provides entry point for the new optional timeline argument.
Ping @ids1024, @YaLTeR, @MarijnS95