| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
| From: Connor O'Brien <connoro@google.com> |
| Date: Wed, 20 Feb 2019 12:17:48 -0800 |
| Subject: ANDROID: cpufreq: times: optimize proc files |
| |
| The majority of the time spent reading /proc/uid_time_in_state is due |
| to seq_printf calls. Use the faster seq_put_* variations instead. |
| |
| Also skip empty hash buckets in uid_seq_next for a further performance |
| improvement. |
| |
| Bug: 111216804 |
| Bug: 127641090 |
| Test: Read /proc/uid_time_in_state and confirm output is sane |
| Test: Compare read times to confirm performance improvement |
| Change-Id: If8783b498ed73d2ddb186a49438af41ac5ab9957 |
| Signed-off-by: Connor O'Brien <connoro@google.com> |
| --- |
| drivers/cpufreq/cpufreq_times.c | 22 ++++++++++++++-------- |
| 1 file changed, 14 insertions(+), 8 deletions(-) |
| |
| diff --git a/drivers/cpufreq/cpufreq_times.c b/drivers/cpufreq/cpufreq_times.c |
| index 42420c5e1e6f..2883d675b1eb 100644 |
| --- a/drivers/cpufreq/cpufreq_times.c |
| +++ b/drivers/cpufreq/cpufreq_times.c |
| @@ -193,10 +193,12 @@ static void *uid_seq_start(struct seq_file *seq, loff_t *pos) |
| |
| static void *uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
| { |
| - (*pos)++; |
| + do { |
| + (*pos)++; |
| |
| - if (*pos >= HASH_SIZE(uid_hash_table)) |
| - return NULL; |
| + if (*pos >= HASH_SIZE(uid_hash_table)) |
| + return NULL; |
| + } while (hlist_empty(&uid_hash_table[*pos])); |
| |
| return &uid_hash_table[*pos]; |
| } |
| @@ -220,7 +222,8 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) |
| if (freqs->freq_table[i] == |
| CPUFREQ_ENTRY_INVALID) |
| continue; |
| - seq_printf(m, " %d", freqs->freq_table[i]); |
| + seq_put_decimal_ull(m, " ", |
| + freqs->freq_table[i]); |
| } |
| } |
| seq_putc(m, '\n'); |
| @@ -229,13 +232,16 @@ static int uid_time_in_state_seq_show(struct seq_file *m, void *v) |
| rcu_read_lock(); |
| |
| hlist_for_each_entry_rcu(uid_entry, (struct hlist_head *)v, hash) { |
| - if (uid_entry->max_state) |
| - seq_printf(m, "%d:", uid_entry->uid); |
| + if (uid_entry->max_state) { |
| + seq_put_decimal_ull(m, "", uid_entry->uid); |
| + seq_putc(m, ':'); |
| + } |
| for (i = 0; i < uid_entry->max_state; ++i) { |
| + u64 time; |
| if (freq_index_invalid(i)) |
| continue; |
| - seq_printf(m, " %lu", (unsigned long)nsec_to_clock_t( |
| - uid_entry->time_in_state[i])); |
| + time = nsec_to_clock_t(uid_entry->time_in_state[i]); |
| + seq_put_decimal_ull(m, " ", time); |
| } |
| if (uid_entry->max_state) |
| seq_putc(m, '\n'); |