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

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.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3c27a36f
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -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);
}

+25 −11
Original line number Diff line number Diff line
@@ -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,
__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;
}

@@ -283,13 +297,13 @@ unlock_service(struct vchiq_service *service)
int
vchiq_get_client_id(unsigned int handle)
{
	struct vchiq_service *service = find_service_by_handle(handle);
	struct vchiq_service *service;
	int id;

	rcu_read_lock();
	service = handle_to_service(handle);
	id = service ? service->client_id : 0;
	if (service)
		unlock_service(service);

	rcu_read_unlock();
	return id;
}

+7 −1
Original line number Diff line number Diff line
@@ -572,7 +572,13 @@ find_closed_service_for_instance(struct vchiq_instance *instance,
	unsigned int handle);

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);

extern void