340 likes | 367 Views
Join us for a workshop on Android kernel issues and learn about various technologies and application approaches for implementing open mobile platforms like Google Android. Gain practical experience and knowledge to create new business models in the mobile industry.
E N D
Android Kernel Issues Date : Mar-13-2008, Thu (13:00 ~ )Location : Seoul Samsung-Dong COEX(1floor Grand Volume) Presentator : - CTO - S/W Lab - Lim,GeunSik (geunsik.lim@samsung.com) CONTENTS PART 1. OverviewPART 2. OpenBinderPART 3. EABIPART 4. Low Memory Killer 본 행사는 구글 안드로이드와 같은 오픈 모바일 플랫폼을 구현하기 위해 필요한 여러 기술과 적용 방안에 대해 알아보는 자리입니다. 실제 경험과 Know-how를 중심으로 구성된 본 행사는 모바일 비즈니스의 새로운 사업 모델을 창출하는 계기가 될 것입니다. 2008 Korea Android(www.kandroid.org)
1. Overview PART 1. OverviewPART 2. OpenBinderPART 3. EABIPART 4. Low Memory Killer
Part 1 Google & OpenSources ‘s Dinner for Open Mobile Platform • What is Android’s License? • Currently, Android Platform is open source completely. The Android mobile OS will be released under Apache License. This means that anyone can customize the android platform and then keep it proprietary. Openbinder Core Qemu Sqlite3 D-BUS SSL Linux Iland’sDalvik OpenGL BSD Libc KHTML Ant Python OpenGL Openbinder System zlib Expat SDL
Part 1 Android Kernel Features O : Needed △ : Option
Did you have Cross Compilr to Compile Android Kernel? • Sourcery G++ Lite Edition (CodeSourcery's version of the GNU Toolchain) • arm-2007q3-53-arm-none-eabi-i686-pc-linux-gnu.tar.bz2 • export PATH=$PATH:<cross_compiler_install_path>/bin/ • Android Kernel: http://android.googlecode.com/files/linux-2.6.23-android-m3-rc20.tar.gz • We need opensource for toolchain like Kernel, gcc, glibc, bintuils http://www.codesourcery.com/gnu_toolchains/arm/download.html • Download the ARM 2007q3 Release • Select "ARM EABI, IA32 GNU /Linux Option (Radio Box)" and Download - Target Platform: ARM EABI - Host Platform: IA32 GNU/Linux - Source Code: Unchecked • Default Floating Point : Soft-Float • If you are want to compile hard-float option to enable VFP Instruciton, Use -mfpu=vfp -mfloat-abit=softfp Select Cross Compiler for ARM v6 How to get CodeSourcery’s Toolchain Part 1 What is Cross Compiler to build Kernel?
fc6#> tar xzf linux-2.6.18-arm1136jf-s.armadillo-500.android.tar.gz fc6#> cd linux-2.6.18-arm1136jf-s.armadillo-500 fc6#> cp ./arch/arm/configs/goldfish_defconfig ./.config (GoldFish Config File) fc6#> make ARCH=arm CROSS_COMPILE=arm_none-linux-gnueabi- menuconfig fc6#> make ARCH=arm CROSS_COMPILE=arm_none-linux-gnueabi- zImage fc6#> make ARCH=arm CROSS_COMPILE=arm_none-linux-gnueabi- modules fc6#> make ARCH=arm CROSS_COMPILE=arm_none-linux-gnueabi- modules_install fc6#> cp ./arch/arm/boot/zImage /tftpboot/ fc6#> cp –rf /lib/modules/ linux-2.6.18-arm1136jf-s.armadillo-500 /tftpboot/target/lib/modules/ fc6#> <android_sdk_install_path>/tools/emulator –console –debug-kernel –kernel kernel-qemu fc6#> adb pull /proc/config.gz ./ fc6#> gunzip config.gz fc6#> vi ./.config Get default .config file from rootFS of anroid emulator. Build 2.6 Kernel Source Part 1 How to build Kernel Source for Android Platform
2. OpenBinder PART 1. OverviewPART 2. OpenBinderPART 3. EABIPART 4. Low Memory Killer
1998 Binder is developed by BeOS. 2001 Palm Company acquired BeOS. 2001 Palm’s Micro Kernel is consist of Binder. 2004 netBSD Cobalt Kernel http://www.netbsd.org/ports/cobalt/ 2005 Contributed by Palm(OHA Member) , 2005 Google used Openbinder for android. (Not Opensource : graphics , user interface , multimedia ramework) 2007 Current BeOS (http://www.beosmax.org) • A complete open-source solution supporting new kinds of component-based system-level design. • Resource management between processes. • Binder is system oriented rather than application oriented. • Support a new kind of component-based system-level development. • Component/object representations of various basic system services. • Binder itself does not impose a particular threading model.The Binder has been used to implement a wide variety of commercial-quality system-level services. Openbiner’s History Part 2 What is OpenBinder? OpenBinder is an open-sourcesystem component framework. OHA
Hardware Scalability System Customization Robust Applications Part 2 Why OpenBinder? These platforms were designed to run on small handheld or dedicated devices. • The mobile device world tends to have a much broader range of hardware capabilities than is found on desktops. size and battery life • ability to run on anything from a 50MHz ARM 7 CPU (without memory protection) up to a 400MHz ARM 9 CPU and beyond. burden on system software • Both hardware manufacturers and phone carriers want to deeply customize their behavior. • it much easier to support this kind of customizability in a manageable way. • Usage of the screen can become a significant problem for more complicated applications, such as web browsers. • Binder helps address this issue by making it easy for one application to sandbox other parts of itself.
make menuconfig & Device Node & Binding Example Part 2 How to Use OpenBinder Driver in Kernel • OpenBinder의 자체적인 통신은 Kernel의 Device Driver으로 통신할 수 있는 주어진 핸들에서 ioctl를 사용하여 수행. For IPC • Android 의 Process(Thread) 생성시마다 binder라는 IPC Mechanism이 부착됨. * Character Device is 251 ~ 253* http://www.lanana.org/docs/device-list/
dd <./dbus-daemon/bus/> activation.c, bus.c, config-loader-expat.c config-parser.c, connection.c, desktop-file.c, dispatch.c, driver.c, expirelist.c, bus/policy.c, services.c, signals.c Part 2 Map info of Google Map Process • What is IPC Mechenism of Android platform for Mobile ? Both Openbinder and D-bus. <ps information on android platform>root 1657 1 100512 24852 ffffffff afe0d204 S /system/bin/runtime bluetooth 1658 1 1224 776 c00a34e8 afe0d07c S /system/bin/dbus-daemon • System for sending messages between applications. (Systemwide message-bus service) http://www.freedesktop.org/software/dbus/ For example , Broadcast signal and System/Session Bus D-BUSVer0.95 OpenBinder Ver 0.8 http://www.open-binder.org • Don't worry about processes or IPC Because of distributed architecture. • Provides resource management between processes. • Handle on an object in another proces. • Powerful facilities for doing multithreaded programming with the Binder.
target#> cd /etc/udev/rules.d/ • target#> vi binderdev.rules • KERNEL=="binder*", NAME="%k", MODE="0666" • target#> vi /etc/autobinder.sh • # you almost certainly want to run this with sudo • depmod • modprobe binderdev • echo lsmod | grep binder • lsmod | grep binder • ls /dev/binder • target#> insmod binderdev.ko • target#> lsmod • Module Size Used by Not tainted • binderdev 63152 0 - Live 0xbf000000 • target#> mknod /dev/binder c 253 0 • target#> /bin/chmod -R a+rw /dev/binder Priority of Created Thread in Android Kernel How to make udev rule How to make static /dev/ rule Part 2 How to combine Openbinder and Udev in rootFS • Do you want to use Dynamic User-space Device in your rootFS?
OpenBinder Ver 0.8 Package Part 2 OpenBinder http://www.mozilla.org/MPL/ ※ OpenBinder는 OS 설계를 위한 객체 지향적 접근 방식을 시도한 기존과는 다른 새로운 방식의 접근 방식으로, 전통적인 Kernel에 의해 구성되는 객체 지향적 운영체제 환경을 제공함. ※ System의 가장 큰 힘은 Multi Process들로 작업이 수행될 때이며,Android에서는 Process들간의 상호작용 및 Object 참조를 효율적으로 관리하기 위하여 Core OpenBinder에 의해 사용되는 특별한 IPC Mechanism을 이용.
Main Role of Conrtibutor Part 2 OpenBinder Contributors
File List in Kernel Space Part 2 Core OpenBinder System http://www.gnu.org/copyleft/gpl.html/
static void set_thread_priority(pid_t thread, int priority) • {// Android Kernel’s Scheduling is Dynamic Priority(=Normal Priority ) to schedule between threads. • int nice; • // The following must match SysThreadChangePriority in libbinder. • if( priority >= 80 ) Worse Priority or low priority ( map 80..100 to 0..19) • { nice = priority - 80; • if(nice > 19) • nice = 19; • } • else Better priority or High Priority ( map 0..79 to -20..-1) • { nice = priority-3 - 80; • nice /= 4; • } • //printk(“*invain’s DEBUG: set_thread_priority tid %d pri %d == nice %d\n", thread, priority, nice); • set_user_nice(find_task_by_pid(thread), nice); • } Priority of the Created Thread in Android Kernel Part 2 Thread’s Priority binding to the OpenBinder • Do you need Realtime Characterestics for Mobile? • Why does nobody talked about the characteristics of real-time kernel androids not? • We can use Preemptible Kernel in Kernel Space for Realtime, But UserSpace Realtime? • We can Implement User-space Realtime Application with Locked Mutex Method (FUTEX) • (Ex: Priority Queuing , Priority Inheritance , Robust Mutex ) App’s Throughput App’s Latency
3. EABI (Embedded Application Binary Interface) PART 1. OverviewPART 2. OpenBinderPART 3. EABIPART 4. Low Memory Killer
EABI(Embedded Application Binary Interface) Part 3 What is EABI? • It sets the standard for the interoperation between relocated files, as well as executable files, for embedded architectures. • the standard makes it possible to combine object files built using different toolchains if both their compilers use EABI. • GCC : CS-2005Q3 release is a modified version of gcc-3.4.4 from gcc-4.1.0 • The commercial ARM RealView C/C++ compiler was the first to support EABI (GCC4.1) • Kernel: EABI is supported in the ARM Linux kernel from version 2.6.16. • Glibc : Earlier glibcs (2.3.3) support EABI userspace but had old-style syscalls to work with older kernels (2.6.0-2.6.15). The effective features for arm-linux users with the use of EABI are Ref 1) Experience showed that those syscall wrappers can not cover all the needed ABI mismatch since some of them are simply hidden from the C library, especially with specialized applications like iptables for example. ARM Information Center - http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0036a/
Part 3 Extending the ARM Processor Portfolio • Continued licensing of both mature and new technology • Cortex-A9 Ecosystem EDA, OS and Software companies supporting Cortex-A9 In Mobile Market Android 년도
http://gcc.gnu.org/svn/gcc/branches/gcc-4_3-branch/gcc/config/arm/arm.chttp://gcc.gnu.org/svn/gcc/branches/gcc-4_3-branch/gcc/config/arm/arm.c • http://sourceware.org/cgi-bin/cvsweb.cgi/src/gas/config/tc-arm.c?cvsroot=src Part 3 Arch & CPU information of GCC about android …………………………… Upper Omission ………………………… {"armv4t", arm7tdmi, "4T", FL_CO_PROC | FL_FOR_ARCH4T, NULL}, {"armv5", arm10tdmi, "5", FL_CO_PROC | FL_FOR_ARCH5, NULL}, {"armv5t", arm10tdmi, "5T", FL_CO_PROC | FL_FOR_ARCH5T, NULL}, {"armv5e", arm1026ejs, "5E", FL_CO_PROC | FL_FOR_ARCH5E, NULL}, {"armv5te", arm1026ejs, "5TE", FL_CO_PROC | FL_FOR_ARCH5TE, NULL}, {"armv6", arm1136js, "6", FL_CO_PROC | FL_FOR_ARCH6, NULL}, {"armv6j", arm1136js, "6J", FL_CO_PROC | FL_FOR_ARCH6J, NULL}, {"armv6k", mpcore, "6K", FL_CO_PROC | FL_FOR_ARCH6K, NULL}, {"armv6z", arm1176jzs, "6Z", FL_CO_PROC | FL_FOR_ARCH6Z, NULL}, {"armv6zk", arm1176jzs, "6ZK", FL_CO_PROC | FL_FOR_ARCH6ZK, NULL}, {"armv6t2", arm1156t2s, "6T2", FL_CO_PROC | FL_FOR_ARCH6T2, NULL}, {"armv7", cortexa8, "7", FL_CO_PROC | FL_FOR_ARCH7, NULL}, {"armv7-a", cortexa8, "7A", FL_CO_PROC | FL_FOR_ARCH7A, NULL}, {"armv7-r", cortexr4, "7R", FL_CO_PROC | FL_FOR_ARCH7R, NULL}, {"armv7-m", cortexm3, "7M", FL_CO_PROC | FL_FOR_ARCH7M, NULL}, {"ep9312", ep9312, "4T", FL_LDSCHED | FL_CIRRUS | FL_FOR_ARCH4, NULL}, {"iwmmxt", iwmmxt, "5TE", FL_LDSCHED | FL_STRONG | FL_FOR_ARCH5TE | FL_XSCALE | FL_IWMMXT , NULL}, {NULL, arm_none, NULL, 0 , NULL} }; …………………………… Upper Omission ………………………… {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL}, {"arm10tdmi", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL}, {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL}, {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM1020E"},
The common gcc command options that are available for EABI are ARM syscall entry convention Part 3 Cross Compiler for EABI EABI user space binaries put the syscall number into r7 and use swi 0 to call the kernel. Syscall register arguments are also expected to have EABI arrangements , that is, 64-bit arguments should be put in a pair of registers from an even register number. Example ARM sycall entry convention with long ftruncate64 (unsigned int fd, loff_t length.
./include/asm-arm/unistd.h Part 3 Legacy ABI vs. EABI It is important to use 0 for the swi argument because backward compatibility with legacy ABI userspace relies on this. The syscall macros in asm-arm/unistd.h were also updated to support both ABIs and implement the right call method automatically. Exectuable Binary Compatibility EABI Legacy ABI • put fd into r0 • put length into r1-r2 • use “swi #(0x900000 + 194)” to call the kernel • put fd into r0 • put length into r2-r3 (skipping over r1) • put 194 into r7 • use “swi 0" to call the kernel 13 #ifndef __ASM_ARM_UNISTD_H 14 #define __ASM_ARM_UNISTD_H 15 #define __NR_OABI_SYSCALL_BASE 0x900000 16 #if defined(__thumb__) || defined(__ARM_EABI__) 17 #define __NR_SYSCALL_BASE 0 18 #else 19 #define __NR_SYSCALL_BASE __NR_OABI_SYSCALL_BASE 20 #endif EABI
For example, Your kernel is 2.6.15- . So You need EABI Feature. Part 3 If EABI is not supported in your kernel? • On any ARM toolchain (v5t_le, xscale_le), in the Processor Features area, the following new freatures need to be set EABI.
Legacy ABI New EABI Part 3 Legacy ABI vs. EABI
Is it possible to run both EABI and non-EABI binaries on the same system? Part 3 Cross Compiler for EABI Yes, it is possible. However, running a dual-ABI system requires care. If you have an old-ABI system, and want to run EABI binaries, you have several choices. One option is to link your programs statically, using the -static option. However, linking dynamically is generally a superior approach. Generally, toolchains use a different dynamic loader (ld.so.3), so it is possible for old-ABI and EABI binaries to coexist. However, you will have to ensure that when you install the EABI libraries you do not overwrite existing libraries, and you will have to set LD_LIBRARY_PATH so that the dynamic loader can find them. ※ Support EABI Feature “make menuconfig”–“Kernel Features”–“[*]Use the ARM EABI to compile the kernel” EABI 관련하여 설명하고 있는 사이트.
4. Low Memory Killer PART 1. OverviewPART 2. OpenBinderPART 3. EABIPART 4. Low Memory Killer
Why Google develop Low Memory Killer without OOM? Part 4 What is Low Memory Killer? TargetBoard에서 사용가능한 Memory 공간이 고갈 상태에 이르렀을 때, OOM(Out Of Memory)을 발생시키는 방법을 사용하지 않고, Process들의 중요도에 따라 Group으로 나눈 후에 중요도가 낮은 Group에 있는 Process부터 하나씩 하나씩 Kill하여 Android의 전체적인 System의 운영을 유지시켜주는 Memory를 확보하는 방법이다. EX) 메모리가 고갈 상태에 이르렀을 때, Low Memory Killer가 작동되면서 udev 프로세스를 Kill. …………………………윗부분 생략 ………………………………. printk: 8 messages suppressed. oom-killer: gfp_mask=0x201d2, order=0 Mem-info: DMA per-cpu: cpu 0 hot: high 18, batch 3 used:12 cpu 0 cold: high 6, batch 1 used:2 DMA32 per-cpu: empty Normal per-cpu: empty HighMem per-cpu: empty Free pages: 1436kB (0kB HighMem) Active:6717 inactive:1641 dirty:0 writeback:0 unstable:0 free:359 slab:1458 mapped:61 pagetables:1700 DMA free:1436kB min:1024kB low:1280kB high:1536kB active:26868kB inactive:6564kB present:65536kB pages_scanned:14954 all_unreclaimable? no lowmem_reserve[]: 0 0 0 0 DMA32 free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no lowmem_reserve[]: 0 0 0 0 Normal free:0kB min:0kB low:0kB high:0kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no lowmem_reserve[]: 0 0 0 0 HighMem free:0kB min:128kB low:128kB high:128kB active:0kB inactive:0kB present:0kB pages_scanned:0 all_unreclaimable? no lowmem_reserve[]: 0 0 0 0 DMA: 51*4kB 26*8kB 4*16kB 0*32kB 1*64kB 1*128kB 1*256kB 1*512kB 0*1024kB 0*2048kB 0*4096kB = 1436kB DMA32: empty Normal: empty HighMem: empty Swap cache: add 0, delete 0, find 0/0, race 0+0 Free swap = 0kB Total swap = 0kB Out of Memory: Kill process 908 (udevd) score 122 and children. Out of memory: Killed process 1922 (udev). Free swap: 0kB 16384 pages of RAM 2623 free pages 924 reserved pages 1458 slab pages 279 pages shared 0 pages swap cached …………………………아랫 부분 생략 ………………………………. • “ lowmem_reserver” Region ./kernel-2.6/mm/page_alloc.c File의 show_free_areas( ) Func 안의 for_each_zone() Func에서 수행.
oom-killer: gfp_mask=0x201d2, order=0 [<c0144b11>] out_of_memory+0x25/0x144 [<c0145fa7>] __alloc_pages+0x1f5/0x275 [<c0147117>] __do_page_cache_readahead+0xc8/0x1e8 [<c01162e5>] __wake_up_common+0x2f/0x53 [<c0116755>] __wake_up+0x2a/0x3d [<c014420e>] filemap_nopage+0x151/0x30b [<c014c731>] __handle_mm_fault+0x24e/0x705 [<c01248a3>] do_gettimeofday+0x31/0xce [<c011554e>] do_page_fault+0x18a/0x46c [<c01153c4>] do_page_fault+0x0/0x46c [<c01037d5>] error_code+0x39/0x40 Mem-info: DMA per-cpu: cpu 0 hot: high 0, batch 1 used:0 ………… Middle Omission …………… Free pages: 21472kB (340kB HighMem) ………… Below Omission …………… OOM Example Kenrel Messages When OOM Guide for Embedded Memory Programming Part 4 OOM (Out of Memory ) Killer Case1) Program is allocating memory continually. while (1) { if (malloc(1<<50) == NULL) { printf("malloc failure after %d MiB\n", n); return 0; } printf ("Got %d Mb\n", ++n); } Case2) Program allocate memory, and use memory immediately. while (1) { if ((Temp = malloc(1<<50)) == NULL) { printf("malloc failure after %d MiB\n", n); return 0;} memset (p, 0, (1<<50)); printf ("Got %d Mb\n", ++n); } Case3) Allocate needed memory using for(), Use allocated memory using for(). for (n = 0; num < 50,000 ; n++) { temp[num] = malloc(1<<50); if (temp[num] == NULL) break; } printf("malloc failure after %d MiB\n", n); for (i = 0; i < num; i++) { memset ( pp[i], 0, (1<<50) ); printf("Got %d Mb\n", i+1); } If fail mem allocation, program exit. If fail mem allocation, program exit. ※ Kernel Messages Analysis: This is caused by DMA problem. Physical HDD’s Problem? In fact , This Memory Allocation Policy Related Problem. ※ Case 3에서 OOM killer는 init를 제외한 현재 실행중인 모든 Process들을 검사 Memory Usage에 따라 Score 부여 이때 superuser Process나 Hardware를 Access중인 Process는 점수가 1/4로 삭감됨 Score가 가장 많은 Process를 Kill함. • What Every Programmer Should Know About Memory • Understanding The Linux Virtual Memory manager • Understanding Virtual Memory in Red Hat Enterprise Linux 4
How do we make Application’s life cycle in Mobile/Embedded? Highest Lowest Part 4 Android Application ‘s Life Cycle 1/2 Android의 중요하면서 보편적이지 않은 하나의 특징은 Application 프로세스의 생명주기가 해당 애플리케이션에 의해 직접적으로 제어되지 않는 다는 것이다. 대신, Application이 사용자를 위해서 얼마나 중요한가? 그리고 시스템 전체적으로 얼마나 많은 Memory가 유용한가라는 Application 실행과 관련된 시스템의 인식기반과 관련된 Application의 조합된 영역들에 의해 결정 남. Importance http://code.google.com/android/intro/lifecycle.html
Why Application’s life cycle is important in android platform? Part 4 Android Application ‘s Life Cycle 2/2 Application 개발자가 Application Process의 생명주기에 얼마나 다른 Application Component (특별히, Activity, Service, IntentReceiver) 가 영향을 미치는가를 이해하는 것은 중요하다. 이러한 Component들을 정확하게 사용하지 않는다면,시스템이 해당 Application이 중요한 작업을 수행 하는 동안 해당 Process를 종료시키는 결과를 야기할 수 있다. Process 생명주기와 관련된 Bug중 일반적인 사례가 IntentReceiver가 onReceveIntent() Method내에서 Intent를 받을 때 Thread를 시작한 다음 해당 함수를 리턴하는 경우이다. 그러한 리턴이 발생 하면, System은 IntentReceiver가 더이상 Active되어 있지 않다고 간주하고, 따라서 그 Hosting Process가 더이상 필요하지 않다고 간주한다. (단지, 다른 Application Component가 그 안에서 Active 되지 않는 한) 따라서, System은 메모리 반환요청이 있는 어떤 시점에선 해당 Process를 종료시킬 수 있다. 이 문제를 해결하기 위한 해법은 System이 해당 Process 내에서 행해지고 있는 Active화된 작업이 여전히 존재한다는 것을 알도록 IntentReceiver로부터 Service를 시작시키는 것이다 . Maps Service Android는 Memory가 부족할 때, 어떤 Process들이 종료되어야 하는가를 결정하기 위해서, Android는 Process를 그것 안에서 실행되는 Component와 그러한 Component의 상태에 기반을 둔 "importance hierarchy "에 추가함.
. Location of Low memory killer Part 4 Kernel Module for Low Memory Killer • ./kernel-2.6/misw/lowmemorykiller/ • Process에 대한 분류방법을 결정할 때, System은 Process내에서 현재 활성화 된 모든 Component 중에서 가장 중요한 레벨을 얻어냄. • Process의 모든 생명주기에 이러한 Activity, Service, IntentReceiver 같은 Component의 각각이 얼마나 영향을 미치는 지에 대해서는 각각에 대한 보다 자세한 문서를 http://code.google.com을 통해서 열람.
. Part 4 About Android’s low memory shrink task • lowmem_shrink() ※Linux Cross Reference WebTool http://lxr.linux.no/linux if(nr_to_scan > 0) lowmem_print(3, "lowmem_shrink %d, %x, ofree %d, ma %d\n", nr_to_scan, gfp_mask, other_free, min_adj); read_lock(&tasklist_lock); for_each_process(p) { if(p->oomkilladj >= 0 && p->mm) { tasksize = get_mm_rss(p->mm); if(nr_to_scan > 0 && tasksize > 0 && p->oomkilladj >= min_adj) { if(selected == NULL || p->oomkilladj > selected->oomkilladj || (p->oomkilladj == selected->oomkilladj && tasksize > selected_tasksize)) { selected = p; selected_tasksize = tasksize; lowmem_print(2, "select %d (%s), adj %d, size %d , to kill\n", p->pid, p->comm, p->oomkilladj, tasksize); } } rem += tasksize; } } if(selected != NULL) { lowmem_print(1, "send sigkill to %d (%s), adj %d, size %d\n", selected->pid, selected->comm, selected->oomkilladj, selected_tasksize); force_sig(SIGKILL, selected); rem -= selected_tasksize; } lowmem_print(4, "lowmem_shrink %d, %x, return %d\n", nr_to_scan, gfp_mask, rem); read_unlock(&tasklist_lock); return rem; ※ static size_t lowmem_minfree[6]={ 3*512, // 6MB = 3 x 5123 x 4 2*1024, // 8MB = 2 x 1024 x 4 4*1024, // 16MB= 4 x 1024 x 4 16*1024, // 64MB = 16x1024 x 4 }; ※ Default lowmem_debug_level is 2. If you want to debug , use 3+ value.