ANDROID: uid_sys_stat: fix data-error of cputime and io
'commit b6115e14 ("ANDROID: uid_sys_stat: split the global lock uid_lock to the fine-grained locks for each hlist in hash_table.")' The above patch split the global lock to per-uid lock to reduce lock competition. But result in data-error from uid_cputime_show and uid_io_show in some cases. E.g, if thread1 and thread2 read /proc/uid_cputime/show_uid_stat at the same time, thread2 maybe operate in partA and zero active_stime and active_utime of uid_entry when thread1 is between partB and partC, which would cause thread1 show the error data. static int uid_cputime_show(struct seq_file *m, void *v) { ... /*partA*/ for (bkt = 0, uid_entry = NULL; uid_entry == NULL && bkt < HASH_SIZE(hash_table); bkt++) { lock_uid_by_bkt(bkt); hlist_for_each_entry(uid_entry, &hash_table[bkt], hash) { uid_entry->active_stime = 0; uid_entry->active_utime = 0; } unlock_uid_by_bkt(bkt); } rcu_read_lock(); /* partB */ do_each_thread(temp, task) { ... lock_uid(uid); if (!(task->flags & PF_EXITING)) { task_cputime_adjusted(task, &utime, &stime); uid_entry->active_utime += utime; uid_entry->active_stime += stime; } unlock_uid(uid); } while_each_thread(temp, task); rcu_read_unlock(); for (bkt = 0, uid_entry = NULL; uid_entry == NULL && bkt < HASH_SIZE(hash_table); bkt++) { lock_uid_by_bkt(bkt); hlist_for_each_entry(uid_entry, &hash_table[bkt], hash) { u64 total_utime = uid_entry->utime + uid_entry->active_utime; u64 total_stime = uid_entry->stime + uid_entry->active_stime; /* partC */ seq_printf(m, "%d: %llu %llu\n", uid_entry->uid, ktime_to_us(total_utime), ktime_to_us(total_stime)); } unlock_uid_by_bkt(bkt); } The patch ensures that the calculation and seq_printf of each uid_entry is within the uid_lock range, in order to accurate data. Bug: 278138377 Change-Id: Iaa2ccd95c4b4b333f04b2ba18d7699d94017394e Signed-off-by:lipeifeng <lipeifeng@oppo.com> (cherry picked from commit ea35d2bd)
Loading
Please sign in to comment