ANDROID: uid_sys_stat: instead update_io_stats_uid_locked to update_io_stats_uid

Update_io_stats_uid_locked would take a long lock-time of uid_lock due to
call do_each_thread to compute uid_entry->io, which would cause to lock
competition sometime.

Using uid_entry_tmp to get the result of update_io_stats_uid, so that we
can unlock_uid during update_io_stats_uid, in order to avoid the
unnecessary lock-time of uid_lock.

Bug: 278138377

Signed-off-by: Peifeng Li <lipeifeng@oppo.com>
(cherry picked from https://android-review.googlesource.com/q/commit:c1fa53f3cf85c0a1c23f0e0a944986b4aa049073)
Merged-In: I5be62105e57e2a896a95d906e3c14e17c7f8077d
Change-Id: I5be62105e57e2a896a95d906e3c14e17c7f8077d
This commit is contained in:
Peifeng Li 2023-09-19 17:35:11 +08:00 committed by Neill Kapron
parent 97f2f8a065
commit c6724bfeda

View File

@ -558,7 +558,11 @@ static void update_io_stats_all(void)
}
}
#ifndef CONFIG_UID_SYS_STATS_DEBUG
static void update_io_stats_uid(struct uid_entry *uid_entry)
#else
static void update_io_stats_uid_locked(struct uid_entry *uid_entry)
#endif
{
struct task_struct *task, *temp;
struct user_namespace *user_ns = current_user_ns();
@ -639,6 +643,9 @@ static ssize_t uid_procstat_write(struct file *file,
uid_t uid;
int argc, state;
char input[128];
#ifndef CONFIG_UID_SYS_STATS_DEBUG
struct uid_entry uid_entry_tmp;
#endif
if (count >= sizeof(input))
return -EINVAL;
@ -667,11 +674,39 @@ static ssize_t uid_procstat_write(struct file *file,
return count;
}
#ifndef CONFIG_UID_SYS_STATS_DEBUG
/*
* Update_io_stats_uid_locked would take a long lock-time of uid_lock
* due to call do_each_thread to compute uid_entry->io, which would
* cause to lock competition sometime.
*
* Using uid_entry_tmp to get the result of Update_io_stats_uid,
* so that we can unlock_uid during update_io_stats_uid, in order
* to avoid the unnecessary lock-time of uid_lock.
*/
uid_entry_tmp.uid = uid_entry->uid;
memcpy(uid_entry_tmp.io, uid_entry->io,
sizeof(struct io_stats) * UID_STATE_SIZE);
unlock_uid(uid);
update_io_stats_uid(&uid_entry_tmp);
lock_uid(uid);
hlist_for_each_entry(uid_entry, &hash_table[hash_min(uid, HASH_BITS(hash_table))], hash) {
if (uid_entry->uid == uid_entry_tmp.uid) {
memcpy(uid_entry->io, uid_entry_tmp.io,
sizeof(struct io_stats) * UID_STATE_SIZE);
uid_entry->state = state;
break;
}
}
unlock_uid(uid);
#else
update_io_stats_uid_locked(uid_entry);
uid_entry->state = state;
unlock_uid(uid);
#endif
return count;
}