Commit a2203cfe authored by Marcelo Diop-Gonzalez's avatar Marcelo Diop-Gonzalez Committed by Greg Kroah-Hartman

staging: vc04_services: don't increment service refcount when it's not needed

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: default avatarMarcelo Diop-Gonzalez <marcgonzalez@google.com>
Link: https://lore.kernel.org/r/ac6186ac888f1acf489b5b504efcba8b0d6a8b25.1581532523.git.marcgonzalez@google.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3c27a36f
...@@ -2497,11 +2497,11 @@ vchiq_instance_get_use_count(struct vchiq_instance *instance) ...@@ -2497,11 +2497,11 @@ vchiq_instance_get_use_count(struct vchiq_instance *instance)
int use_count = 0, i; int use_count = 0, i;
i = 0; i = 0;
while ((service = next_service_by_instance(instance->state, rcu_read_lock();
instance, &i))) { while ((service = __next_service_by_instance(instance->state,
instance, &i)))
use_count += service->service_use_count; use_count += service->service_use_count;
unlock_service(service); rcu_read_unlock();
}
return use_count; return use_count;
} }
...@@ -2524,11 +2524,11 @@ vchiq_instance_set_trace(struct vchiq_instance *instance, int trace) ...@@ -2524,11 +2524,11 @@ vchiq_instance_set_trace(struct vchiq_instance *instance, int trace)
int i; int i;
i = 0; i = 0;
while ((service = next_service_by_instance(instance->state, rcu_read_lock();
instance, &i))) { while ((service = __next_service_by_instance(instance->state,
instance, &i)))
service->trace = trace; service->trace = trace;
unlock_service(service); rcu_read_unlock();
}
instance->trace = (trace != 0); instance->trace = (trace != 0);
} }
......
...@@ -222,28 +222,42 @@ find_closed_service_for_instance(struct vchiq_instance *instance, ...@@ -222,28 +222,42 @@ find_closed_service_for_instance(struct vchiq_instance *instance,
} }
struct vchiq_service * struct vchiq_service *
next_service_by_instance(struct vchiq_state *state, struct vchiq_instance *instance, __next_service_by_instance(struct vchiq_state *state,
struct vchiq_instance *instance,
int *pidx) int *pidx)
{ {
struct vchiq_service *service = NULL; struct vchiq_service *service = NULL;
int idx = *pidx; int idx = *pidx;
rcu_read_lock();
while (idx < state->unused_service) { while (idx < state->unused_service) {
struct vchiq_service *srv; struct vchiq_service *srv;
srv = rcu_dereference(state->services[idx++]); srv = rcu_dereference(state->services[idx++]);
if (srv && srv->srvstate != VCHIQ_SRVSTATE_FREE && if (srv && srv->srvstate != VCHIQ_SRVSTATE_FREE &&
srv->instance == instance && srv->instance == instance) {
kref_get_unless_zero(&srv->ref_count)) { service = srv;
service = rcu_pointer_handoff(srv);
break; break;
} }
} }
rcu_read_unlock();
*pidx = idx; *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; return service;
} }
...@@ -283,13 +297,13 @@ unlock_service(struct vchiq_service *service) ...@@ -283,13 +297,13 @@ unlock_service(struct vchiq_service *service)
int int
vchiq_get_client_id(unsigned int handle) vchiq_get_client_id(unsigned int handle)
{ {
struct vchiq_service *service = find_service_by_handle(handle); struct vchiq_service *service;
int id; int id;
rcu_read_lock();
service = handle_to_service(handle);
id = service ? service->client_id : 0; id = service ? service->client_id : 0;
if (service) rcu_read_unlock();
unlock_service(service);
return id; return id;
} }
......
...@@ -572,7 +572,13 @@ find_closed_service_for_instance(struct vchiq_instance *instance, ...@@ -572,7 +572,13 @@ find_closed_service_for_instance(struct vchiq_instance *instance,
unsigned int handle); unsigned int handle);
extern struct vchiq_service * extern struct vchiq_service *
next_service_by_instance(struct vchiq_state *state, struct vchiq_instance *instance, __next_service_by_instance(struct vchiq_state *state,
struct vchiq_instance *instance,
int *pidx);
extern struct vchiq_service *
next_service_by_instance(struct vchiq_state *state,
struct vchiq_instance *instance,
int *pidx); int *pidx);
extern void extern void
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment