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

Commit f290ff66 authored by Harshdeep Dhatt's avatar Harshdeep Dhatt Committed by Jordan Crouse
Browse files

msm: kgsl: Change drawctxt mutex to spinlock



adreno_drawctxt_dump is called from within timer context and hence
this function cannot sleep. But it needs exclusive access to its
cmdqueue. Therefore, changing the drawctxt mutex to spinlock.

Change-Id: I180c3a4703ffc51bb9929df44dae862e2e6a432b
Signed-off-by: default avatarHarshdeep Dhatt <hdhatt@codeaurora.org>
parent 41c7e1df
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -196,12 +196,12 @@ static int ctx_print(struct seq_file *s, void *unused)


	seq_puts(s, "cmdqueue:\n");
	seq_puts(s, "cmdqueue:\n");


	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);
	for (i = drawctxt->cmdqueue_head;
	for (i = drawctxt->cmdqueue_head;
		i != drawctxt->cmdqueue_tail;
		i != drawctxt->cmdqueue_tail;
		i = CMDQUEUE_NEXT(i, ADRENO_CONTEXT_CMDQUEUE_SIZE))
		i = CMDQUEUE_NEXT(i, ADRENO_CONTEXT_CMDQUEUE_SIZE))
		cmdbatch_print(s, drawctxt->cmdqueue[i]);
		cmdbatch_print(s, drawctxt->cmdqueue[i]);
	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);


	seq_puts(s, "events:\n");
	seq_puts(s, "events:\n");
	spin_lock(&drawctxt->base.events.lock);
	spin_lock(&drawctxt->base.events.lock);
+17 −17
Original line number Original line Diff line number Diff line
@@ -364,9 +364,9 @@ static struct kgsl_cmdbatch *adreno_dispatcher_get_cmdbatch(
{
{
	struct kgsl_cmdbatch *cmdbatch;
	struct kgsl_cmdbatch *cmdbatch;


	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);
	cmdbatch = _get_cmdbatch(drawctxt);
	cmdbatch = _get_cmdbatch(drawctxt);
	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);


	return cmdbatch;
	return cmdbatch;
}
}
@@ -385,11 +385,11 @@ static inline int adreno_dispatcher_requeue_cmdbatch(
		struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch)
		struct adreno_context *drawctxt, struct kgsl_cmdbatch *cmdbatch)
{
{
	unsigned int prev;
	unsigned int prev;
	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);


	if (kgsl_context_detached(&drawctxt->base) ||
	if (kgsl_context_detached(&drawctxt->base) ||
		kgsl_context_invalid(&drawctxt->base)) {
		kgsl_context_invalid(&drawctxt->base)) {
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);
		/* get rid of this cmdbatch since the context is bad */
		/* get rid of this cmdbatch since the context is bad */
		kgsl_cmdbatch_destroy(cmdbatch);
		kgsl_cmdbatch_destroy(cmdbatch);
		return -EINVAL;
		return -EINVAL;
@@ -411,7 +411,7 @@ static inline int adreno_dispatcher_requeue_cmdbatch(


	/* Reset the command queue head to reflect the newly requeued change */
	/* Reset the command queue head to reflect the newly requeued change */
	drawctxt->cmdqueue_head = prev;
	drawctxt->cmdqueue_head = prev;
	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);
	return 0;
	return 0;
}
}


@@ -792,7 +792,7 @@ static int _check_context_queue(struct adreno_context *drawctxt)
{
{
	int ret;
	int ret;


	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);


	/*
	/*
	 * Wake up if there is room in the context or if the whole thing got
	 * Wake up if there is room in the context or if the whole thing got
@@ -804,7 +804,7 @@ static int _check_context_queue(struct adreno_context *drawctxt)
	else
	else
		ret = drawctxt->queued < _context_cmdqueue_size ? 1 : 0;
		ret = drawctxt->queued < _context_cmdqueue_size ? 1 : 0;


	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);


	return ret;
	return ret;
}
}
@@ -861,10 +861,10 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,
				ADRENO_CMDBATCH_DISPATCH_CMDQUEUE(cmdbatch);
				ADRENO_CMDBATCH_DISPATCH_CMDQUEUE(cmdbatch);
	int ret;
	int ret;


	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);


	if (kgsl_context_detached(&drawctxt->base)) {
	if (kgsl_context_detached(&drawctxt->base)) {
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


@@ -921,17 +921,17 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,


	while (drawctxt->queued >= _context_cmdqueue_size) {
	while (drawctxt->queued >= _context_cmdqueue_size) {
		trace_adreno_drawctxt_sleep(drawctxt);
		trace_adreno_drawctxt_sleep(drawctxt);
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);


		ret = wait_event_interruptible_timeout(drawctxt->wq,
		ret = wait_event_interruptible_timeout(drawctxt->wq,
			_check_context_queue(drawctxt),
			_check_context_queue(drawctxt),
			msecs_to_jiffies(_context_queue_wait));
			msecs_to_jiffies(_context_queue_wait));


		mutex_lock(&drawctxt->mutex);
		spin_lock(&drawctxt->lock);
		trace_adreno_drawctxt_wake(drawctxt);
		trace_adreno_drawctxt_wake(drawctxt);


		if (ret <= 0) {
		if (ret <= 0) {
			mutex_unlock(&drawctxt->mutex);
			spin_unlock(&drawctxt->lock);
			return (ret == 0) ? -ETIMEDOUT : (int) ret;
			return (ret == 0) ? -ETIMEDOUT : (int) ret;
		}
		}
	}
	}
@@ -941,17 +941,17 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,
	 */
	 */


	if (kgsl_context_invalid(&drawctxt->base)) {
	if (kgsl_context_invalid(&drawctxt->base)) {
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);
		return -EDEADLK;
		return -EDEADLK;
	}
	}
	if (kgsl_context_detached(&drawctxt->base)) {
	if (kgsl_context_detached(&drawctxt->base)) {
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);
		return -EINVAL;
		return -EINVAL;
	}
	}


	ret = get_timestamp(drawctxt, cmdbatch, timestamp);
	ret = get_timestamp(drawctxt, cmdbatch, timestamp);
	if (ret) {
	if (ret) {
		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);
		return ret;
		return ret;
	}
	}


@@ -970,7 +970,7 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,
				drawctxt->queued);
				drawctxt->queued);


			_retire_marker(cmdbatch);
			_retire_marker(cmdbatch);
			mutex_unlock(&drawctxt->mutex);
			spin_unlock(&drawctxt->lock);
			return 0;
			return 0;
		}
		}


@@ -1025,7 +1025,7 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,


	_track_context(dispatch_q, drawctxt->base.id);
	_track_context(dispatch_q, drawctxt->base.id);


	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);


	/* Add the context to the dispatcher pending list */
	/* Add the context to the dispatcher pending list */
	dispatcher_queue_context(adreno_dev, drawctxt);
	dispatcher_queue_context(adreno_dev, drawctxt);
+9 −16
Original line number Original line Diff line number Diff line
@@ -62,12 +62,12 @@ void adreno_drawctxt_dump(struct kgsl_device *device,
	struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
	struct adreno_context *drawctxt = ADRENO_CONTEXT(context);
	int index, pos;
	int index, pos;
	char buf[120];
	char buf[120];
	mutex_lock(&drawctxt->mutex);


	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_QUEUED, &queue);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_QUEUED, &queue);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_CONSUMED, &start);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_CONSUMED, &start);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED, &retire);
	kgsl_readtimestamp(device, context, KGSL_TIMESTAMP_RETIRED, &retire);


	spin_lock(&drawctxt->lock);
	dev_err(device->dev,
	dev_err(device->dev,
		"  context[%d]: queue=%d, submit=%d, start=%d, retire=%d\n",
		"  context[%d]: queue=%d, submit=%d, start=%d, retire=%d\n",
		context->id, queue, drawctxt->submitted_timestamp,
		context->id, queue, drawctxt->submitted_timestamp,
@@ -108,7 +108,7 @@ void adreno_drawctxt_dump(struct kgsl_device *device,
	dev_err(device->dev, "  context[%d]: submit times: %s\n",
	dev_err(device->dev, "  context[%d]: submit times: %s\n",
		context->id, buf);
		context->id, buf);


	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);
}
}


/**
/**
@@ -233,11 +233,9 @@ void adreno_drawctxt_invalidate(struct kgsl_device *device,


	trace_adreno_drawctxt_invalidate(drawctxt);
	trace_adreno_drawctxt_invalidate(drawctxt);


	spin_lock(&drawctxt->lock);
	set_bit(KGSL_CONTEXT_PRIV_INVALID, &context->priv);
	set_bit(KGSL_CONTEXT_PRIV_INVALID, &context->priv);


	/* Clear the pending queue */
	mutex_lock(&drawctxt->mutex);

	/*
	/*
	 * set the timestamp to the last value since the context is invalidated
	 * set the timestamp to the last value since the context is invalidated
	 * and we want the pending events for this context to go away
	 * and we want the pending events for this context to go away
@@ -258,18 +256,13 @@ void adreno_drawctxt_invalidate(struct kgsl_device *device,
		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
			ADRENO_CONTEXT_CMDQUEUE_SIZE;
			ADRENO_CONTEXT_CMDQUEUE_SIZE;


		mutex_unlock(&drawctxt->mutex);

		mutex_lock(&device->mutex);
		kgsl_cancel_events_timestamp(device, &context->events,
		kgsl_cancel_events_timestamp(device, &context->events,
			cmdbatch->timestamp);
			cmdbatch->timestamp);
		mutex_unlock(&device->mutex);


		kgsl_cmdbatch_destroy(cmdbatch);
		kgsl_cmdbatch_destroy(cmdbatch);
		mutex_lock(&drawctxt->mutex);
	}
	}


	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);


	/* Make sure all "retired" events are processed */
	/* Make sure all "retired" events are processed */
	kgsl_process_event_group(device, &context->events);
	kgsl_process_event_group(device, &context->events);
@@ -365,7 +358,7 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv,
	drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS;
	drawctxt->base.flags |= KGSL_CONTEXT_PER_CONTEXT_TS;
	drawctxt->type = (drawctxt->base.flags & KGSL_CONTEXT_TYPE_MASK)
	drawctxt->type = (drawctxt->base.flags & KGSL_CONTEXT_TYPE_MASK)
		>> KGSL_CONTEXT_TYPE_SHIFT;
		>> KGSL_CONTEXT_TYPE_SHIFT;
	mutex_init(&drawctxt->mutex);
	spin_lock_init(&drawctxt->lock);
	init_waitqueue_head(&drawctxt->wq);
	init_waitqueue_head(&drawctxt->wq);
	init_waitqueue_head(&drawctxt->waiting);
	init_waitqueue_head(&drawctxt->waiting);


@@ -434,7 +427,7 @@ int adreno_drawctxt_detach(struct kgsl_context *context)
	if (rb->drawctxt_active == drawctxt)
	if (rb->drawctxt_active == drawctxt)
		adreno_drawctxt_switch(adreno_dev, rb, NULL, 0);
		adreno_drawctxt_switch(adreno_dev, rb, NULL, 0);


	mutex_lock(&drawctxt->mutex);
	spin_lock(&drawctxt->lock);


	while (drawctxt->cmdqueue_head != drawctxt->cmdqueue_tail) {
	while (drawctxt->cmdqueue_head != drawctxt->cmdqueue_tail) {
		struct kgsl_cmdbatch *cmdbatch =
		struct kgsl_cmdbatch *cmdbatch =
@@ -443,7 +436,7 @@ int adreno_drawctxt_detach(struct kgsl_context *context)
		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
		drawctxt->cmdqueue_head = (drawctxt->cmdqueue_head + 1) %
			ADRENO_CONTEXT_CMDQUEUE_SIZE;
			ADRENO_CONTEXT_CMDQUEUE_SIZE;


		mutex_unlock(&drawctxt->mutex);
		spin_unlock(&drawctxt->lock);


		/*
		/*
		 * If the context is deteached while we are waiting for
		 * If the context is deteached while we are waiting for
@@ -459,10 +452,10 @@ int adreno_drawctxt_detach(struct kgsl_context *context)
		 */
		 */


		kgsl_cmdbatch_destroy(cmdbatch);
		kgsl_cmdbatch_destroy(cmdbatch);
		mutex_lock(&drawctxt->mutex);
		spin_lock(&drawctxt->lock);
	}
	}


	mutex_unlock(&drawctxt->mutex);
	spin_unlock(&drawctxt->lock);
	/*
	/*
	 * internal_timestamp is set in adreno_ringbuffer_addcmds,
	 * internal_timestamp is set in adreno_ringbuffer_addcmds,
	 * which holds the device mutex. The entire context destroy
	 * which holds the device mutex. The entire context destroy
+1 −1
Original line number Original line Diff line number Diff line
@@ -57,7 +57,7 @@ struct adreno_context {
	unsigned int timestamp;
	unsigned int timestamp;
	unsigned int internal_timestamp;
	unsigned int internal_timestamp;
	unsigned int type;
	unsigned int type;
	struct mutex mutex;
	spinlock_t lock;


	/* Dispatcher */
	/* Dispatcher */
	struct kgsl_cmdbatch *cmdqueue[ADRENO_CONTEXT_CMDQUEUE_SIZE];
	struct kgsl_cmdbatch *cmdqueue[ADRENO_CONTEXT_CMDQUEUE_SIZE];