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

Commit 0a40fdf3 authored by qctecmdr Service's avatar qctecmdr Service Committed by Gerrit - the friendly Code Review server
Browse files

Merge "psi: introduce state_mask to represent stalled psi states"

parents 7a21db5e be807b64
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ enum psi_task_count {
	NR_IOWAIT,
	NR_MEMSTALL,
	NR_RUNNING,
	NR_PSI_TASK_COUNTS,
	NR_PSI_TASK_COUNTS = 3,
};

/* Task state bitmasks */
@@ -24,7 +24,7 @@ enum psi_res {
	PSI_IO,
	PSI_MEM,
	PSI_CPU,
	NR_PSI_RESOURCES,
	NR_PSI_RESOURCES = 3,
};

/*
@@ -41,7 +41,7 @@ enum psi_states {
	PSI_CPU_SOME,
	/* Only per-CPU, to weigh the CPU in the global average: */
	PSI_NONIDLE,
	NR_PSI_STATES,
	NR_PSI_STATES = 6,
};

struct psi_group_cpu {
@@ -53,6 +53,9 @@ struct psi_group_cpu {
	/* States of the tasks belonging to this group */
	unsigned int tasks[NR_PSI_TASK_COUNTS];

	/* Aggregate pressure state derived from the tasks */
	u32 state_mask;

	/* Period time sampling buckets for each state of interest (ns) */
	u32 times[NR_PSI_STATES];

+19 −10
Original line number Diff line number Diff line
@@ -213,17 +213,17 @@ static bool test_state(unsigned int *tasks, enum psi_states state)
static void get_recent_times(struct psi_group *group, int cpu, u32 *times)
{
	struct psi_group_cpu *groupc = per_cpu_ptr(group->pcpu, cpu);
	unsigned int tasks[NR_PSI_TASK_COUNTS];
	u64 now, state_start;
	enum psi_states s;
	unsigned int seq;
	int s;
	u32 state_mask;

	/* Snapshot a coherent view of the CPU state */
	do {
		seq = read_seqcount_begin(&groupc->seq);
		now = cpu_clock(cpu);
		memcpy(times, groupc->times, sizeof(groupc->times));
		memcpy(tasks, groupc->tasks, sizeof(groupc->tasks));
		state_mask = groupc->state_mask;
		state_start = groupc->state_start;
	} while (read_seqcount_retry(&groupc->seq, seq));

@@ -239,7 +239,7 @@ static void get_recent_times(struct psi_group *group, int cpu, u32 *times)
		 * (u32) and our reported pressure close to what's
		 * actually happening.
		 */
		if (test_state(tasks, s))
		if (state_mask & (1 << s))
			times[s] += now - state_start;

		delta = times[s] - groupc->times_prev[s];
@@ -407,15 +407,15 @@ static void record_times(struct psi_group_cpu *groupc, int cpu,
	delta = now - groupc->state_start;
	groupc->state_start = now;

	if (test_state(groupc->tasks, PSI_IO_SOME)) {
	if (groupc->state_mask & (1 << PSI_IO_SOME)) {
		groupc->times[PSI_IO_SOME] += delta;
		if (test_state(groupc->tasks, PSI_IO_FULL))
		if (groupc->state_mask & (1 << PSI_IO_FULL))
			groupc->times[PSI_IO_FULL] += delta;
	}

	if (test_state(groupc->tasks, PSI_MEM_SOME)) {
	if (groupc->state_mask & (1 << PSI_MEM_SOME)) {
		groupc->times[PSI_MEM_SOME] += delta;
		if (test_state(groupc->tasks, PSI_MEM_FULL))
		if (groupc->state_mask & (1 << PSI_MEM_FULL))
			groupc->times[PSI_MEM_FULL] += delta;
		else if (memstall_tick) {
			u32 sample;
@@ -436,10 +436,10 @@ static void record_times(struct psi_group_cpu *groupc, int cpu,
		}
	}

	if (test_state(groupc->tasks, PSI_CPU_SOME))
	if (groupc->state_mask & (1 << PSI_CPU_SOME))
		groupc->times[PSI_CPU_SOME] += delta;

	if (test_state(groupc->tasks, PSI_NONIDLE))
	if (groupc->state_mask & (1 << PSI_NONIDLE))
		groupc->times[PSI_NONIDLE] += delta;
}

@@ -448,6 +448,8 @@ static void psi_group_change(struct psi_group *group, int cpu,
{
	struct psi_group_cpu *groupc;
	unsigned int t, m;
	enum psi_states s;
	u32 state_mask = 0;

	groupc = per_cpu_ptr(group->pcpu, cpu);

@@ -480,6 +482,13 @@ static void psi_group_change(struct psi_group *group, int cpu,
		if (set & (1 << t))
			groupc->tasks[t]++;

	/* Calculate state mask representing active states */
	for (s = 0; s < NR_PSI_STATES; s++) {
		if (test_state(groupc->tasks, s))
			state_mask |= (1 << s);
	}
	groupc->state_mask = state_mask;

	write_seqcount_end(&groupc->seq);
}

+10 −0
Original line number Diff line number Diff line
@@ -920,6 +920,16 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task)
 * CONTEXT:
 * spin_lock_irq(rq->lock)
 *
 * This function is called during schedule() when a kworker is going
 * to sleep. It's used by psi to identify aggregation workers during
 * dequeuing, to allow periodic aggregation to shut-off when that
 * worker is the last task in the system or cgroup to go to sleep.
 *
 * As this function doesn't involve any workqueue-related locking, it
 * only returns stable values when called from inside the scheduler's
 * queuing and dequeuing paths, when @task, which must be a kworker,
 * is guaranteed to not be processing any works.
 *
 * Return:
 * The last work function %current executed as a worker, NULL if it
 * hasn't executed any work yet.