Skip to content

Commit daa694e

Browse files
oleg-nesterovakpm00
authored andcommitted
getrusage: move thread_group_cputime_adjusted() outside of lock_task_sighand()
Patch series "getrusage: use sig->stats_lock", v2. This patch (of 2): thread_group_cputime() does its own locking, we can safely shift thread_group_cputime_adjusted() which does another for_each_thread loop outside of ->siglock protected section. This is also preparation for the next patch which changes getrusage() to use stats_lock instead of siglock, thread_group_cputime() takes the same lock. With the current implementation recursive read_seqbegin_or_lock() is fine, thread_group_cputime() can't enter the slow mode if the caller holds stats_lock, yet this looks more safe and better performance-wise. Link: https://lkml.kernel.org/r/20240122155023.GA26169@redhat.com Link: https://lkml.kernel.org/r/20240122155050.GA26205@redhat.com Signed-off-by: Oleg Nesterov <oleg@redhat.com> Reported-by: Dylan Hatch <dylanbhatch@google.com> Tested-by: Dylan Hatch <dylanbhatch@google.com> Cc: Eric W. Biederman <ebiederm@xmission.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
1 parent e656c7a commit daa694e

File tree

1 file changed

+19
-15
lines changed

1 file changed

+19
-15
lines changed

kernel/sys.c

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,17 +1785,19 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
17851785
struct task_struct *t;
17861786
unsigned long flags;
17871787
u64 tgutime, tgstime, utime, stime;
1788-
unsigned long maxrss = 0;
1788+
unsigned long maxrss;
1789+
struct mm_struct *mm;
17891790
struct signal_struct *sig = p->signal;
17901791

1791-
memset((char *)r, 0, sizeof (*r));
1792+
memset(r, 0, sizeof(*r));
17921793
utime = stime = 0;
1794+
maxrss = 0;
17931795

17941796
if (who == RUSAGE_THREAD) {
17951797
task_cputime_adjusted(current, &utime, &stime);
17961798
accumulate_thread_rusage(p, r);
17971799
maxrss = sig->maxrss;
1798-
goto out;
1800+
goto out_thread;
17991801
}
18001802

18011803
if (!lock_task_sighand(p, &flags))
@@ -1819,9 +1821,6 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
18191821
fallthrough;
18201822

18211823
case RUSAGE_SELF:
1822-
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
1823-
utime += tgutime;
1824-
stime += tgstime;
18251824
r->ru_nvcsw += sig->nvcsw;
18261825
r->ru_nivcsw += sig->nivcsw;
18271826
r->ru_minflt += sig->min_flt;
@@ -1839,19 +1838,24 @@ void getrusage(struct task_struct *p, int who, struct rusage *r)
18391838
}
18401839
unlock_task_sighand(p, &flags);
18411840

1842-
out:
1843-
r->ru_utime = ns_to_kernel_old_timeval(utime);
1844-
r->ru_stime = ns_to_kernel_old_timeval(stime);
1841+
if (who == RUSAGE_CHILDREN)
1842+
goto out_children;
18451843

1846-
if (who != RUSAGE_CHILDREN) {
1847-
struct mm_struct *mm = get_task_mm(p);
1844+
thread_group_cputime_adjusted(p, &tgutime, &tgstime);
1845+
utime += tgutime;
1846+
stime += tgstime;
18481847

1849-
if (mm) {
1850-
setmax_mm_hiwater_rss(&maxrss, mm);
1851-
mmput(mm);
1852-
}
1848+
out_thread:
1849+
mm = get_task_mm(p);
1850+
if (mm) {
1851+
setmax_mm_hiwater_rss(&maxrss, mm);
1852+
mmput(mm);
18531853
}
1854+
1855+
out_children:
18541856
r->ru_maxrss = maxrss * (PAGE_SIZE / 1024); /* convert pages to KBs */
1857+
r->ru_utime = ns_to_kernel_old_timeval(utime);
1858+
r->ru_stime = ns_to_kernel_old_timeval(stime);
18551859
}
18561860

18571861
SYSCALL_DEFINE2(getrusage, int, who, struct rusage __user *, ru)

0 commit comments

Comments
 (0)