-
Notifications
You must be signed in to change notification settings - Fork 481
Rust NetDevice and NetDeviceOperationsVtable struct #208
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
Conversation
|
I'm a bit struggling with the Also I'm unsure on how to populate the kind field of that struct |
|
Maybe I'm misunderstanding your issue, but if you're thinking of doing something similar to the existing For the |
|
@adamrk I think I understand how the |
|
I created a proc macro, which creates a wrapped |
14ea91c to
6e3bed3
Compare
|
and Now I have to document everything. help is appreciated :-) |
| description: b"Android Binder", | ||
| license: b"GPL v2", | ||
| 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.
This should likely go into a different commit -- or is GitHub confused due to having several commits in the PR? Please rebase to have 1 commit anyway.
| //! This is a demonstration of what a small driver looks like in Rust, based on drivers/net/dummy.c. | ||
| //! This code is provided as a demonstration only, not as a proposal to mass-rewrite existing drivers in Rust |
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.
See my comment on #254 (comment).
I guess we can talk about this tomorrow in 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.
I think that was the wording of @joshtriplett, while talking about this at our last 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.
I'm not fixated on the exact wording, I just want to make sure that people don't see a Rust version of an existing C driver and assume we're trying to rewrite the world in Rust. In this context, we're providing samples of what drivers would look like; we're not writing replacements.
In the future, some driver maintainers may choose to use Rust in existing drivers, but that's up to those driver maintainers, not us.
rust/helpers.c
Outdated
| EXPORT_SYMBOL_GPL(rust_helper_dev_lstats_add); | ||
|
|
||
| // See https://github.com/rust-lang/rust-bindgen/issues/1671 | ||
| #if !defined(CONFIG_ARM) |
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.
? Perhaps GitHub is confused -- please rebase.
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.
Tried that yesterday, but not even the rust branch builds on my system currently. Something with exports.o and symbols
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.
after a git clean -xfd (as make mrproper does not work #255 ) it builds the rebased version.
I pushed the rebased version, but I'm sot sure if/why it still makes this as a change.
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.
Ah, now it is clear -- somehow you ended up with the comment moved outside of the #ifdef.
rust/kernel/error.rs
Outdated
| /// Used by the rtnl_link_ops macro to interface with C | ||
| pub fn c_from_kernel_result<T>(r: KernelResult<T>) -> 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.
If it is not intended to be used by users, hide the docs.
rust/kernel/net/device.rs
Outdated
| } | ||
| } | ||
|
|
||
| /// register_locked - register a network device if the RtnlLock is already hold |
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 guess this is copied from C docs, but do not put the name of the function etc.
| /// | ||
| /// # Safety | ||
| /// | ||
| /// caller must hold the RtnlLock and semaphore |
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.
| /// caller must hold the RtnlLock and semaphore | |
| /// Caller must hold the [`RtnlLock`] and semaphore. |
And similar everywhere else.
rust/kernel/net/netlink.rs
Outdated
| /*pub unsafe fn from_ptr(ptr: *const bindings::nlattr) -> &'static mut Self { | ||
| (ptr as *mut NlAttr).as_mut().unwrap() | ||
| }*/ |
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 see a bunch of commented out code etc.
From the quick review I did above, I assume you are still working on this (i.e. there is a bunch of commented out code, |
rust/kernel/net/device.rs
Outdated
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.
Should we implement this Deref and DerefMut or should we consider this unsafe, as this exposes the direct bindings?
f3ddd55 to
018db0a
Compare
|
To summarise what I understood in the meeting. I will remove the line saying it is just a test driver. I finish up the abstraction in the |
|
If you prefer, you can put it here if you want, too. Like with Binder, for the moment we have it in this tree to have everything in one place. While they will not be merged with the Rust support, I can submit it as an extra patch (with you as the author etc.) like I did with Binder from Wedson in the RFC. @wedsonaf @TheSven73 since they have the other two potential drivers. |
Sounds great. I will create a second commit like Wedson explained, so one with abstractions and one with the driver. |
|
If you prefer, different PRs is also fine (and allows us to merge things bit by bit). |
|
I would prefer 2 commits. One pr is easier I guess, but two is also fine. Whatever you prefer. |
|
FYI: there's a merge conflict here. |
6ca2cb4 to
f973478
Compare
This comment has been minimized.
This comment has been minimized.
soruh
left 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.
There are quite a few places where I'd like more safety comments and the address functions in net/mod.rs could probably be safer (see my comment there).
(I didn't look at the changes to module.rs)
rust/kernel/net/ethtool.rs
Outdated
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 comments should probably be updated to reflect that this struct describes which methods are implemented by an implementation of EthToolOps not which ones are defined by the trait itself.
rust/kernel/net/ethtool.rs
Outdated
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.
s/ipmlemeted/implemeted/
rust/kernel/net/rtnl.rs
Outdated
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 could use ptr::null_mut
rust/kernel/net/rtnl.rs
Outdated
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 as *const _ seems redundant
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, but I think rust wants them, as this is not directly the right type for the view of rust
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 in this case you don't need it is since you're turning a &rtnl_link_ops into a *const rtnl_link_ops. I agree that the other ones are necessary.
(I could of course be wrong about that and it's ultimately not that important)
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 be that I missed .0 befor. And then you need this. Is it is valid, but rust doesn't know that.
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.
That was probably the case, you can only do &T as *const T but not &U as *const T, even if U only contains a 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.
Yes, as U has repr Transparent. It would also be valid, but rust isn't able to check that. That's the reason to go over *const _
But yeah, will change it.
rust/kernel/net/rtnl.rs
Outdated
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 could be self.get_pointer() as *mut bindings::rtnl_link_ops
rust/kernel/net/skbuff.rs
Outdated
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.
Otherwise the packet could potentially already be freed.
This sounds like this function should potentially be unsafe.
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 It couldn't, as then we don't have self anymore? But not completely sure right now
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 don't follow completely, are you saying that this is indeed safe/you're not sure about it's safety or that this could't be an unsafe method?
If we're not certain about about the safety of a method, the default should really be making it unsafe.
rust/kernel/net/skbuff.rs
Outdated
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.
unnecessary parenthesis
drivers/net/dummy_rs.rs
Outdated
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.
use fn start_xmit(mut skb: SkBuff, ... and remove the let mut skb = skb;.
drivers/net/dummy_rs.rs
Outdated
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 does this return a Result if it can't fail?
drivers/net/dummy_rs.rs
Outdated
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 you could use the cstr! macro here
rust/kernel/net/mod.rs
Outdated
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 pretty sure this will need to use ptr::read_unaligned. Even if the underlying cpu architecture allows efficient unaligned accesses using normal load instructions, LLVM can optimize based on the assumption that addr as usize % 4 == 0. For example it could vectorize in ways that would cause overlap if the address is not aligned to 4 bytes. Or it could optimize away manual alignment checks. By the way you can use addr.offset(4) instead of addr as usize + 4.
rust/kernel/net/mod.rs
Outdated
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 was thinking that
| *(addr as *const u16) | |
| | *((addr as usize + 2) as *const u16) | |
| | *((addr as usize + 4) as *const u16) | |
| == 0 | |
| *(addr as *const [u16; 3]) == [0; 3] |
would be nicer to read. When I tested if LLVM would be able to optimize it I noticed the following: On x86_64 and aarch64 the current version uses 3 loads while the suggested version does 2 loads just like the CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS version. On armv7 this results in a branch + load from a constant pool for the suggested version while version uses 3 loads and no constant pool.
Because of this I think this suggestion should be used for CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS to avoid UB at no perf cost, but not(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) should remain 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.
Would it maybe make sense for all of these methods to take a &[u8; 6] and be completely safe to call or is there an inherent reason we need to treat these values as u16s?
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 CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS there would be no change. for not(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) that would require 6 loads (one for each u8) instead of 3 (one for each u16).
rust/kernel/net/device.rs
Outdated
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.
Note that Rust's polymorphize support is not yet mature, so one copy of each function might be monomorphized for each T. Not a big concern here though.
rust/kernel/net/device.rs
Outdated
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.
Any particular reason to use SCREAMING_SNAKE_CASE here?
rust/kernel/net/device.rs
Outdated
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 is likely to be very common in bindings. We may want a mini version of bitflags!.
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.
Excluding tests and docs the bitflags crate is a little less than 600 lines big. bitflags is a slow moving crate and doesn't implement a huge set of features. I don't know what the policy on vendoring extern crates is, but I don't think there is much benefit of writing a mini version over just vendoring bitflags. At most it would save codegen of a couple of methods, though most methods are marked as #[inline] and thus only codegened when used.
rust/kernel/net/ethtool.rs
Outdated
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 also seems to be pretty common for bindings. Maybe we need to have a attribute macro. I'll think about a sensible design.
rust/kernel/net/device.rs
Outdated
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.
s/refference/reference/g
rust/kernel/net/ethtool.rs
Outdated
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.
| /// Represents which fields of [`struct ethtool_ops`] should pe populated with pointers for the trait [`EthToolOps`] | |
| /// Represents which fields of [`struct ethtool_ops`] should be populated with pointers for the trait [`EthToolOps`] |
nit
ci: retry add-apt-repository to deal with network issues
|
Review of
|
|
Closing this, as it is quite outdated, and the commit history Is completely broken. |

add function for net_device functions
Contains #226 and #227