How to accout max_rss precisely

Heran Yang herany1999 at gmail.com
Mon Jun 17 01:29:59 EDT 2024


Hi!

I do this test leverage systemd-run. The command likes:

systemd-run --user --unit test --wait ./a

Though there are some accounting bugs in systemd-run (check PR #33258), the
accounting value is aligned
with cgroups. The cgroups creating step is like this:

1. Setup a cgroup (now it has no process in it)
2. Write the pid of this process to cgroup and execve the command
immediately afterward

I guess there is no over-measuring or under-measuring during this process,
but I'm not sure.


Mulyadi Santosa <mulyadi.santosa at gmail.com> 于2024年6月16日周日 21:10写道:

> Hi
>
> I think the key here is : when exactly cgroup is created for your program?
>
>
>
> On Sun, Jun 16, 2024, 15:53 Heran Yang <herany1999 at gmail.com> wrote:
>
>> Hi, and thanks for your reply. I totally forgot to take the dynamic
>> loader into consideration, which is my bad.
>>
>> But another problem is that the peak value cannot align with the max_rss
>> getting from `getrusage` function, which
>> is ~1000KiB. I guess that it has some connection with max_rss inheriting,
>> but I'm not sure about that. Do you have
>> any opinion about it?
>>
>> 杨贺然 <herany1999 at gmail.com> 于2024年6月4日周二 21:37写道:
>>
>>> Hi, and thanks for your reply. I totally forgot to take the dynamic
>>> loader into consideration, which is my bad.
>>>
>>> But another problem is that the peak value cannot align with the max_rss
>>> getting from `getrusage` function, which
>>> is ~1000KiB. I guess that it has some connection with max_rss
>>> inheriting, but I'm not sure about that. Do you have
>>> any opinion about it?
>>>
>>> Valdis Klētnieks <valdis.kletnieks at vt.edu> 于2024年6月4日周二 01:44写道:
>>>
>>>> On Sat, 01 Jun 2024 15:01:32 +0800, 杨贺然 said:
>>>>
>>>> > // a.c
>>>> > int main() {}
>>>> >
>>>> > It shows that `memory.peak` of this program is ~500KiB, which does
>>>> not make
>>>> > sense to me.
>>>>
>>>> Makes sense to me...
>>>>
>>>> [~] cat > testnull.c
>>>>  int main() {}
>>>> [~] gcc testnull.c
>>>> [~] ldd a.out
>>>>         linux-vdso.so.1 (0x00007efc6a650000)
>>>>         libc.so.6 => /lib64/libc.so.6 (0x00007efc6a43d000)
>>>>         /lib64/ld-linux-x86-64.so.2 (0x00007efc6a652000)
>>>> [~] objdump -d a.out
>>>>
>>>> a.out:     file format elf64-x86-64
>>>>
>>>>
>>>> Disassembly of section .init:
>>>>
>>>> 0000000000401000 <_init>:
>>>>   401000:       f3 0f 1e fa             endbr64
>>>>   401004:       48 83 ec 08             sub    $0x8,%rsp
>>>>   401008:       48 8b 05 d1 2f 00 00    mov    0x2fd1(%rip),%rax
>>>> # 403fe0 <__gmon_start__ at Base>
>>>>   40100f:       48 85 c0                test   %rax,%rax
>>>>   401012:       74 02                   je     401016 <_init+0x16>
>>>>   401014:       ff d0                   call   *%rax
>>>>   401016:       48 83 c4 08             add    $0x8,%rsp
>>>>   40101a:       c3                      ret
>>>>
>>>> Disassembly of section .text:
>>>>
>>>> 0000000000401020 <_start>:
>>>>   401020:       f3 0f 1e fa             endbr64
>>>>   401024:       31 ed                   xor    %ebp,%ebp
>>>>   401026:       49 89 d1                mov    %rdx,%r9
>>>>   401029:       5e                      pop    %rsi
>>>>   40102a:       48 89 e2                mov    %rsp,%rdx
>>>>   40102d:       48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
>>>>   401031:       50                      push   %rax
>>>>   401032:       54                      push   %rsp
>>>>   401033:       45 31 c0                xor    %r8d,%r8d
>>>>   401036:       31 c9                   xor    %ecx,%ecx
>>>>   401038:       48 c7 c7 06 11 40 00    mov    $0x401106,%rdi
>>>>   40103f:       ff 15 93 2f 00 00       call   *0x2f93(%rip)        #
>>>> 403fd8 <__libc_start_main at GLIBC_2.34>
>>>>   401045:       f4                      hlt
>>>>   401046:       66 2e 0f 1f 84 00 00    cs nopw 0x0(%rax,%rax,1)
>>>>   40104d:       00 00 00
>>>> (.....)
>>>>
>>>> Basically, its not *really* a totally null program.  You've got the
>>>> dynamic
>>>> loader ld-linux running first, which then *doesn't* run main()
>>>> directly, but
>>>> rather invokes _start, which needs to happen so that __libc_start_main
>>>> can get
>>>> called and initialize stuff lie stdio, malloc, and other such t hings,
>>>> before
>>>> it finally calls main().
>>>>
>>>> Personally, I'm surprised that ld-linux and glibc initialization can
>>>> finish
>>>> without going over 500k - even more so if shared library text pages are
>>>> included in memory.peak.  Somebody  else can wade into that mess, I
>>>> admit
>>>> having been around since kernel 2.5.47 or so, and I never did
>>>> understand the
>>>> memory accounting for shared text pages....
>>>>
>>>> _______________________________________________
>> Kernelnewbies mailing list
>> Kernelnewbies at kernelnewbies.org
>> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> https://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20240617/17914cb3/attachment.html>


More information about the Kernelnewbies mailing list