summaryrefslogtreecommitdiff
path: root/drivers/misc
diff options
context:
space:
mode:
authorWei Wang <wvw@google.com>2017-03-13 12:22:21 -0700
committerJin Qian <jinqian@google.com>2017-03-14 23:53:27 +0000
commit75a7736c2ad9b019ac131f124f53f3c194bf3c95 (patch)
tree56f1bb6541dec244bcdab124546aff84d59df904 /drivers/misc
parent4b20ed9406bc88023353f04e07788ed4c3846aa2 (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.c31
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;
}