diff options
| author | Wei Wang <wvw@google.com> | 2017-03-13 12:22:21 -0700 |
|---|---|---|
| committer | Jin Qian <jinqian@google.com> | 2017-03-14 23:53:27 +0000 |
| commit | 75a7736c2ad9b019ac131f124f53f3c194bf3c95 (patch) | |
| tree | 56f1bb6541dec244bcdab124546aff84d59df904 /drivers/misc | |
| parent | 4b20ed9406bc88023353f04e07788ed4c3846aa2 (diff) | |
uid_sys_stats: change to use rt_mutex
We see this happens multiple times in heavy workload in systrace
and AMS stuck in uid_lock.
Running process: Process 953
Running thread: android.ui
State: Uninterruptible Sleep
Start:
1,025.628 ms
Duration:
27,955.949 ms
On CPU:
Running instead: system_server
Args:
{kernel callsite when blocked:: "uid_procstat_write+0xb8/0x144"}
Changing to rt_mutex can mitigate the priority inversion
Bug: 34991231
Bug: 34193533
Test: on marlin
Change-Id: I28eb3971331cea60b1075740c792ab87d103262c
Signed-off-by: Wei Wang <wvw@google.com>
Diffstat (limited to 'drivers/misc')
| -rw-r--r-- | drivers/misc/uid_sys_stats.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c index 4988e323cf02..204b23484266 100644 --- a/drivers/misc/uid_sys_stats.c +++ b/drivers/misc/uid_sys_stats.c @@ -21,6 +21,7 @@ #include <linux/list.h> #include <linux/proc_fs.h> #include <linux/profile.h> +#include <linux/rtmutex.h> #include <linux/sched.h> #include <linux/seq_file.h> #include <linux/slab.h> @@ -29,7 +30,7 @@ #define UID_HASH_BITS 10 DECLARE_HASHTABLE(hash_table, UID_HASH_BITS); -static DEFINE_MUTEX(uid_lock); +static DEFINE_RT_MUTEX(uid_lock); static struct proc_dir_entry *cpu_parent; static struct proc_dir_entry *io_parent; static struct proc_dir_entry *proc_parent; @@ -98,7 +99,7 @@ static int uid_cputime_show(struct seq_file *m, void *v) cputime_t stime; unsigned long bkt; - mutex_lock(&uid_lock); + rt_mutex_lock(&uid_lock); hash_for_each(hash_table, bkt, uid_entry, hash) { uid_entry->active_stime = 0; @@ -111,7 +112,7 @@ static int uid_cputime_show(struct seq_file *m, void *v) current_user_ns(), task_uid(task))); if (!uid_entry) { read_unlock(&tasklist_lock); - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); pr_err("%s: failed to find the uid_entry for uid %d\n", __func__, from_kuid_munged(current_user_ns(), task_uid(task))); @@ -135,7 +136,7 @@ static int uid_cputime_show(struct seq_file *m, void *v) cputime_to_jiffies(total_stime)) * USEC_PER_MSEC); } - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return 0; } @@ -182,7 +183,7 @@ static ssize_t uid_remove_write(struct file *file, kstrtol(end_uid, 10, &uid_end) != 0) { return -EINVAL; } - mutex_lock(&uid_lock); + rt_mutex_lock(&uid_lock); for (; uid_start <= uid_end; uid_start++) { hash_for_each_possible_safe(hash_table, uid_entry, tmp, @@ -194,7 +195,7 @@ static ssize_t uid_remove_write(struct file *file, } } - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return count; } @@ -243,7 +244,7 @@ static void update_io_stats_locked(void) struct io_stats *io_bucket, *io_curr, *io_last; unsigned long bkt; - BUG_ON(!mutex_is_locked(&uid_lock)); + BUG_ON(!rt_mutex_is_locked(&uid_lock)); hash_for_each(hash_table, bkt, uid_entry, hash) memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, @@ -285,7 +286,7 @@ static int uid_io_show(struct seq_file *m, void *v) struct uid_entry *uid_entry; unsigned long bkt; - mutex_lock(&uid_lock); + rt_mutex_lock(&uid_lock); update_io_stats_locked(); @@ -304,7 +305,7 @@ static int uid_io_show(struct seq_file *m, void *v) uid_entry->io[UID_STATE_BACKGROUND].fsync); } - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return 0; } @@ -349,16 +350,16 @@ static ssize_t uid_procstat_write(struct file *file, if (state != UID_STATE_BACKGROUND && state != UID_STATE_FOREGROUND) return -EINVAL; - mutex_lock(&uid_lock); + rt_mutex_lock(&uid_lock); uid_entry = find_or_register_uid(uid); if (!uid_entry) { - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return -EINVAL; } if (uid_entry->state == state) { - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return count; } @@ -366,7 +367,7 @@ static ssize_t uid_procstat_write(struct file *file, uid_entry->state = state; - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return count; } @@ -388,7 +389,7 @@ static int process_notifier(struct notifier_block *self, if (!task) return NOTIFY_OK; - mutex_lock(&uid_lock); + rt_mutex_lock(&uid_lock); uid = from_kuid_munged(current_user_ns(), task_uid(task)); uid_entry = find_or_register_uid(uid); if (!uid_entry) { @@ -404,7 +405,7 @@ static int process_notifier(struct notifier_block *self, clean_uid_io_last_stats(uid_entry, task); exit: - mutex_unlock(&uid_lock); + rt_mutex_unlock(&uid_lock); return NOTIFY_OK; } |
