본문 바로가기

리눅스 커널의 구조와 원리/14. 메모리 관리

[mm] OOM Killer log and kernel code review

log 

[  747.358161] 81920 pages cma reserved
[  747.358164] Tasks state (memory values in pages):
[  747.358167] [  pid  ]   uid  tgid total_vm      rss pgtables_bytes swapents oom_score_adj name
[  747.358186] [    142]     0   142    12270       43    94208      236          -250 systemd-journal
...
[  747.358591] [   1468]     0  1468     1740      131    45056        0             0 bash
[  747.358597] [   1502]  1000  1502    39991       99    65536        0             0 gvfsd-metadata
[  747.358607] [   1604]     0  1604  2570484   224052 20631552     1271             0 invoke_memleak
[  747.358612] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/,task=invoke_memleak,pid=1604,uid=0
[  747.358652] Out of memory: Killed process 1604 (invoke_memleak) total-vm:10281936kB, anon-rss:896204kB, file-rss:4kB, shmem-rss:0kB, UID:0 pgtables:20148kB oom_score_adj:0

__oom_kill_process() function

https://elixir.bootlin.com/linux/v5.15.30/source/mm/oom_kill.c
static void __oom_kill_process(struct task_struct *victim, const char *message)
{
struct task_struct *p;
..
pr_err("%s: Killed process %d (%s) total-vm:%lukB, anon-rss:%lukB, file-rss:%lukB, shmem-rss:%lukB, UID:%u pgtables:%lukB oom_score_adj:%hd\n",
message, task_pid_nr(victim), victim->comm, K(mm->total_vm),
K(get_mm_counter(mm, MM_ANONPAGES)),
K(get_mm_counter(mm, MM_FILEPAGES)),
K(get_mm_counter(mm, MM_SHMEMPAGES)),
from_kuid(&init_user_ns, task_uid(victim)),
mm_pgtables_bytes(mm) >> 10, victim->signal->oom_score_adj);
task_unlock(victim);

(where)
#define K(x) ((x) << (PAGE_SHIFT-10))

Access 'K(mm->total_vm)' using TRACE32

v.v %t  (struct task_struct*)0xffffff8040238000

  (struct task_struct *) (struct task_struct*)0xffffff8040238000 = 0xFFFFFF8040238000 -> (
    (struct thread_info) thread_info = ((long unsigned int) flags = 0, (u64) preempt_count = 4294967
    (unsigned int) __state = 1,
    (void *) stack = 0xFFFFFFC008028000,
...
    (struct mm_struct *) mm = 0xFFFFFF8041A08000 -> (
      (struct vm_area_struct *) mmap = 0xFFFFFF8040F2D0B8,
      (struct rb_root) mm_rb = ((struct rb_node *) rb_node = 0xFFFFFF8040F2DDC8),
      (u64) vmacache_seqnum = 55,
      (long unsigned int (*)()) get_unmapped_area = 0xFFFFFFD1744A5194,
      (long unsigned int) mmap_base = 548384292864,
      (long unsigned int) mmap_legacy_base = 0,
      (long unsigned int) task_size = 549755813888,
      (long unsigned int) highest_vm_end = 548951498752,
      (pgd_t *) pgd = 0xFFFFFF8040F2C000,
      (atomic_t) membarrier_state = ((int) counter = 0),
      (atomic_t) mm_users = ((int) counter = 1),
      (atomic_t) mm_count = ((int) counter = 1),
      (atomic_long_t) pgtables_bytes = ((s64) counter = 86016),
      (int) map_count = 130,
      (spinlock_t) page_table_lock = ((struct raw_spinlock) rlock = ((arch_spinlock_t) raw_lock = ((
      (struct rw_semaphore) mmap_lock = ((atomic_long_t) count = ((s64) counter = 0), (atomic_long_t
      (struct list_head) mmlist = ((struct list_head *) next = 0xFFFFFF8041A08090, (struct list_head
      (long unsigned int) hiwater_rss = 7782,
      (long unsigned int) hiwater_vm = 58098,
      (long unsigned int) total_vm = 41714,  // <<-- K(mm->total_vm)
      (long unsigned int) locked_vm = 0,