ANDROID: uid_sys_stats: avoid double accounting of dying threads When a thread is being killed process_notifier() is called to record the final accounting of the thread. But after that uid_cputime_show() and add_uid_io_stats() can be called before the dying thread is removed from the parent's thread_group resulting in double accounting. This can cause the user and system time for a given UID to move backwards in /proc/uid_cputime/show_uid_stat. That gives negative delta times in KernelCpuUidUserSysTimeReader.readDeltaImpl() and it logs an error: "Negative user/sys time delta for UID=..." One consequence of which was incorrectly calculated power consumptions in BatteryStats. With this change we avoid the double accounting by ignoring the thread if it has the PF_EXITING flag set. Bug: 144366911 Change-Id: I6b929e8f558cd81ce1c00481c8b550d24877aa2c Signed-off-by: Rickard Möller <rickard.moller@sony.com>
diff --git a/drivers/misc/uid_sys_stats.c b/drivers/misc/uid_sys_stats.c index 3954e34..d04faf3 100644 --- a/drivers/misc/uid_sys_stats.c +++ b/drivers/misc/uid_sys_stats.c
@@ -358,9 +358,12 @@ static int uid_cputime_show(struct seq_file *m, void *v) __func__, uid); return -ENOMEM; } - task_cputime_adjusted(task, &utime, &stime); - uid_entry->active_utime += utime; - uid_entry->active_stime += stime; + /* avoid double accounting of dying threads */ + if (!(task->flags & PF_EXITING)) { + task_cputime_adjusted(task, &utime, &stime); + uid_entry->active_utime += utime; + uid_entry->active_stime += stime; + } } while_each_thread(temp, task); rcu_read_unlock(); @@ -453,6 +456,10 @@ static void add_uid_io_stats(struct uid_entry *uid_entry, { struct io_stats *io_slot = &uid_entry->io[slot]; + /* avoid double accounting of dying threads */ + if (slot != UID_STATE_DEAD_TASKS && (task->flags & PF_EXITING)) + return; + io_slot->read_bytes += task->ioac.read_bytes; io_slot->write_bytes += compute_write_bytes(task); io_slot->rchar += task->ioac.rchar;