Android - oom-killer invoked failures

     Android's low memory killer was introduced to proactively look for low memory situations and kill least important or background process to restore some memory. So much so that one of the google developer at Google IO 2011 claimed that malloc in Android would never fail. For most part this makes sense and an android device with many applications would usually have low memory kill logs in dmesg.

[  793.376328] select 378 (Usage), adj 10, size 5552, to kill
[  793.376354] send sigkill to 378 (Usage), adj 10, size 5552
[  794.313554] select 409 (Homescreen), adj 8, size 4065, to kill
[  794.313576] select 500 ((Preallocated a), adj 10, size 2787, to kill
[  794.313591] send sigkill to 500 ((Preallocated a), adj 10, size 2787
[  796.038379] select 409 (Homescreen), adj 8, size 4213, to kill
[  796.038398] send sigkill to 409 (Homescreen), adj 8, size 4213

      However, in some cases, the kernel logs might have the linux's out of memory killer logs like so so has invoked oom-killer logs. This is usually seen when Android is ported on to a new hardware.

<4>[ 3471.413659] ... invoked oom-killer: gfp_mask=0x200da, order=0, oom_adj=2, oom_score_adj=134
<4>[ 3471.413721] [<c00497f4>] (unwind_backtrace+0x0/0x12c) from [<c0135760>] (dump_header.clone.1+0x6c/0x18c)
<4>[ 3471.413747] [<c0135760>] (dump_header.clone.1+0x6c/0x18c) from [<c01358c0>] (oom_kill_process.clone.0+0x40/0x21c)
<4>[ 3471.413772] [<c01358c0>] (oom_kill_process.clone.0+0x40/0x21c) from [<c0135cf8>] (out_of_memory+0x25c/0x330)
<4>[ 3471.413799] [<c0135cf8>] (out_of_memory+0x25c/0x330) from [<c0139728>] (__alloc_pages_nodemask+0x4fc/0x6ac)
<4>[ 3471.413826] [<c0139728>] (__alloc_pages_nodemask+0x4fc/0x6ac) from [<c014ec30>] (handle_pte_fault+0x188/0x818)
<4>[ 3471.413849] [<c014ec30>] (handle_pte_fault+0x188/0x818) from [<c014f8e0>] (handle_mm_fault+0x1c0/0x1dc)
<4>[ 3471.413874] [<c014f8e0>] (handle_mm_fault+0x1c0/0x1dc) from [<c05b8d10>] (do_page_fault+0x164/0x314)
<4>[ 3471.413902] [<c05b8d10>] (do_page_fault+0x164/0x314) from [<c003d240>] (do_DataAbort+0x34/0x94)
<4>[ 3471.413932] [<c003d240>] (do_DataAbort+0x34/0x94) from [<c05b7160>] (ret_from_exception+0x0/0x10)
<4>[ 3471.413947] Exception stack(0xc4679fb0 to 0xc4679ff8)
<4>[ 3471.413962] 9fa0:                                     4b52b000 00000000 00000fe0 00000000
<4>[ 3471.413981] 9fc0: beb74180 fffff634 41db70a8 000002ea 00000800 00002000 4b52c000 00000000
<4>[ 3471.413999] 9fe0: 00000000 beb74144 00000000 41423bc4 20000010 ffffffff 

     So why would oom-killer be invoked despite the low memory killer? Ideally, the low memory killer should have had enough opportunity to kill background process? A look into the design of the low memory killer explains the scenario. Android's low memory killer unlike linux's out of memory killer checks the memory status periodically.

static struct shrinker lowmem_shrinker = {
.shrink = lowmem_shrink,
.seeks = DEFAULT_SEEKS * 16
};

     So its still possible for oom-killer to be invoked when a huge memory request is initiated during the sleep time of low memory killer and the request can't be serviced. Usually, applications don't cause this behavior and the candidate is often the vendor specific implementations like persistent services, graphics etc. This probably explains as to why Android developers never really disabled the pom killer and issued guidelines (https://source.android.com/devices/low-ram.html) to fine tune low memory killer for vendor specific implementations.

      

No comments: