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>
This commit is contained in:
Rickard Möller
2019-11-01 14:20:46 +01:00
committed by Todd Kjos
parent 1e3594cbb8
commit 953d6c5a95

View File

@@ -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;