• L
    fs: fix files.usage bug when move tasks · 0a960e73
    Lu Jialin 提交于
    hulk inclusion
    category: bugfix
    bugzilla: 50779
    CVE: NA
    
    --------
    
    If parent cgroup files.limit is 0, fail to move a task into child
    cgroup. When kill the task, the files.usage of parent cgroup and child
    cgroup is abnormal.
    
    /sys/fs/cgroup/parent # ls
    cgroup.clone_children  files.limit            tasks
    cgroup.procs           files.usage
    child                  notify_on_release
    /sys/fs/cgroup/parent # echo 0 >files.limit
    /sys/fs/cgroup/parent # cd child
    /sys/fs/cgroup/parent/child # ls
    cgroup.clone_children  files.limit            notify_on_release
    cgroup.procs           files.usage            tasks
    /sys/fs/cgroup/parent/child # echo 156 >tasks
    [  879.564728] Open files limit overcommited
    /sys/fs/cgroup/parent/child # kill -9 156
    /sys/fs/cgroup/parent/child # [  886.363690] WARNING: CPU: 0 PID: 156 at mm/page_counter.c:62 page_counter_cancel+0x26/0x30
    [  886.364093] Modules linked in:
    [  886.364093] CPU: 0 PID: 156 Comm: top Not tainted 4.18.0+ #1
    [  886.364093] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org 04/01/2014
    [  886.365350] RIP: 0010:page_counter_cancel+0x26/0x30
    [  886.365350] Code: 0f 1f 40 00 66 66 66 66 90 48 89 f0 53 48 f7 d8 f0 48 0f c1 07 48 29 f0 48 89 c3 48 89 c6 e8 61 ff ff ff 48 85 d5
    [  886.365350] RSP: 0018:ffffb754006b7d00 EFLAGS: 00000286
    [  886.365350] RAX: 0000000000000000 RBX: ffffffffffffffff RCX: 0000000000000001
    [  886.365350] RDX: 0000000000000000 RSI: ffffffffffffffff RDI: ffff9ca61888b930
    [  886.365350] RBP: 0000000000000001 R08: 00000000000295c0 R09: ffffffff820597aa
    [  886.365350] R10: ffffffffffffffff R11: ffffd78601823508 R12: 0000000000000000
    [  886.365350] R13: ffff9ca6181c0628 R14: 0000000000000000 R15: ffff9ca663e9d000
    [  886.365350] FS:  0000000000000000(0000) GS:ffff9ca661e00000(0000) knlGS:0000000000000000
    [  886.365350] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
    [  886.365350] CR2: 0000000000867fb8 CR3: 0000000017a0a000 CR4: 00000000000006f0
    [  886.365350] Call Trace:
    [  886.369392]  page_counter_uncharge+0x1d/0x30
    [  886.369392]  put_files_struct+0x7c/0xe0
    [  886.369392]  do_exit+0x2c7/0xb90
    [  886.369392]  ? __schedule+0x2a1/0x900
    [  886.369392]  do_group_exit+0x3a/0xa0
    [  886.369392]  get_signal+0x15e/0x870
    [  886.369392]  do_signal+0x36/0x610
    [  886.369392]  ? do_vfs_ioctl+0xa4/0x640
    [  886.369392]  ? do_vfs_ioctl+0xa4/0x640
    [  886.369392]  ? dput+0x29/0x110
    [  886.369392]  exit_to_usermode_loop+0x71/0xe0
    [  886.369392]  do_syscall_64+0x181/0x1b0
    [  886.369392]  entry_SYSCALL_64_after_hwframe+0x65/0xca
    [  886.369392] RIP: 0033:0x4b9b5a
    [  886.369392] Code: Bad RIP value.
    [  886.369392] RSP: 002b:00007ffe27221968 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
    [  886.373373] RAX: fffffffffffffe00 RBX: 0000000000000001 RCX: 00000000004b9b5a
    [  886.373373] RDX: 00007ffe27221930 RSI: 0000000000005402 RDI: 0000000000000000
    [  886.373373] RBP: 0000000000000135 R08: 00007ffe272219a4 R09: 0000000000000010
    [  886.373373] R10: 0000000000000000 R11: 0000000000000206 R12: 0000000000000000
    [  886.373373] R13: 0000000000000005 R14: 0000000000000135 R15: 0000000000000000
    [  886.373373] ---[ end trace 56c4971a753a98c5 ]---
    
    [1]+  Killed                     top
    /sys/fs/cgroup/parent/child # ls
    cgroup.clone_children  files.limit            notify_on_release
    cgroup.procs           files.usage            tasks
    /sys/fs/cgroup/parent/child # cat files.usage
    18446744073709551613
    /sys/fs/cgroup/parent/child # cd ..
    /sys/fs/cgroup/parent # ls
    cgroup.clone_children  files.limit            tasks
    cgroup.procs           files.usage
    child                  notify_on_release
    /sys/fs/cgroup/parent # cat files.usage
    18446744073709551613
    
    The reason is when fail to move a task into child cgroup,the files.usage
    of child cgroup and its parent cgroup are the same as before. The struct
    files_cgroup points to the dst_css. Therefore, when kill the task, the
    page_counter_uncharge() will subtract the files.usage of child cgroup and
    its parent cgroup again. The files.usage will be abnormal.
    
    If we just change the struct files_cgroup pointers when charge success in
    files_cgroup_attach, problems will occur in some extreme scenario.
    1)If we add num_files into original page_counter when fail to charge the
    file resource into new cgroup, the files.usage will be larger than
    files.limit of the original cgroup when new task moves into the original
    cgroup at the same time.
    2)If we subtract num_files into original page_counter when success to
    charge the file resource into new cgroup, when the parent files.limit
    equals to the files.usage and there are two child cgroups of the parent,
    it will be failed to move the task from one child cgroup into another
    child cgroup.
    
    The patch implements files_cgroup_attach() into files_cgroup_can_attach()
    and delete files_cgroup_attach(). This will make move file related resource
    into new cgroup before move task. When try_charge is failed, task and its
    file resource will be in the original cgroup.The above problems will be
    solved.
    Signed-off-by: NLu Jialin <lujialin4@huawei.com>
    Reviewed-by: NHou Tao <houtao1@huawei.com>
    Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
    Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
    Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
    0a960e73
filescontrol.c 7.5 KB