Skip to content

Commit

Permalink
Merge branch '14.0-matrix' into 14.0-DSP
Browse files Browse the repository at this point in the history
  • Loading branch information
kondors1995 committed Sep 1, 2024
2 parents 7ab31f0 + e5a1fc5 commit ad0cc65
Show file tree
Hide file tree
Showing 23 changed files with 488 additions and 430 deletions.
34 changes: 34 additions & 0 deletions Documentation/cgroup-v2.txt
Original file line number Diff line number Diff line change
Expand Up @@ -902,6 +902,13 @@ controller implements weight and absolute bandwidth limit models for
normal scheduling policy and absolute bandwidth allocation model for
realtime scheduling policy.

In all the above models, cycles distribution is defined only on a temporal
base and it does not account for the frequency at which tasks are executed.
The (optional) utilization clamping support allows to hint the schedutil
cpufreq governor about the minimum desired frequency which should always be
provided by a CPU, as well as the maximum desired frequency, which should not
be exceeded by a CPU.


CPU Interface Files
~~~~~~~~~~~~~~~~~~~
Expand Down Expand Up @@ -964,6 +971,33 @@ All time durations are in microseconds.
Shows pressure stall information for CPU. See
Documentation/accounting/psi.txt for details.

cpu.uclamp.min
A read-write single value file which exists on non-root cgroups.
The default is "0", i.e. no utilization boosting.

The requested minimum utilization (protection) as a percentage
rational number, e.g. 12.34 for 12.34%.

This interface allows reading and setting minimum utilization clamp
values similar to the sched_setattr(2). This minimum utilization
value is used to clamp the task specific minimum utilization clamp.

The requested minimum utilization (protection) is always capped by
the current value for the maximum utilization (limit), i.e.
`cpu.uclamp.max`.

cpu.uclamp.max
A read-write single value file which exists on non-root cgroups.
The default is "max". i.e. no utilization capping

The requested maximum utilization (limit) as a percentage rational
number, e.g. 98.76 for 98.76%.

This interface allows reading and setting maximum utilization clamp
values similar to the sched_setattr(2). This maximum utilization
value is used to clamp the task specific maximum utilization clamp.



Memory
------
Expand Down
4 changes: 2 additions & 2 deletions Documentation/scheduler/sched-tune.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,9 @@ Thus, with the sched_cfs_boost enabled we have the following main functions to
get the current utilization of a CPU:

cpu_util()
boosted_cpu_util()
stune_util()

The new boosted_cpu_util() is similar to the first but returns a boosted
The new stune_util() is similar to the first but returns a boosted
utilization signal which is a function of the sched_cfs_boost value.

This function is used in the CFS scheduler code paths where schedutil needs to
Expand Down
2 changes: 2 additions & 0 deletions arch/arm64/configs/raphael_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ CONFIG_TOOLS_SUPPORT_RELR=y
CONFIG_LOCALVERSION="-SOVIET-STAR-"
CONFIG_INLINE_OPTIMIZATION=y
# CONFIG_FHANDLE is not set
CONFIG_AUDIT=y
CONFIG_IRQ_SBALANCE=y
CONFIG_SBALANCE_EXCLUDE_CPUS="3,6,7"
CONFIG_NO_HZ=y
Expand All @@ -24,6 +25,7 @@ CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_SCHED=y
# CONFIG_FAIR_GROUP_SCHED is not set
CONFIG_UCLAMP_TASK_GROUP=y
CONFIG_UCLAMP_ASSIST=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export THINLTO_CACHE=~/ltocache/
DEFCONFIG="raphael_defconfig"

# Kernel Details
REV="R6.4"
REV="R6.5"

EDITION="DSP"
VER="$EDITION"-"$REV"
Expand Down
20 changes: 5 additions & 15 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -537,21 +537,11 @@ unsigned int cpufreq_policy_transition_delay_us(struct cpufreq_policy *policy)
return policy->transition_delay_us;

latency = policy->cpuinfo.transition_latency / NSEC_PER_USEC;
if (latency) {
/*
* For platforms that can change the frequency very fast (< 10
* us), the above formula gives a decent transition delay. But
* for platforms where transition_latency is in milliseconds, it
* ends up giving unrealistic values.
*
* Cap the default transition delay to 10 ms, which seems to be
* a reasonable amount of time after which we should reevaluate
* the frequency.
*/
return min(latency * LATENCY_MULTIPLIER, (unsigned int)10000);
}
if (latency)
/* Give a 50% breathing room between updates */
return latency + (latency >> 1);

return LATENCY_MULTIPLIER;
return USEC_PER_MSEC;
}
EXPORT_SYMBOL_GPL(cpufreq_policy_transition_delay_us);

Expand Down Expand Up @@ -1880,7 +1870,7 @@ unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy,
int ret;
target_freq = clamp_val(target_freq, policy->min, policy->max);

ret = cpufreq_driver->fast_switch(policy, target_freq);
ret = cpufreq_driver->fast_switch(policy, target_freq);
if (ret) {
cpufreq_times_record_transition(policy, ret);
cpufreq_stats_record_transition(policy, ret);
Expand Down
119 changes: 86 additions & 33 deletions drivers/cpufreq/cpufreq_stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,72 +12,124 @@
#include <linux/cpu.h>
#include <linux/cpufreq.h>
#include <linux/module.h>
#include <linux/sched/clock.h>
#include <linux/slab.h>

struct cpufreq_stats {
unsigned int total_trans;
atomic64_t last_time;
unsigned long long last_time;
unsigned int max_state;
unsigned int state_num;
unsigned int last_index;
atomic64_t *time_in_state;
u64 *time_in_state;
unsigned int *freq_table;
unsigned int *trans_table;

/* Deferred reset */
unsigned int reset_pending;
unsigned long long reset_time;
};

static void cpufreq_stats_update(struct cpufreq_stats *stats)
static void cpufreq_stats_update(struct cpufreq_stats *stats,
unsigned long long time)
{
unsigned long long cur_time = get_jiffies_64();
unsigned long long time = cur_time;
unsigned long long cur_time = local_clock();

time = atomic64_xchg(&stats->last_time, time);
atomic64_add(cur_time - time, &stats->time_in_state[stats->last_index]);
stats->time_in_state[stats->last_index] += cur_time - time;
stats->last_time = cur_time;
}

static void cpufreq_stats_clear_table(struct cpufreq_stats *stats)
static void cpufreq_stats_reset_table(struct cpufreq_stats *stats)
{
unsigned int count = stats->max_state;

memset(stats->time_in_state, 0, count * sizeof(atomic64_t));
memset(stats->time_in_state, 0, count * sizeof(u64));
memset(stats->trans_table, 0, count * count * sizeof(int));
atomic64_set(&stats->last_time, get_jiffies_64());
stats->last_time = local_clock();
stats->total_trans = 0;

/* Adjust for the time elapsed since reset was requested */
WRITE_ONCE(stats->reset_pending, 0);
/*
* Prevent the reset_time read from being reordered before the
* reset_pending accesses in cpufreq_stats_record_transition().
*/
smp_rmb();
cpufreq_stats_update(stats, READ_ONCE(stats->reset_time));
}

static ssize_t show_total_trans(struct cpufreq_policy *policy, char *buf)
{
return sprintf(buf, "%d\n", policy->stats->total_trans);
struct cpufreq_stats *stats = policy->stats;

if (READ_ONCE(stats->reset_pending))
return sprintf(buf, "%d\n", 0);
else
return sprintf(buf, "%u\n", stats->total_trans);
}
cpufreq_freq_attr_ro(total_trans);

static ssize_t show_time_in_state(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stats = policy->stats;
bool pending = READ_ONCE(stats->reset_pending);
unsigned long long time;
ssize_t len = 0;
int i;

cpufreq_stats_update(stats);
for (i = 0; i < stats->state_num; i++) {
if (pending) {
if (i == stats->last_index) {
/*
* Prevent the reset_time read from occurring
* before the reset_pending read above.
*/
smp_rmb();
time = local_clock() - READ_ONCE(stats->reset_time);
} else {
time = 0;
}
} else {
time = stats->time_in_state[i];
if (i == stats->last_index)
time += local_clock() - stats->last_time;
}

len += sprintf(buf + len, "%u %llu\n", stats->freq_table[i],
(unsigned long long)
jiffies_64_to_clock_t(atomic64_read(
&stats->time_in_state[i])));
nsec_to_clock_t(time));
}
return len;
}
cpufreq_freq_attr_ro(time_in_state);

/* We don't care what is written to the attribute */
static ssize_t store_reset(struct cpufreq_policy *policy, const char *buf,
size_t count)
{
/* We don't care what is written to the attribute. */
cpufreq_stats_clear_table(policy->stats);
struct cpufreq_stats *stats = policy->stats;

/*
* Defer resetting of stats to cpufreq_stats_record_transition() to
* avoid races.
*/
WRITE_ONCE(stats->reset_time, local_clock());
/*
* The memory barrier below is to prevent the readers of reset_time from
* seeing a stale or partially updated value.
*/
smp_wmb();
WRITE_ONCE(stats->reset_pending, 1);

return count;
}
cpufreq_freq_attr_wo(reset);

static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
{
struct cpufreq_stats *stats = policy->stats;
bool pending = READ_ONCE(stats->reset_pending);
ssize_t len = 0;
int i, j;
int i, j, count;

len += scnprintf(buf + len, PAGE_SIZE - len, " From : To\n");
len += scnprintf(buf + len, PAGE_SIZE - len, " : ");
Expand All @@ -102,8 +154,13 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
for (j = 0; j < stats->state_num; j++) {
if (len >= PAGE_SIZE)
break;
len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ",
stats->trans_table[i*stats->max_state+j]);

if (pending)
count = 0;
else
count = stats->trans_table[i * stats->max_state + j];

len += scnprintf(buf + len, PAGE_SIZE - len, "%9u ", count);
}
if (len >= PAGE_SIZE)
break;
Expand All @@ -118,10 +175,6 @@ static ssize_t show_trans_table(struct cpufreq_policy *policy, char *buf)
}
cpufreq_freq_attr_ro(trans_table);

cpufreq_freq_attr_ro(total_trans);
cpufreq_freq_attr_ro(time_in_state);
cpufreq_freq_attr_wo(reset);

static struct attribute *default_attrs[] = {
&total_trans.attr,
&time_in_state.attr,
Expand Down Expand Up @@ -161,7 +214,7 @@ void cpufreq_stats_free_table(struct cpufreq_policy *policy)

void cpufreq_stats_create_table(struct cpufreq_policy *policy)
{
unsigned int i = 0, count = 0, ret = -ENOMEM;
unsigned int i = 0, count;
struct cpufreq_stats *stats;
unsigned int alloc_size;
struct cpufreq_frequency_table *pos;
Expand All @@ -178,7 +231,7 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
if (!stats)
return;

alloc_size = count * sizeof(int) + count * sizeof(atomic64_t);
alloc_size = count * sizeof(int) + count * sizeof(u64);

alloc_size += count * count * sizeof(int);

Expand All @@ -199,12 +252,11 @@ void cpufreq_stats_create_table(struct cpufreq_policy *policy)
stats->freq_table[i++] = pos->frequency;

stats->state_num = i;
atomic64_set(&stats->last_time, get_jiffies_64());
stats->last_time = local_clock();
stats->last_index = freq_table_get_index(stats, policy->cur);

policy->stats = stats;
ret = sysfs_create_group(&policy->kobj, &stats_attr_group);
if (!ret)
if (!sysfs_create_group(&policy->kobj, &stats_attr_group))
return;

/* We failed, release resources */
Expand All @@ -220,10 +272,11 @@ void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
struct cpufreq_stats *stats = policy->stats;
int old_index, new_index;

if (unlikely(!stats)) {
pr_debug("%s: No stats found\n", __func__);
if (unlikely(!stats))
return;
}

if (unlikely(READ_ONCE(stats->reset_pending)))
cpufreq_stats_reset_table(stats);

old_index = stats->last_index;
new_index = freq_table_get_index(stats, new_freq);
Expand All @@ -232,7 +285,7 @@ void cpufreq_stats_record_transition(struct cpufreq_policy *policy,
if (unlikely(old_index == -1 || new_index == -1 || old_index == new_index))
return;

cpufreq_stats_update(stats);
cpufreq_stats_update(stats, stats->last_time);

stats->last_index = new_index;
stats->trans_table[old_index * stats->max_state + new_index]++;
Expand Down
1 change: 0 additions & 1 deletion drivers/platform/msm/gsi/gsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ static void gsi_process_chan(struct gsi_xfer_compl_evt *evt,
if (callback) {
if (unlikely(atomic_read(&ch_ctx->poll_mode))) {
GSIERR("Calling client callback in polling mode\n");
WARN_ON(1);
}
ch_ctx->props.xfer_cb(notify);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,8 @@ util_scan_parse_rnr_ie(struct scan_cache_entry *scan_entry,
rnr_ie_len = ie->ie_len;
data = (uint8_t *)ie + sizeof(struct ie_header);

while (data < ((uint8_t *)ie + rnr_ie_len + 2)) {
while ((data + sizeof(struct neighbor_ap_info_field)) <=
((uint8_t *)ie + rnr_ie_len + 2)) {
neighbor_ap_info = (struct neighbor_ap_info_field *)data;
tbtt_count = neighbor_ap_info->tbtt_header.tbtt_info_count;
tbtt_length = neighbor_ap_info->tbtt_header.tbtt_info_length;
Expand All @@ -725,7 +726,8 @@ util_scan_parse_rnr_ie(struct scan_cache_entry *scan_entry,
break;

for (i = 0; i < (tbtt_count + 1) &&
data < ((uint8_t *)ie + rnr_ie_len + 2); i++) {
(data + tbtt_length) <=
((uint8_t *)ie + rnr_ie_len + 2); i++) {
if (i < MAX_RNR_BSS)
util_scan_update_rnr(
&scan_entry->rnr.bss_info[i],
Expand Down
8 changes: 0 additions & 8 deletions include/linux/cpufreq.h
Original file line number Diff line number Diff line change
Expand Up @@ -493,14 +493,6 @@ static inline unsigned long cpufreq_scale(unsigned long old, u_int div,
#define CPUFREQ_POLICY_POWERSAVE (1)
#define CPUFREQ_POLICY_PERFORMANCE (2)

/*
* The polling frequency depends on the capability of the processor. Default
* polling frequency is 1000 times the transition latency of the processor. The
* ondemand governor will work on any processor with transition latency <= 10ms,
* using appropriate sampling rate.
*/
#define LATENCY_MULTIPLIER (1000)

struct cpufreq_governor {
char name[CPUFREQ_NAME_LEN];
int (*init)(struct cpufreq_policy *policy);
Expand Down
Loading

0 comments on commit ad0cc65

Please sign in to comment.