From d52f0e3fa7c017957630212b465215a1cee2a3fc Mon Sep 17 00:00:00 2001 From: Jin Qian Date: Mon, 22 May 2017 12:08:06 -0700 Subject: [PATCH] uid_sys_stats: defer io stats calulation for dead tasks Store sum of dead task io stats in uid_entry and defer uid io calulation until next uid proc stat change or dumpsys. Bug: 37754877 Change-Id: I970f010a4c841c5ca26d0efc7e027414c3c952e0 Signed-off-by: Jin Qian Signed-off-by: Francisco Franco --- drivers/misc/uid_sys_stats.c | 111 +++++++++++++---------------------- 1 file changed, 42 insertions(+), 69 deletions(-) diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c index a22b3bc4f43..d677b37e480 100644 --- a/drivers/misc/uid_sys_stats.c +++ b/drivers/misc/uid_sys_stats.c @@ -49,7 +49,8 @@ struct io_stats { #define UID_STATE_TOTAL_CURR 2 #define UID_STATE_TOTAL_LAST 3 -#define UID_STATE_SIZE 4 +#define UID_STATE_DEAD_TASKS 4 +#define UID_STATE_SIZE 5 struct uid_entry { uid_t uid; @@ -221,41 +222,48 @@ static u64 compute_write_bytes(struct task_struct *task) return task->ioac.write_bytes - task->ioac.cancelled_write_bytes; } -static void add_uid_io_curr_stats(struct uid_entry *uid_entry, - struct task_struct *task) +static void add_uid_io_stats(struct uid_entry *uid_entry, + struct task_struct *task, int slot) { - struct io_stats *io_curr = &uid_entry->io[UID_STATE_TOTAL_CURR]; + struct io_stats *io_slot = &uid_entry->io[slot]; - io_curr->read_bytes += task->ioac.read_bytes; - io_curr->write_bytes += compute_write_bytes(task); - io_curr->rchar += task->ioac.rchar; - io_curr->wchar += task->ioac.wchar; - io_curr->fsync += task->ioac.syscfs; + io_slot->read_bytes += task->ioac.read_bytes; + io_slot->write_bytes += compute_write_bytes(task); + io_slot->rchar += task->ioac.rchar; + io_slot->wchar += task->ioac.wchar; + io_slot->fsync += task->ioac.syscfs; } -static void clean_uid_io_last_stats(struct uid_entry *uid_entry, - struct task_struct *task) +static void compute_uid_io_bucket_stats(struct io_stats *io_bucket, + struct io_stats *io_curr, + struct io_stats *io_last, + struct io_stats *io_dead) { - struct io_stats *io_last = &uid_entry->io[UID_STATE_TOTAL_LAST]; + io_bucket->read_bytes += io_curr->read_bytes + io_dead->read_bytes - + io_last->read_bytes; + io_bucket->write_bytes += io_curr->write_bytes + io_dead->write_bytes - + io_last->write_bytes; + io_bucket->rchar += io_curr->rchar + io_dead->rchar - io_last->rchar; + io_bucket->wchar += io_curr->wchar + io_dead->wchar - io_last->wchar; + io_bucket->fsync += io_curr->fsync + io_dead->fsync - io_last->fsync; - io_last->read_bytes -= task->ioac.read_bytes; - io_last->write_bytes -= compute_write_bytes(task); - io_last->rchar -= task->ioac.rchar; - io_last->wchar -= task->ioac.wchar; - io_last->fsync -= task->ioac.syscfs; + io_last->read_bytes = io_curr->read_bytes; + io_last->write_bytes = io_curr->write_bytes; + io_last->rchar = io_curr->rchar; + io_last->wchar = io_curr->wchar; + io_last->fsync = io_curr->fsync; + + memset(io_dead, 0, sizeof(struct io_stats)); } static void update_io_stats_all_locked(void) { struct uid_entry *uid_entry; struct task_struct *task, *temp; - struct io_stats *io_bucket, *io_curr, *io_last; struct user_namespace *user_ns = current_user_ns(); unsigned long bkt; uid_t uid; - 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, sizeof(struct io_stats)); @@ -266,72 +274,38 @@ static void update_io_stats_all_locked(void) uid_entry = find_or_register_uid(uid); if (!uid_entry) continue; - add_uid_io_curr_stats(uid_entry, task); + add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); } while_each_thread(temp, task); rcu_read_unlock(); hash_for_each(hash_table, bkt, uid_entry, hash) { - io_bucket = &uid_entry->io[uid_entry->state]; - io_curr = &uid_entry->io[UID_STATE_TOTAL_CURR]; - io_last = &uid_entry->io[UID_STATE_TOTAL_LAST]; - - io_bucket->read_bytes += - io_curr->read_bytes - io_last->read_bytes; - io_bucket->write_bytes += - io_curr->write_bytes - io_last->write_bytes; - io_bucket->rchar += io_curr->rchar - io_last->rchar; - io_bucket->wchar += io_curr->wchar - io_last->wchar; - io_bucket->fsync += io_curr->fsync - io_last->fsync; - - io_last->read_bytes = io_curr->read_bytes; - io_last->write_bytes = io_curr->write_bytes; - io_last->rchar = io_curr->rchar; - io_last->wchar = io_curr->wchar; - io_last->fsync = io_curr->fsync; + compute_uid_io_bucket_stats(&uid_entry->io[uid_entry->state], + &uid_entry->io[UID_STATE_TOTAL_CURR], + &uid_entry->io[UID_STATE_TOTAL_LAST], + &uid_entry->io[UID_STATE_DEAD_TASKS]); } } -static void update_io_stats_uid_locked(uid_t target_uid) +static void update_io_stats_uid_locked(struct uid_entry *uid_entry) { - struct uid_entry *uid_entry; struct task_struct *task, *temp; - struct io_stats *io_bucket, *io_curr, *io_last; struct user_namespace *user_ns = current_user_ns(); - BUG_ON(!rt_mutex_is_locked(&uid_lock)); - - uid_entry = find_or_register_uid(target_uid); - if (!uid_entry) - return; - memset(&uid_entry->io[UID_STATE_TOTAL_CURR], 0, sizeof(struct io_stats)); rcu_read_lock(); do_each_thread(temp, task) { - if (from_kuid_munged(user_ns, task_uid(task)) != target_uid) + if (from_kuid_munged(user_ns, task_uid(task)) != uid_entry->uid) continue; - add_uid_io_curr_stats(uid_entry, task); + add_uid_io_stats(uid_entry, task, UID_STATE_TOTAL_CURR); } while_each_thread(temp, task); rcu_read_unlock(); - io_bucket = &uid_entry->io[uid_entry->state]; - io_curr = &uid_entry->io[UID_STATE_TOTAL_CURR]; - io_last = &uid_entry->io[UID_STATE_TOTAL_LAST]; - - io_bucket->read_bytes += - io_curr->read_bytes - io_last->read_bytes; - io_bucket->write_bytes += - io_curr->write_bytes - io_last->write_bytes; - io_bucket->rchar += io_curr->rchar - io_last->rchar; - io_bucket->wchar += io_curr->wchar - io_last->wchar; - io_bucket->fsync += io_curr->fsync - io_last->fsync; - - io_last->read_bytes = io_curr->read_bytes; - io_last->write_bytes = io_curr->write_bytes; - io_last->rchar = io_curr->rchar; - io_last->wchar = io_curr->wchar; - io_last->fsync = io_curr->fsync; + compute_uid_io_bucket_stats(&uid_entry->io[uid_entry->state], + &uid_entry->io[UID_STATE_TOTAL_CURR], + &uid_entry->io[UID_STATE_TOTAL_LAST], + &uid_entry->io[UID_STATE_DEAD_TASKS]); } static int uid_io_show(struct seq_file *m, void *v) @@ -416,7 +390,7 @@ static ssize_t uid_procstat_write(struct file *file, return count; } - update_io_stats_uid_locked(uid); + update_io_stats_uid_locked(uid_entry); uid_entry->state = state; @@ -456,8 +430,7 @@ static int process_notifier(struct notifier_block *self, uid_entry->power += task->cpu_power; task->cpu_power = ULLONG_MAX; - update_io_stats_uid_locked(uid); - clean_uid_io_last_stats(uid_entry, task); + add_uid_io_stats(uid_entry, task, UID_STATE_DEAD_TASKS); exit: rt_mutex_unlock(&uid_lock); -- 2.20.1