On Wed, Oct 14, 2020 at 12:43:08PM -0500, David Lechner wrote:
> On 9/26/20 9:18 PM, William Breathitt Gray wrote:
> > diff --git a/drivers/counter/counter-chrdev.c 
> > b/drivers/counter/counter-chrdev.c
> > new file mode 100644
> > index 000000000000..2be3846e4105
> > --- /dev/null
> > +++ b/drivers/counter/counter-chrdev.c
> 
> 
> > +/**
> > + * counter_push_event - queue event for userspace reading
> > + * @counter:       pointer to Counter structure
> > + * @event: triggered event
> > + * @channel:       event channel
> > + *
> > + * Note: If no one is watching for the respective event, it is silently
> > + * discarded.
> > + *
> > + * RETURNS:
> > + * 0 on success, negative error number on failure.
> > + */
> > +int counter_push_event(struct counter_device *const counter, const u8 
> > event,
> > +                  const u8 channel)
> > +{
> > +   struct counter_event ev = {0};
> > +   unsigned int copied = 0;
> > +   unsigned long flags;
> > +   struct counter_event_node *event_node;
> > +   struct counter_comp_node *comp_node;
> > +   int err;
> > +
> > +   ev.timestamp = ktime_get_ns();
> > +   ev.watch.event = event;
> > +   ev.watch.channel = channel;
> > +
> > +   raw_spin_lock_irqsave(&counter->events_lock, flags);
> > +
> > +   /* Search for event in the list */
> > +   list_for_each_entry(event_node, &counter->events_list, l)
> > +           if (event_node->event == event &&
> > +               event_node->channel == channel)
> > +                   break;
> > +
> > +   /* If event is not in the list */
> > +   if (&event_node->l == &counter->events_list)
> > +           goto exit_early;
> > +
> > +   /* Read and queue relevant comp for userspace */
> > +   list_for_each_entry(comp_node, &event_node->comp_list, l) {
> > +           err = counter_get_data(counter, comp_node, &ev.value_u8);
> 
> Currently all counter devices are memory mapped devices so calling
> counter_get_data() here with interrupts disabled is probably OK, but
> if any counter drivers are added that use I2C/SPI/etc. that will take
> a long time to read, it would cause problems leaving interrupts
> disabled here.
> 
> Brainstorming: Would it make sense to separate the event from the
> component value being read? As I mentioned in one of my previous
> reviews, I think there are some cases where we would just want to
> know when an event happened and not read any additional data anyway.
> In the case of a slow communication bus, this would also let us
> queue the event in the kfifo and notify poll right away and then
> defer the reads in a workqueue for later.

I don't see any problems with reporting just an event without any
component value attached (e.g. userspace could handle the component
reads via sysfs at a later point). We would just need a way to inform
userspace that the struct counter_component in the struct counter_watch
returned should be ignored.

Perhaps we can add an additional member to struct counter_watch
indicating whether it's an empty watch; or alternatively, add a new
component scope define to differentiate between an actual component and
an empty one (e.g. COUNTER_SCOPE_EVENT). What do you think?

William Breathitt Gray

Attachment: signature.asc
Description: PGP signature

Reply via email to