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

Commit ce7e742c authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Change the active context tracker"

parents 31b14076 990059b7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,8 @@ static struct adreno_device device_3d0 = {
	.pwrctrl_flag = BIT(ADRENO_SPTP_PC_CTRL) | BIT(ADRENO_PPD_CTRL) |
		BIT(ADRENO_LM_CTRL) | BIT(ADRENO_HWCG_CTRL),
	.profile.enabled = false,
	.active_list = LIST_HEAD_INIT(device_3d0.active_list),
	.active_list_lock = __SPIN_LOCK_UNLOCKED(device_3d0.active_list_lock),
};

/* Ptr to array for the current set of fault detect registers */
+5 −0
Original line number Diff line number Diff line
@@ -326,6 +326,8 @@ struct adreno_gpu_core {
 * @csdev: Pointer to a coresight device (if applicable)
 * @gpmu_throttle_counters - counteers for number of throttled clocks
 * @irq_storm_work: Worker to handle possible interrupt storms
 * @active_list: List to track active contexts
 * @active_list_lock: Lock to protect active_list
 */
struct adreno_device {
	struct kgsl_device dev;    /* Must be first field in this struct */
@@ -387,6 +389,9 @@ struct adreno_device {
	struct coresight_device *csdev;
	uint32_t gpmu_throttle_counters[ADRENO_GPMU_THROTTLE_COUNTERS];
	struct work_struct irq_storm_work;

	struct list_head active_list;
	spinlock_t active_list_lock;
};

/**
+55 −45
Original line number Diff line number Diff line
@@ -78,59 +78,69 @@ unsigned int adreno_cmdbatch_timeout = 2000;
/* Interval for reading and comparing fault detection registers */
static unsigned int _fault_timer_interval = 200;

/**
 * _track_context - Add a context ID to the list of recently seen contexts
 * for the command queue
 * @cmdqueue: cmdqueue to add the context to
 * @id: ID of the context to add
 *
 * This function is called when a new item is added to a context - this tracks
 * the number of active contexts seen in the last 100ms for the command queue
 */
static void _track_context(struct adreno_dispatcher_cmdqueue *cmdqueue,
		unsigned int id)
static void _add_context(struct adreno_device *adreno_dev,
		struct adreno_context *drawctxt)
{
	struct adreno_context_list *list = cmdqueue->active_contexts;
	int oldest = -1, empty = -1;
	unsigned long age = 0;
	int i, count = 0;
	bool updated = false;

	for (i = 0; i < ACTIVE_CONTEXT_LIST_MAX; i++) {

		/* If the new ID matches the slot update the expire time */
		if (list[i].id == id) {
			list[i].jiffies = jiffies + msecs_to_jiffies(100);
			updated = true;
			count++;
			continue;
		}
	/* Remove it from the list */
	list_del_init(&drawctxt->active_node);

		/* Remember and skip empty slots */
		if ((list[i].id == 0) ||
			time_after(jiffies, list[i].jiffies)) {
			empty = i;
			continue;
	/* And push it to the front */
	drawctxt->active_time = jiffies;
	list_add(&drawctxt->active_node, &adreno_dev->active_list);
}

		count++;
static int __count_context(struct adreno_context *drawctxt, void *data)
{
	unsigned long expires = drawctxt->active_time + msecs_to_jiffies(100);

		/* Remember the oldest active entry */
		if (oldest == -1 || time_before(list[i].jiffies, age)) {
			age = list[i].jiffies;
			oldest = i;
	return time_after(jiffies, expires) ? 0 : 1;
}

static int __count_cmdqueue_context(struct adreno_context *drawctxt, void *data)
{
	unsigned long expires = drawctxt->active_time + msecs_to_jiffies(100);

	if (time_after(jiffies, expires))
		return 0;

	return (&drawctxt->rb->dispatch_q ==
			(struct adreno_dispatcher_cmdqueue *) data) ? 1 : 0;
}

	if (updated == false) {
		int pos = (empty != -1) ? empty : oldest;
static int _adreno_count_active_contexts(struct adreno_device *adreno_dev,
		int (*func)(struct adreno_context *, void *), void *data)
{
	struct adreno_context *ctxt;
	int count = 0;

	list_for_each_entry(ctxt, &adreno_dev->active_list, active_node) {
		if (func(ctxt, data) == 0)
			return count;

		list[pos].jiffies = jiffies + msecs_to_jiffies(100);
		list[pos].id = id;
		count++;
	}

	cmdqueue->active_context_count = count;
	return count;
}

static void _track_context(struct adreno_device *adreno_dev,
		struct adreno_dispatcher_cmdqueue *cmdqueue,
		struct adreno_context *drawctxt)
{
	struct kgsl_device *device = KGSL_DEVICE(adreno_dev);

	spin_lock(&adreno_dev->active_list_lock);

	_add_context(adreno_dev, drawctxt);

	device->active_context_count =
			_adreno_count_active_contexts(adreno_dev,
					__count_context, NULL);
	cmdqueue->active_context_count =
			_adreno_count_active_contexts(adreno_dev,
					__count_cmdqueue_context, cmdqueue);

	spin_unlock(&adreno_dev->active_list_lock);
}

/*
@@ -1174,7 +1184,7 @@ int adreno_dispatcher_queue_cmd(struct adreno_device *adreno_dev,
	drawctxt->queued++;
	trace_adreno_cmdbatch_queued(cmdbatch, drawctxt->queued);

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

	spin_unlock(&drawctxt->lock);

+1 −10
Original line number Diff line number Diff line
@@ -64,28 +64,19 @@ enum adreno_dispatcher_starve_timer_states {

#define CMDQUEUE_NEXT(_i, _s) (((_i) + 1) % (_s))

#define ACTIVE_CONTEXT_LIST_MAX 2

struct adreno_context_list {
	unsigned int id;
	unsigned long jiffies;
};

/**
 * struct adreno_dispatcher_cmdqueue - List of commands for a RB level
 * @cmd_q: List of command batches submitted to dispatcher
 * @inflight: Number of commands inflight in this q
 * @head: Head pointer to the q
 * @tail: Queues tail pointer
 * @active_contexts: List of most recently seen contexts
 * @active_context_count: Number of active contexts in the active_contexts list
 * @active_context_count: Number of active contexts seen in this rb cmdqueue
 */
struct adreno_dispatcher_cmdqueue {
	struct kgsl_cmdbatch *cmd_q[ADRENO_DISPATCH_CMDQUEUE_SIZE];
	unsigned int inflight;
	unsigned int head;
	unsigned int tail;
	struct adreno_context_list active_contexts[ACTIVE_CONTEXT_LIST_MAX];
	int active_context_count;
};

+6 −0
Original line number Diff line number Diff line
@@ -420,6 +420,8 @@ adreno_drawctxt_create(struct kgsl_device_private *dev_priv,

	adreno_context_debugfs_init(ADRENO_DEVICE(device), drawctxt);

	INIT_LIST_HEAD(&drawctxt->active_node);

	/* copy back whatever flags we dediced were valid */
	*flags = drawctxt->base.flags;
	return &drawctxt->base;
@@ -462,6 +464,10 @@ void adreno_drawctxt_detach(struct kgsl_context *context)
	drawctxt = ADRENO_CONTEXT(context);
	rb = drawctxt->rb;

	spin_lock(&adreno_dev->active_list_lock);
	list_del_init(&drawctxt->active_node);
	spin_unlock(&adreno_dev->active_list_lock);

	/* deactivate context */
	mutex_lock(&device->mutex);
	if (rb->drawctxt_active == drawctxt) {
Loading