All of lore.kernel.org
 help / color / mirror / Atom feed
From: Viresh Kumar <viresh.kumar@linaro.org>
To: Kent Gibson <warthog618@gmail.com>
Cc: "Linus Walleij" <linus.walleij@linaro.org>,
	"Bartosz Golaszewski" <brgl@bgdev.pl>,
	"Vincent Guittot" <vincent.guittot@linaro.org>,
	linux-gpio@vger.kernel.org,
	"Miguel Ojeda" <miguel.ojeda.sandonis@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@google.com>,
	"Alex Bennée" <alex.bennee@linaro.org>,
	stratos-dev@op-lists.linaro.org,
	"Gerard Ryan" <g.m0n3y.2503@gmail.com>
Subject: Re: [PATCH V4 4/8] libgpiod: Add rust wrapper crate
Date: Wed, 27 Jul 2022 14:37:01 +0530	[thread overview]
Message-ID: <20220727090701.hfgv2thsd2w36wyg@vireshk-i7> (raw)
In-Reply-To: <20220727025754.GD88787@sol>

On 27-07-22, 10:57, Kent Gibson wrote:
> On Fri, Jul 08, 2022 at 05:04:57PM +0530, Viresh Kumar wrote:

> > +    /// Get the path used to find the chip.
> > +    pub fn get_path(&self) -> Result<&str> {
> 
> It seems absurd that a method that simply returns the path provided to
> open() requires a Result, but that is a consequence of wrapping.
> 
> I was considering suggesting caching a copy in struct Chip, but all the
> other methods require Results so at least this is consistent :-(.
> 
> Yay, more unwrapping than Xmas past.

:)

> > +        // SAFETY: The string returned by libgpiod is guaranteed to live as long
> > +        // as the `struct Chip`.
> > +        let path = unsafe { bindings::gpiod_chip_get_path(self.ichip.chip()) };
> 
> Trusting that it is never NULL?

I believe we discussed that early on (few months back) and decided this will
never be NULL and since the Rust wrappers are pretty much part of the same
repository, we can take that as a guarantee. An out-of-this-repository user
can't really assume that.

> Add a null check to be sure.

But I am fine with this as well.

> > +    /// Wait for line status events on any of the watched lines on the chip.
> > +    pub fn wait_info_event(&self, timeout: Duration) -> Result<()> {
> 
> Durations cannot be negative, so caller cannot make this block
> indefinitely.  Make timeout an Option? (no timeout => block)

I didn't know we want the always blocking capability as well. Yeah, Option
sounds like the right approach.

So in that case we just pass -1 to gpiod_chip_wait_info_event() ?

> > +        let ret = unsafe {
> > +            bindings::gpiod_chip_wait_info_event(self.ichip.chip(), timeout.as_nanos() as i64)
> > +        };

> > diff --git a/bindings/rust/src/chip_info.rs b/bindings/rust/src/chip_info.rs
> > +/// GPIO chip Information
> > +pub struct ChipInfo {
> > +    info: *mut bindings::gpiod_chip_info,
> > +}
> > +
> 
> Consider modules and namespaces rather than lumping everything in
> the gpiod space.
> 
> e.g. gpiod::ChipInfo -> gpiod::chip::Info

The modules are already there, as file names. So what we really have is
gpiod::chip_info::ChipInfo (yeah it isn't great for sure). But then it looked
tougher/complex/unnecessary for end users to know the internals of a dependency
and so I did this:

pub use crate::chip::*;
pub use crate::edge_event::*;
pub use crate::event_buffer::*;
pub use crate::info_event::*;
pub use crate::line_config::*;
pub use crate::line_info::*;
pub use crate::line_request::*;
pub use crate::request_config::*;

which puts everything under gpiod::*. I think it is easier for users that way.
The modules are fine for in-crate management, but for end user they shouldn't be
visible.

> > diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs
> > +/// Error codes for libgpiod operations
> > +#[derive(Copy, Clone, Debug, PartialEq, ThisError)]
> > +pub enum Error {

> > +    #[error("Operation {0} Failed: {1}")]
> > +    OperationFailed(&'static str, IoError),
> 
> Use an enum for the operation rather than a string?

Not sure I understood this.

> And if it returns an IoError it must be an IoOperation?
> Else if the IoError is just an errno then call it that.
> 
> > +}

> > diff --git a/bindings/rust/src/line_info.rs b/bindings/rust/src/line_info.rs
> > +/// Line info
> > +///
> > +/// Exposes functions for retrieving kernel information about both requested and
> > +/// free lines.  Line info object contains an immutable snapshot of a line's status.
> > +///
> > +/// The line info contains all the publicly available information about a
> > +/// line, which does not include the line value.  The line must be requested
> > +/// to access the line value.
> > +
> > +pub struct LineInfo {
> > +    info: *mut bindings::gpiod_line_info,
> > +    ichip: Option<Arc<ChipInternal>>,
> > +    free: bool,
> 
> This flag makes no sense - the info always needs to be freed no matter
> which path, watched or not, was taken to get it from the C API.

Not the one created with gpiod_info_event_get_line_info(), else it will result
in double free.

> > +    /// Stop watching the line
> > +    pub fn unwatch(&mut self) {
> > +        if let Some(ichip) = &self.ichip {
> > +            unsafe {
> > +                bindings::gpiod_chip_unwatch_line_info(ichip.chip(), self.get_offset());
> > +            }
> > +            self.ichip = None;
> > +        }
> > +    }
> > +
> 
> This should be a method of the chip, not the info.

I think there were some issues with my understanding of the whole watch thing.
Is there any existing example of gpiowatch somewhere ?

> > +impl TryFrom<&InfoEvent> for LineInfo {
> 
> Is try_from appropriate for getting a contained object?
> "from" normally refers to a type conversion.

Not sure, but as most of new() is going away here, I will likely move this to
info_event as well. No try-from with that.

> > +impl Drop for LineInfo {
> > +    fn drop(&mut self) {
> > +        // We must not free the Line info object created from `struct InfoEvent` by calling
> > +        // libgpiod API.
> > +        if self.free {
> > +            self.unwatch();
> 
> Why does dropping a LineInfo unwatch the line???

Because I thought it is related to the Line's info and we won't wanna watch once
line info is gone. Again, it is my wrong interpretation.

> > +    /// Get values of a subset of lines associated with the request.
> > +    pub fn get_values_subset(&self, offsets: &[u32], values: &mut Vec<i32>) -> Result<()> {
> > +        if offsets.len() != values.len() {
> > +            return Err(Error::OperationFailed(
> > +                "Gpio LineRequest array size mismatch",
> > +                IoError::new(EINVAL),
> > +            ));
> > +        }
> > +
> 
> Returned values are awkward to use as the user has to index into them
> using the index corresponding to the offset in offsets.
> Provide a Values type that maps offset to value, e.g. using an IntMap,
> and pass that in instead of separate offsets and values arrays.

We would need to separate out the offsets then as that's what
gpiod_line_request_get_values_subset() needs. Maybe take offsets, like now, as
an argument and return Result<IntMap> ?

> Same applies to set_values_subset().

That would be fine here though.

> > +    /// Set the size of the kernel event buffer for the request.
> > +    ///
> > +    /// The kernel may adjust the value if it's too high. If set to 0, the
> > +    /// default value will be used.
> > +    pub fn set_event_buffer_size(&self, size: u32) {
> > +        unsafe {
> > +            bindings::gpiod_request_config_set_event_buffer_size(self.config, size as c_ulong)
> > +        }
> > +    }
> 
> The kernel may adjust the value regardless - this value is a tentative
> suggestion to the kernel (the kernel buffers have to be sized in 2^N, so
> it generally rounds up to the next power of 2, within limits).
> 
> > +
> > +    /// Get the edge event buffer size for the request config.
> > +    pub fn get_event_buffer_size(&self) -> u32 {
> > +        unsafe { bindings::gpiod_request_config_get_event_buffer_size(self.config) as u32 }
> > +    }
> 
> You might want to note that this just reads the value from the config.
> The actual value used by the kernel is not made available to user space.

Do you want me to add these two comments for the above two routines ?

Other comments, which I removed, look acceptable to me. Will try to incorporate
all that in the next version.

Thanks a lot for the very thorough review.

-- 
viresh

  reply	other threads:[~2022-07-27  9:08 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-08 11:34 [PATCH V4 0/8] libgpiod: Add Rust bindings Viresh Kumar
2022-07-08 11:34 ` [PATCH V4 1/8] libgpiod: Add libgpiod-sys rust crate Viresh Kumar
2022-07-27  2:57   ` Kent Gibson
2022-07-27  4:51     ` Viresh Kumar
2022-07-27  5:17       ` Kent Gibson
2022-07-27  5:45         ` Viresh Kumar
2022-08-01 12:11         ` Viresh Kumar
2022-08-01 15:56           ` Kent Gibson
2022-08-02  8:50             ` Viresh Kumar
2022-08-02  9:36               ` Kent Gibson
2022-07-08 11:34 ` [PATCH V4 2/8] libgpiod: Add pre generated rust bindings Viresh Kumar
2022-07-27  2:57   ` Kent Gibson
2022-07-27  5:15     ` Viresh Kumar
2022-07-27  5:31       ` Kent Gibson
2022-07-27  6:00         ` Viresh Kumar
2022-07-27  6:06           ` Kent Gibson
2022-07-08 11:34 ` [PATCH V4 3/8] libgpiod-sys: Add support to generate gpiosim bindings Viresh Kumar
2022-07-27  2:57   ` Kent Gibson
2022-07-27  5:30     ` Viresh Kumar
2022-07-08 11:34 ` [PATCH V4 4/8] libgpiod: Add rust wrapper crate Viresh Kumar
2022-07-27  2:57   ` Kent Gibson
2022-07-27  9:07     ` Viresh Kumar [this message]
2022-07-27 10:08       ` Kent Gibson
2022-07-27 11:06         ` Miguel Ojeda
2022-07-27 12:40           ` Kent Gibson
2022-07-27 13:02             ` Miguel Ojeda
2022-07-28  3:11               ` Kent Gibson
2022-07-29  4:40                 ` Viresh Kumar
2022-07-28  3:10         ` Kent Gibson
2022-08-01 12:05         ` Viresh Kumar
2022-08-01 13:20           ` Kent Gibson
2022-08-01 13:28             ` Miguel Ojeda
2022-07-28  8:52     ` Viresh Kumar
2022-07-28  9:59       ` Kent Gibson
2022-07-08 11:34 ` [PATCH V4 5/8] libgpiod: Add rust examples Viresh Kumar
2022-07-27  2:58   ` Kent Gibson
2022-07-27  9:23     ` Viresh Kumar
2022-07-27  9:59       ` Kent Gibson
2022-07-27 10:06         ` Viresh Kumar
2022-07-27 10:32           ` Kent Gibson
2022-07-27 10:33             ` Viresh Kumar
2022-07-08 11:34 ` [PATCH V4 6/8] libgpiod: Derive debug traits for few definitions Viresh Kumar
2022-07-27  2:58   ` Kent Gibson
2022-07-27  6:20     ` Viresh Kumar
2022-07-08 11:35 ` [PATCH V4 7/8] libgpiod: Add rust tests Viresh Kumar
2022-07-27  2:58   ` Kent Gibson
2022-07-27  9:59     ` Viresh Kumar
2022-07-27 10:27       ` Kent Gibson
2022-08-01 11:54     ` Viresh Kumar
2022-08-01 12:38       ` Kent Gibson
2022-08-02  5:44         ` Viresh Kumar
2022-08-02  5:47           ` Kent Gibson
2022-07-08 11:35 ` [PATCH V4 8/8] libgpiod: Integrate building of rust bindings with make Viresh Kumar
2022-07-27  2:59   ` Kent Gibson
2022-07-27  6:18     ` Viresh Kumar
2022-07-27  6:25       ` Kent Gibson
2022-07-27  6:35         ` Viresh Kumar
2022-07-27  6:45           ` Kent Gibson
2022-07-27  6:51             ` Viresh Kumar
2022-07-15 19:07 ` [PATCH V4 0/8] libgpiod: Add Rust bindings Bartosz Golaszewski
2022-07-15 19:17   ` Miguel Ojeda
2022-07-15 19:27     ` Miguel Ojeda
2022-07-16  9:43       ` Miguel Ojeda
2022-07-16 10:43         ` Bartosz Golaszewski
2022-07-16 12:23           ` Kent Gibson
2022-07-16 13:46           ` Miguel Ojeda

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220727090701.hfgv2thsd2w36wyg@vireshk-i7 \
    --to=viresh.kumar@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=brgl@bgdev.pl \
    --cc=g.m0n3y.2503@gmail.com \
    --cc=linus.walleij@linaro.org \
    --cc=linux-gpio@vger.kernel.org \
    --cc=miguel.ojeda.sandonis@gmail.com \
    --cc=stratos-dev@op-lists.linaro.org \
    --cc=vincent.guittot@linaro.org \
    --cc=warthog618@gmail.com \
    --cc=wedsonaf@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.