On Sun, 31 Mar 2024 at 07:27, Benno Lossin <benno.lossin@xxxxxxxxx> wrote: > > On 31.03.24 03:00, Wedson Almeida Filho wrote: > > On Wed, 27 Mar 2024 at 13:04, Benno Lossin <benno.lossin@xxxxxxxxx> wrote: > >> + #[cfg(not(MODULE))] > >> + #[doc(hidden)] > >> + #[no_mangle] > >> + pub extern \"C\" fn __{name}_exit() {{ > >> + __exit() > > I just noticed this should be wrapped in an `unsafe` block with a SAFETY > comment. Will fix this in v2. > > >> + }} > >> > >> - #[cfg(not(MODULE))] > >> - #[doc(hidden)] > >> - #[no_mangle] > >> - pub extern \"C\" fn __{name}_exit() {{ > >> - __exit() > >> - }} > >> + /// # Safety > >> + /// > >> + /// This function must > >> + /// - only be called once, > >> + /// - not be called concurrently with `__exit`. > > > > I don't think the second item is needed here, it really is a > > requirement on `__exit`. > > Fixed. > > > > >> + unsafe fn __init() -> core::ffi::c_int {{ > >> + match <{type_} as kernel::Module>::init(&THIS_MODULE) {{ > >> + Ok(m) => {{ > >> + // SAFETY: > >> + // no data race, since `__MOD` can only be accessed by this module and > >> + // there only `__init` and `__exit` access it. These functions are only > >> + // called once and `__exit` cannot be called before or during `__init`. > >> + unsafe {{ > >> + __MOD = Some(m); > >> + }} > >> + return 0; > >> + }} > >> + Err(e) => {{ > >> + return e.to_errno(); > >> + }} > >> + }} > >> + }} > >> > >> - fn __init() -> core::ffi::c_int {{ > >> - match <{type_} as kernel::Module>::init(&THIS_MODULE) {{ > >> - Ok(m) => {{ > >> + /// # Safety > >> + /// > >> + /// This function must > >> + /// - only be called once, > >> + /// - be called after `__init`, > >> + /// - not be called concurrently with `__init`. > > > > The second item is incomplete: it must be called after `__init` *succeeds*. > > Indeed. > > > > > With that added (which is a different precondition), I think the third > > item can be dropped because if you have to wait to see whether > > `__init` succeeded or failed before you can call `__exit`, then > > certainly you cannot call it concurrently with `__init`. > > I would love to drop that requirement, but I am not sure we can. With > that requirement, I wanted to ensure that no data race on `__MOD` can > happen. If you need to verify that `__init` succeeded, one might think > that it is not possible to call `__exit` such that a data race occurs, > but I think it could theoretically be done if the concrete `Module` > implementation never failed. I see. If you're concerned about compiler reordering, then we need compiler barriers. > Do you have any suggestion for what I could add to the "be called after > `__init` was called and returned `0`" requirement to make a data race > impossible? If you're concerned with reordering from the processor as well, then we need cpu barriers. You'd have to say that the cpu/thread executing `__init` must have a release barrier after `__init` completes, and the thread/cpu doing `__exit` must have an acquire barrier before starting `__exit`. But I'm not sure we need to go that far. Mostly because C is going to guarantee that ordering for us, so I'd say we can just omit this or perhaps say "This function must only be called from the exit module implementation". > -- > Cheers, > Benno > > > > >> + unsafe fn __exit() {{ > >> + // SAFETY: > >> + // no data race, since `__MOD` can only be accessed by this module and there > >> + // only `__init` and `__exit` access it. These functions are only called once > >> + // and `__init` was already called. > >> unsafe {{ > >> - __MOD = Some(m); > >> + // Invokes `drop()` on `__MOD`, which should be used for cleanup. > >> + __MOD = None; > >> }} > >> - return 0; > >> }} > >> - Err(e) => {{ > >> - return e.to_errno(); > >> - }} > >> - }} > >> - }} > >> > >> - fn __exit() {{ > >> - unsafe {{ > >> - // Invokes `drop()` on `__MOD`, which should be used for cleanup. > >> - __MOD = None; > >> + {modinfo} > >> }} > >> }} > >> - > >> - {modinfo} > >> ", > >> type_ = info.type_, > >> name = info.name, > >> > >> base-commit: 4cece764965020c22cff7665b18a012006359095 > >> -- > >> 2.44.0 > >> > >> >