On Thu, Feb 13, 2020 at 12:03:32PM -0500, Marcelo Diop-Gonzalez wrote:
> On Wed, Feb 12, 2020 at 1:43 PM Marcelo Diop-Gonzalez
> <marcgonza...@google.com> wrote:
> >
> > There are a few places where a service's reference count is incremented,
> > something quick is done, and the refcount is dropped. This can be made
> > a little simpler/faster by not grabbing a reference in these cases.
> >
> > Signed-off-by: Marcelo Diop-Gonzalez <marcgonza...@google.com>
> > ---
> >  .../interface/vchiq_arm/vchiq_arm.c           | 16 ++++-----
> >  .../interface/vchiq_arm/vchiq_core.c          | 36 +++++++++++++------
> >  .../interface/vchiq_arm/vchiq_core.h          |  8 ++++-
> >  3 files changed, 40 insertions(+), 20 deletions(-)
> >
> > diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c 
> > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > index 3ed0e4ea7f5c..b377f18aed45 100644
> > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
> > @@ -2497,11 +2497,11 @@ vchiq_instance_get_use_count(struct vchiq_instance 
> > *instance)
> >         int use_count = 0, i;
> >
> >         i = 0;
> > -       while ((service = next_service_by_instance(instance->state,
> > -               instance, &i))) {
> > +       rcu_read_lock();
> > +       while ((service = __next_service_by_instance(instance->state,
> > +                                                    instance, &i)))
> >                 use_count += service->service_use_count;
> > -               unlock_service(service);
> > -       }
> > +       rcu_read_unlock();
> >         return use_count;
> >  }
> >
> > @@ -2524,11 +2524,11 @@ vchiq_instance_set_trace(struct vchiq_instance 
> > *instance, int trace)
> >         int i;
> >
> >         i = 0;
> > -       while ((service = next_service_by_instance(instance->state,
> > -               instance, &i))) {
> > +       rcu_read_lock();
> > +       while ((service = __next_service_by_instance(instance->state,
> > +                                                    instance, &i)))
> >                 service->trace = trace;
> > -               unlock_service(service);
> > -       }
> > +       rcu_read_unlock();
> >         instance->trace = (trace != 0);
> >  }
> >
> > diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c 
> > b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> > index 65270a5b29db..d7d7f4d9d57f 100644
> > --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> > +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
> > @@ -222,28 +222,42 @@ find_closed_service_for_instance(struct 
> > vchiq_instance *instance,
> >  }
> >
> >  struct vchiq_service *
> > -next_service_by_instance(struct vchiq_state *state, struct vchiq_instance 
> > *instance,
> > -                        int *pidx)
> > +__next_service_by_instance(struct vchiq_state *state,
> > +                          struct vchiq_instance *instance,
> > +                          int *pidx)
> >  {
> >         struct vchiq_service *service = NULL;
> >         int idx = *pidx;
> >
> > -       rcu_read_lock();
> >         while (idx < state->unused_service) {
> >                 struct vchiq_service *srv;
> >
> >                 srv = rcu_dereference(state->services[idx++]);
> >                 if (srv && srv->srvstate != VCHIQ_SRVSTATE_FREE &&
> > -                   srv->instance == instance &&
> > -                   kref_get_unless_zero(&srv->ref_count)) {
> > -                       service = rcu_pointer_handoff(srv);
> > +                   srv->instance == instance) {
> > +                       service = srv;
> >                         break;
> >                 }
> >         }
> > -       rcu_read_unlock();
> >
> >         *pidx = idx;
> > +       return service;
> > +}
> >
> > +struct vchiq_service *
> > +next_service_by_instance(struct vchiq_state *state,
> > +                        struct vchiq_instance *instance,
> > +                        int *pidx)
> > +{
> > +       struct vchiq_service *service;
> > +
> > +       rcu_read_lock();
> > +       service = __next_service_by_instance(state, instance, pidx);
> > +       if (service && kref_get_unless_zero(&service->ref_count))
> > +               service = rcu_pointer_handoff(service);
> > +       else
> > +               service = NULL;
> > +       rcu_read_unlock();
> >         return service;
> >  }
> 
> ahh wait, this one is buggy..... If kref_get_unless_zero fails then we
> want to keep looking
> for the next one. Greg, since you already applied this one, would it
> be best for me to send
> a patch on top of this or send a V2?

On top is easiest for me, I don't like to revert things :)

thanks,

greg k-h
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to