Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da176acc authored by Jordan Crouse's avatar Jordan Crouse Committed by Jeremy Gebben
Browse files

msm: kgsl: Don't WARN in _kgsl_context_get



There is a sizable window between the reference count on a context
going to zero and it actually getting removed from the idr. In the
meantime somebody else could try to get the context and fail
kref_get_unless zero(). Thats okay - it just means that you can't
trust the pointer.  This mostly comes into play with kgsl_release()
which races with all the other things that hold a context reference.

Remove the WARN and trust that all callers of _kgl_context_get()
do the right thing (as of today, they do).

Change-Id: Ic0dedbadbd9f257042da9ea7e18e7ba4f27c1a0a
Signed-off-by: default avatarJordan Crouse <jcrouse@codeaurora.org>
parent f2a01c49
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -733,7 +733,7 @@ struct kgsl_cmdbatch *kgsl_cmdbatch_create(struct kgsl_device *device,

	if (!_kgsl_context_get(context)) {
		kfree(cmdbatch);
		return ERR_PTR(-EINVAL);
		return ERR_PTR(-ENOENT);
	}

	kref_init(&cmdbatch->refcount);
+1 −9
Original line number Diff line number Diff line
@@ -724,16 +724,8 @@ static inline int _kgsl_context_get(struct kgsl_context *context)
{
	int ret = 0;

	if (context) {
	if (context)
		ret = kref_get_unless_zero(&context->refcount);
		/*
		 * We shouldn't realistically fail kref_get_unless_zero unless
		 * we did something really dumb so make the failure both public
		 * and painful
		 */

		WARN_ON(!ret);
	}

	return ret;
}
+11 −3
Original line number Diff line number Diff line
/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -68,7 +68,12 @@ static void _process_event_group(struct kgsl_device *device,

	context = group->context;

	_kgsl_context_get(context);
	/*
	 * Sanity check to be sure that we we aren't racing with the context
	 * getting destroyed
	 */
	if (context != NULL && !_kgsl_context_get(context))
		BUG();

	spin_lock(&group->lock);

@@ -251,7 +256,10 @@ int kgsl_add_event(struct kgsl_device *device, struct kgsl_event_group *group,
		return -ENOMEM;

	/* Get a reference to the context while the event is active */
	_kgsl_context_get(context);
	if (context != NULL && !_kgsl_context_get(context)) {
		kmem_cache_free(events_cache, event);
		return -ENOENT;
	}

	event->device = device;
	event->context = context;
+4 −2
Original line number Diff line number Diff line
@@ -115,8 +115,10 @@ static int _add_fence_event(struct kgsl_device *device,
	 * Increase the refcount for the context to keep it through the
	 * callback
	 */

	_kgsl_context_get(context);
	if (!_kgsl_context_get(context)) {
		kfree(event);
		return -ENOENT;
	}

	event->context = context;
	event->timestamp = timestamp;