Home | History | Annotate | Download | only in lmkd
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #define LOG_TAG "lowmemorykiller"
     18 
     19 #include <arpa/inet.h>
     20 #include <errno.h>
     21 #include <signal.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 #include <time.h>
     25 #include <sys/cdefs.h>
     26 #include <sys/epoll.h>
     27 #include <sys/eventfd.h>
     28 #include <sys/mman.h>
     29 #include <sys/socket.h>
     30 #include <sys/types.h>
     31 #include <unistd.h>
     32 
     33 #include <cutils/sockets.h>
     34 #include <log/log.h>
     35 #include <processgroup/processgroup.h>
     36 
     37 #ifndef __unused
     38 #define __unused __attribute__((__unused__))
     39 #endif
     40 
     41 #define MEMCG_SYSFS_PATH "/dev/memcg/"
     42 #define MEMPRESSURE_WATCH_LEVEL "low"
     43 #define ZONEINFO_PATH "/proc/zoneinfo"
     44 #define LINE_MAX 128
     45 
     46 #define INKERNEL_MINFREE_PATH "/sys/module/lowmemorykiller/parameters/minfree"
     47 #define INKERNEL_ADJ_PATH "/sys/module/lowmemorykiller/parameters/adj"
     48 
     49 #define ARRAY_SIZE(x)   (sizeof(x) / sizeof(*(x)))
     50 
     51 enum lmk_cmd {
     52     LMK_TARGET,
     53     LMK_PROCPRIO,
     54     LMK_PROCREMOVE,
     55 };
     56 
     57 #define MAX_TARGETS 6
     58 /*
     59  * longest is LMK_TARGET followed by MAX_TARGETS each minfree and minkillprio
     60  * values
     61  */
     62 #define CTRL_PACKET_MAX (sizeof(int) * (MAX_TARGETS * 2 + 1))
     63 
     64 /* default to old in-kernel interface if no memory pressure events */
     65 static int use_inkernel_interface = 1;
     66 
     67 /* memory pressure level medium event */
     68 static int mpevfd;
     69 
     70 /* control socket listen and data */
     71 static int ctrl_lfd;
     72 static int ctrl_dfd = -1;
     73 static int ctrl_dfd_reopened; /* did we reopen ctrl conn on this loop? */
     74 
     75 /* 1 memory pressure level, 1 ctrl listen socket, 1 ctrl data socket */
     76 #define MAX_EPOLL_EVENTS 3
     77 static int epollfd;
     78 static int maxevents;
     79 
     80 /* OOM score values used by both kernel and framework */
     81 #define OOM_SCORE_ADJ_MIN       (-1000)
     82 #define OOM_SCORE_ADJ_MAX       1000
     83 
     84 static int lowmem_adj[MAX_TARGETS];
     85 static int lowmem_minfree[MAX_TARGETS];
     86 static int lowmem_targets_size;
     87 
     88 struct sysmeminfo {
     89     int nr_free_pages;
     90     int nr_file_pages;
     91     int nr_shmem;
     92     int totalreserve_pages;
     93 };
     94 
     95 struct adjslot_list {
     96     struct adjslot_list *next;
     97     struct adjslot_list *prev;
     98 };
     99 
    100 struct proc {
    101     struct adjslot_list asl;
    102     int pid;
    103     uid_t uid;
    104     int oomadj;
    105     struct proc *pidhash_next;
    106 };
    107 
    108 #define PIDHASH_SZ 1024
    109 static struct proc *pidhash[PIDHASH_SZ];
    110 #define pid_hashfn(x) ((((x) >> 8) ^ (x)) & (PIDHASH_SZ - 1))
    111 
    112 #define ADJTOSLOT(adj) (adj + -OOM_SCORE_ADJ_MIN)
    113 static struct adjslot_list procadjslot_list[ADJTOSLOT(OOM_SCORE_ADJ_MAX) + 1];
    114 
    115 /*
    116  * Wait 1-2 seconds for the death report of a killed process prior to
    117  * considering killing more processes.
    118  */
    119 #define KILL_TIMEOUT 2
    120 /* Time of last process kill we initiated, stop me before I kill again */
    121 static time_t kill_lasttime;
    122 
    123 /* PAGE_SIZE / 1024 */
    124 static long page_k;
    125 
    126 static ssize_t read_all(int fd, char *buf, size_t max_len)
    127 {
    128     ssize_t ret = 0;
    129 
    130     while (max_len > 0) {
    131         ssize_t r = read(fd, buf, max_len);
    132         if (r == 0) {
    133             break;
    134         }
    135         if (r == -1) {
    136             return -1;
    137         }
    138         ret += r;
    139         buf += r;
    140         max_len -= r;
    141     }
    142 
    143     return ret;
    144 }
    145 
    146 static struct proc *pid_lookup(int pid) {
    147     struct proc *procp;
    148 
    149     for (procp = pidhash[pid_hashfn(pid)]; procp && procp->pid != pid;
    150          procp = procp->pidhash_next)
    151             ;
    152 
    153     return procp;
    154 }
    155 
    156 static void adjslot_insert(struct adjslot_list *head, struct adjslot_list *new)
    157 {
    158     struct adjslot_list *next = head->next;
    159     new->prev = head;
    160     new->next = next;
    161     next->prev = new;
    162     head->next = new;
    163 }
    164 
    165 static void adjslot_remove(struct adjslot_list *old)
    166 {
    167     struct adjslot_list *prev = old->prev;
    168     struct adjslot_list *next = old->next;
    169     next->prev = prev;
    170     prev->next = next;
    171 }
    172 
    173 static struct adjslot_list *adjslot_tail(struct adjslot_list *head) {
    174     struct adjslot_list *asl = head->prev;
    175 
    176     return asl == head ? NULL : asl;
    177 }
    178 
    179 static void proc_slot(struct proc *procp) {
    180     int adjslot = ADJTOSLOT(procp->oomadj);
    181 
    182     adjslot_insert(&procadjslot_list[adjslot], &procp->asl);
    183 }
    184 
    185 static void proc_unslot(struct proc *procp) {
    186     adjslot_remove(&procp->asl);
    187 }
    188 
    189 static void proc_insert(struct proc *procp) {
    190     int hval = pid_hashfn(procp->pid);
    191 
    192     procp->pidhash_next = pidhash[hval];
    193     pidhash[hval] = procp;
    194     proc_slot(procp);
    195 }
    196 
    197 static int pid_remove(int pid) {
    198     int hval = pid_hashfn(pid);
    199     struct proc *procp;
    200     struct proc *prevp;
    201 
    202     for (procp = pidhash[hval], prevp = NULL; procp && procp->pid != pid;
    203          procp = procp->pidhash_next)
    204             prevp = procp;
    205 
    206     if (!procp)
    207         return -1;
    208 
    209     if (!prevp)
    210         pidhash[hval] = procp->pidhash_next;
    211     else
    212         prevp->pidhash_next = procp->pidhash_next;
    213 
    214     proc_unslot(procp);
    215     free(procp);
    216     return 0;
    217 }
    218 
    219 static void writefilestring(char *path, char *s) {
    220     int fd = open(path, O_WRONLY | O_CLOEXEC);
    221     int len = strlen(s);
    222     int ret;
    223 
    224     if (fd < 0) {
    225         ALOGE("Error opening %s; errno=%d", path, errno);
    226         return;
    227     }
    228 
    229     ret = write(fd, s, len);
    230     if (ret < 0) {
    231         ALOGE("Error writing %s; errno=%d", path, errno);
    232     } else if (ret < len) {
    233         ALOGE("Short write on %s; length=%d", path, ret);
    234     }
    235 
    236     close(fd);
    237 }
    238 
    239 static void cmd_procprio(int pid, int uid, int oomadj) {
    240     struct proc *procp;
    241     char path[80];
    242     char val[20];
    243 
    244     if (oomadj < OOM_SCORE_ADJ_MIN || oomadj > OOM_SCORE_ADJ_MAX) {
    245         ALOGE("Invalid PROCPRIO oomadj argument %d", oomadj);
    246         return;
    247     }
    248 
    249     snprintf(path, sizeof(path), "/proc/%d/oom_score_adj", pid);
    250     snprintf(val, sizeof(val), "%d", oomadj);
    251     writefilestring(path, val);
    252 
    253     if (use_inkernel_interface)
    254         return;
    255 
    256     procp = pid_lookup(pid);
    257     if (!procp) {
    258             procp = malloc(sizeof(struct proc));
    259             if (!procp) {
    260                 // Oh, the irony.  May need to rebuild our state.
    261                 return;
    262             }
    263 
    264             procp->pid = pid;
    265             procp->uid = uid;
    266             procp->oomadj = oomadj;
    267             proc_insert(procp);
    268     } else {
    269         proc_unslot(procp);
    270         procp->oomadj = oomadj;
    271         proc_slot(procp);
    272     }
    273 }
    274 
    275 static void cmd_procremove(int pid) {
    276     if (use_inkernel_interface)
    277         return;
    278 
    279     pid_remove(pid);
    280     kill_lasttime = 0;
    281 }
    282 
    283 static void cmd_target(int ntargets, int *params) {
    284     int i;
    285 
    286     if (ntargets > (int)ARRAY_SIZE(lowmem_adj))
    287         return;
    288 
    289     for (i = 0; i < ntargets; i++) {
    290         lowmem_minfree[i] = ntohl(*params++);
    291         lowmem_adj[i] = ntohl(*params++);
    292     }
    293 
    294     lowmem_targets_size = ntargets;
    295 
    296     if (use_inkernel_interface) {
    297         char minfreestr[128];
    298         char killpriostr[128];
    299 
    300         minfreestr[0] = '\0';
    301         killpriostr[0] = '\0';
    302 
    303         for (i = 0; i < lowmem_targets_size; i++) {
    304             char val[40];
    305 
    306             if (i) {
    307                 strlcat(minfreestr, ",", sizeof(minfreestr));
    308                 strlcat(killpriostr, ",", sizeof(killpriostr));
    309             }
    310 
    311             snprintf(val, sizeof(val), "%d", lowmem_minfree[i]);
    312             strlcat(minfreestr, val, sizeof(minfreestr));
    313             snprintf(val, sizeof(val), "%d", lowmem_adj[i]);
    314             strlcat(killpriostr, val, sizeof(killpriostr));
    315         }
    316 
    317         writefilestring(INKERNEL_MINFREE_PATH, minfreestr);
    318         writefilestring(INKERNEL_ADJ_PATH, killpriostr);
    319     }
    320 }
    321 
    322 static void ctrl_data_close(void) {
    323     ALOGI("Closing Activity Manager data connection");
    324     close(ctrl_dfd);
    325     ctrl_dfd = -1;
    326     maxevents--;
    327 }
    328 
    329 static int ctrl_data_read(char *buf, size_t bufsz) {
    330     int ret = 0;
    331 
    332     ret = read(ctrl_dfd, buf, bufsz);
    333 
    334     if (ret == -1) {
    335         ALOGE("control data socket read failed; errno=%d", errno);
    336     } else if (ret == 0) {
    337         ALOGE("Got EOF on control data socket");
    338         ret = -1;
    339     }
    340 
    341     return ret;
    342 }
    343 
    344 static void ctrl_command_handler(void) {
    345     int ibuf[CTRL_PACKET_MAX / sizeof(int)];
    346     int len;
    347     int cmd = -1;
    348     int nargs;
    349     int targets;
    350 
    351     len = ctrl_data_read((char *)ibuf, CTRL_PACKET_MAX);
    352     if (len <= 0)
    353         return;
    354 
    355     nargs = len / sizeof(int) - 1;
    356     if (nargs < 0)
    357         goto wronglen;
    358 
    359     cmd = ntohl(ibuf[0]);
    360 
    361     switch(cmd) {
    362     case LMK_TARGET:
    363         targets = nargs / 2;
    364         if (nargs & 0x1 || targets > (int)ARRAY_SIZE(lowmem_adj))
    365             goto wronglen;
    366         cmd_target(targets, &ibuf[1]);
    367         break;
    368     case LMK_PROCPRIO:
    369         if (nargs != 3)
    370             goto wronglen;
    371         cmd_procprio(ntohl(ibuf[1]), ntohl(ibuf[2]), ntohl(ibuf[3]));
    372         break;
    373     case LMK_PROCREMOVE:
    374         if (nargs != 1)
    375             goto wronglen;
    376         cmd_procremove(ntohl(ibuf[1]));
    377         break;
    378     default:
    379         ALOGE("Received unknown command code %d", cmd);
    380         return;
    381     }
    382 
    383     return;
    384 
    385 wronglen:
    386     ALOGE("Wrong control socket read length cmd=%d len=%d", cmd, len);
    387 }
    388 
    389 static void ctrl_data_handler(uint32_t events) {
    390     if (events & EPOLLHUP) {
    391         ALOGI("ActivityManager disconnected");
    392         if (!ctrl_dfd_reopened)
    393             ctrl_data_close();
    394     } else if (events & EPOLLIN) {
    395         ctrl_command_handler();
    396     }
    397 }
    398 
    399 static void ctrl_connect_handler(uint32_t events __unused) {
    400     struct sockaddr_storage ss;
    401     struct sockaddr *addrp = (struct sockaddr *)&ss;
    402     socklen_t alen;
    403     struct epoll_event epev;
    404 
    405     if (ctrl_dfd >= 0) {
    406         ctrl_data_close();
    407         ctrl_dfd_reopened = 1;
    408     }
    409 
    410     alen = sizeof(ss);
    411     ctrl_dfd = accept(ctrl_lfd, addrp, &alen);
    412 
    413     if (ctrl_dfd < 0) {
    414         ALOGE("lmkd control socket accept failed; errno=%d", errno);
    415         return;
    416     }
    417 
    418     ALOGI("ActivityManager connected");
    419     maxevents++;
    420     epev.events = EPOLLIN;
    421     epev.data.ptr = (void *)ctrl_data_handler;
    422     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, ctrl_dfd, &epev) == -1) {
    423         ALOGE("epoll_ctl for data connection socket failed; errno=%d", errno);
    424         ctrl_data_close();
    425         return;
    426     }
    427 }
    428 
    429 static int zoneinfo_parse_protection(char *cp) {
    430     int max = 0;
    431     int zoneval;
    432     char *save_ptr;
    433 
    434     for (cp = strtok_r(cp, "(), ", &save_ptr); cp; cp = strtok_r(NULL, "), ", &save_ptr)) {
    435         zoneval = strtol(cp, &cp, 0);
    436         if (zoneval > max)
    437             max = zoneval;
    438     }
    439 
    440     return max;
    441 }
    442 
    443 static void zoneinfo_parse_line(char *line, struct sysmeminfo *mip) {
    444     char *cp = line;
    445     char *ap;
    446     char *save_ptr;
    447 
    448     cp = strtok_r(line, " ", &save_ptr);
    449     if (!cp)
    450         return;
    451 
    452     ap = strtok_r(NULL, " ", &save_ptr);
    453     if (!ap)
    454         return;
    455 
    456     if (!strcmp(cp, "nr_free_pages"))
    457         mip->nr_free_pages += strtol(ap, NULL, 0);
    458     else if (!strcmp(cp, "nr_file_pages"))
    459         mip->nr_file_pages += strtol(ap, NULL, 0);
    460     else if (!strcmp(cp, "nr_shmem"))
    461         mip->nr_shmem += strtol(ap, NULL, 0);
    462     else if (!strcmp(cp, "high"))
    463         mip->totalreserve_pages += strtol(ap, NULL, 0);
    464     else if (!strcmp(cp, "protection:"))
    465         mip->totalreserve_pages += zoneinfo_parse_protection(ap);
    466 }
    467 
    468 static int zoneinfo_parse(struct sysmeminfo *mip) {
    469     int fd;
    470     ssize_t size;
    471     char buf[PAGE_SIZE];
    472     char *save_ptr;
    473     char *line;
    474 
    475     memset(mip, 0, sizeof(struct sysmeminfo));
    476 
    477     fd = open(ZONEINFO_PATH, O_RDONLY | O_CLOEXEC);
    478     if (fd == -1) {
    479         ALOGE("%s open: errno=%d", ZONEINFO_PATH, errno);
    480         return -1;
    481     }
    482 
    483     size = read_all(fd, buf, sizeof(buf) - 1);
    484     if (size < 0) {
    485         ALOGE("%s read: errno=%d", ZONEINFO_PATH, errno);
    486         close(fd);
    487         return -1;
    488     }
    489     ALOG_ASSERT((size_t)size < sizeof(buf) - 1, "/proc/zoneinfo too large");
    490     buf[size] = 0;
    491 
    492     for (line = strtok_r(buf, "\n", &save_ptr); line; line = strtok_r(NULL, "\n", &save_ptr))
    493             zoneinfo_parse_line(line, mip);
    494 
    495     close(fd);
    496     return 0;
    497 }
    498 
    499 static int proc_get_size(int pid) {
    500     char path[PATH_MAX];
    501     char line[LINE_MAX];
    502     int fd;
    503     int rss = 0;
    504     int total;
    505     ssize_t ret;
    506 
    507     snprintf(path, PATH_MAX, "/proc/%d/statm", pid);
    508     fd = open(path, O_RDONLY | O_CLOEXEC);
    509     if (fd == -1)
    510         return -1;
    511 
    512     ret = read_all(fd, line, sizeof(line) - 1);
    513     if (ret < 0) {
    514         close(fd);
    515         return -1;
    516     }
    517 
    518     sscanf(line, "%d %d ", &total, &rss);
    519     close(fd);
    520     return rss;
    521 }
    522 
    523 static char *proc_get_name(int pid) {
    524     char path[PATH_MAX];
    525     static char line[LINE_MAX];
    526     int fd;
    527     char *cp;
    528     ssize_t ret;
    529 
    530     snprintf(path, PATH_MAX, "/proc/%d/cmdline", pid);
    531     fd = open(path, O_RDONLY | O_CLOEXEC);
    532     if (fd == -1)
    533         return NULL;
    534     ret = read_all(fd, line, sizeof(line) - 1);
    535     close(fd);
    536     if (ret < 0) {
    537         return NULL;
    538     }
    539 
    540     cp = strchr(line, ' ');
    541     if (cp)
    542         *cp = '\0';
    543 
    544     return line;
    545 }
    546 
    547 static struct proc *proc_adj_lru(int oomadj) {
    548     return (struct proc *)adjslot_tail(&procadjslot_list[ADJTOSLOT(oomadj)]);
    549 }
    550 
    551 /* Kill one process specified by procp.  Returns the size of the process killed */
    552 static int kill_one_process(struct proc *procp, int other_free, int other_file,
    553         int minfree, int min_score_adj, bool first)
    554 {
    555     int pid = procp->pid;
    556     uid_t uid = procp->uid;
    557     char *taskname;
    558     int tasksize;
    559     int r;
    560 
    561     taskname = proc_get_name(pid);
    562     if (!taskname) {
    563         pid_remove(pid);
    564         return -1;
    565     }
    566 
    567     tasksize = proc_get_size(pid);
    568     if (tasksize <= 0) {
    569         pid_remove(pid);
    570         return -1;
    571     }
    572 
    573     ALOGI("Killing '%s' (%d), uid %d, adj %d\n"
    574           "   to free %ldkB because cache %s%ldkB is below limit %ldkB for oom_adj %d\n"
    575           "   Free memory is %s%ldkB %s reserved",
    576           taskname, pid, uid, procp->oomadj, tasksize * page_k,
    577           first ? "" : "~", other_file * page_k, minfree * page_k, min_score_adj,
    578           first ? "" : "~", other_free * page_k, other_free >= 0 ? "above" : "below");
    579     r = kill(pid, SIGKILL);
    580     killProcessGroup(uid, pid, SIGKILL);
    581     pid_remove(pid);
    582 
    583     if (r) {
    584         ALOGE("kill(%d): errno=%d", procp->pid, errno);
    585         return -1;
    586     } else {
    587         return tasksize;
    588     }
    589 }
    590 
    591 /*
    592  * Find a process to kill based on the current (possibly estimated) free memory
    593  * and cached memory sizes.  Returns the size of the killed processes.
    594  */
    595 static int find_and_kill_process(int other_free, int other_file, bool first)
    596 {
    597     int i;
    598     int min_score_adj = OOM_SCORE_ADJ_MAX + 1;
    599     int minfree = 0;
    600     int killed_size = 0;
    601 
    602     for (i = 0; i < lowmem_targets_size; i++) {
    603         minfree = lowmem_minfree[i];
    604         if (other_free < minfree && other_file < minfree) {
    605             min_score_adj = lowmem_adj[i];
    606             break;
    607         }
    608     }
    609 
    610     if (min_score_adj == OOM_SCORE_ADJ_MAX + 1)
    611         return 0;
    612 
    613     for (i = OOM_SCORE_ADJ_MAX; i >= min_score_adj; i--) {
    614         struct proc *procp;
    615 
    616 retry:
    617         procp = proc_adj_lru(i);
    618 
    619         if (procp) {
    620             killed_size = kill_one_process(procp, other_free, other_file, minfree, min_score_adj, first);
    621             if (killed_size < 0) {
    622                 goto retry;
    623             } else {
    624                 return killed_size;
    625             }
    626         }
    627     }
    628 
    629     return 0;
    630 }
    631 
    632 static void mp_event(uint32_t events __unused) {
    633     int ret;
    634     unsigned long long evcount;
    635     struct sysmeminfo mi;
    636     int other_free;
    637     int other_file;
    638     int killed_size;
    639     bool first = true;
    640 
    641     ret = read(mpevfd, &evcount, sizeof(evcount));
    642     if (ret < 0)
    643         ALOGE("Error reading memory pressure event fd; errno=%d",
    644               errno);
    645 
    646     if (time(NULL) - kill_lasttime < KILL_TIMEOUT)
    647         return;
    648 
    649     while (zoneinfo_parse(&mi) < 0) {
    650         // Failed to read /proc/zoneinfo, assume ENOMEM and kill something
    651         find_and_kill_process(0, 0, true);
    652     }
    653 
    654     other_free = mi.nr_free_pages - mi.totalreserve_pages;
    655     other_file = mi.nr_file_pages - mi.nr_shmem;
    656 
    657     do {
    658         killed_size = find_and_kill_process(other_free, other_file, first);
    659         if (killed_size > 0) {
    660             first = false;
    661             other_free += killed_size;
    662             other_file += killed_size;
    663         }
    664     } while (killed_size > 0);
    665 }
    666 
    667 static int init_mp(char *levelstr, void *event_handler)
    668 {
    669     int mpfd;
    670     int evfd;
    671     int evctlfd;
    672     char buf[256];
    673     struct epoll_event epev;
    674     int ret;
    675 
    676     mpfd = open(MEMCG_SYSFS_PATH "memory.pressure_level", O_RDONLY | O_CLOEXEC);
    677     if (mpfd < 0) {
    678         ALOGI("No kernel memory.pressure_level support (errno=%d)", errno);
    679         goto err_open_mpfd;
    680     }
    681 
    682     evctlfd = open(MEMCG_SYSFS_PATH "cgroup.event_control", O_WRONLY | O_CLOEXEC);
    683     if (evctlfd < 0) {
    684         ALOGI("No kernel memory cgroup event control (errno=%d)", errno);
    685         goto err_open_evctlfd;
    686     }
    687 
    688     evfd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
    689     if (evfd < 0) {
    690         ALOGE("eventfd failed for level %s; errno=%d", levelstr, errno);
    691         goto err_eventfd;
    692     }
    693 
    694     ret = snprintf(buf, sizeof(buf), "%d %d %s", evfd, mpfd, levelstr);
    695     if (ret >= (ssize_t)sizeof(buf)) {
    696         ALOGE("cgroup.event_control line overflow for level %s", levelstr);
    697         goto err;
    698     }
    699 
    700     ret = write(evctlfd, buf, strlen(buf) + 1);
    701     if (ret == -1) {
    702         ALOGE("cgroup.event_control write failed for level %s; errno=%d",
    703               levelstr, errno);
    704         goto err;
    705     }
    706 
    707     epev.events = EPOLLIN;
    708     epev.data.ptr = event_handler;
    709     ret = epoll_ctl(epollfd, EPOLL_CTL_ADD, evfd, &epev);
    710     if (ret == -1) {
    711         ALOGE("epoll_ctl for level %s failed; errno=%d", levelstr, errno);
    712         goto err;
    713     }
    714     maxevents++;
    715     mpevfd = evfd;
    716     return 0;
    717 
    718 err:
    719     close(evfd);
    720 err_eventfd:
    721     close(evctlfd);
    722 err_open_evctlfd:
    723     close(mpfd);
    724 err_open_mpfd:
    725     return -1;
    726 }
    727 
    728 static int init(void) {
    729     struct epoll_event epev;
    730     int i;
    731     int ret;
    732 
    733     page_k = sysconf(_SC_PAGESIZE);
    734     if (page_k == -1)
    735         page_k = PAGE_SIZE;
    736     page_k /= 1024;
    737 
    738     epollfd = epoll_create(MAX_EPOLL_EVENTS);
    739     if (epollfd == -1) {
    740         ALOGE("epoll_create failed (errno=%d)", errno);
    741         return -1;
    742     }
    743 
    744     ctrl_lfd = android_get_control_socket("lmkd");
    745     if (ctrl_lfd < 0) {
    746         ALOGE("get lmkd control socket failed");
    747         return -1;
    748     }
    749 
    750     ret = listen(ctrl_lfd, 1);
    751     if (ret < 0) {
    752         ALOGE("lmkd control socket listen failed (errno=%d)", errno);
    753         return -1;
    754     }
    755 
    756     epev.events = EPOLLIN;
    757     epev.data.ptr = (void *)ctrl_connect_handler;
    758     if (epoll_ctl(epollfd, EPOLL_CTL_ADD, ctrl_lfd, &epev) == -1) {
    759         ALOGE("epoll_ctl for lmkd control socket failed (errno=%d)", errno);
    760         return -1;
    761     }
    762     maxevents++;
    763 
    764     use_inkernel_interface = !access(INKERNEL_MINFREE_PATH, W_OK);
    765 
    766     if (use_inkernel_interface) {
    767         ALOGI("Using in-kernel low memory killer interface");
    768     } else {
    769         ret = init_mp(MEMPRESSURE_WATCH_LEVEL, (void *)&mp_event);
    770         if (ret)
    771             ALOGE("Kernel does not support memory pressure events or in-kernel low memory killer");
    772     }
    773 
    774     for (i = 0; i <= ADJTOSLOT(OOM_SCORE_ADJ_MAX); i++) {
    775         procadjslot_list[i].next = &procadjslot_list[i];
    776         procadjslot_list[i].prev = &procadjslot_list[i];
    777     }
    778 
    779     return 0;
    780 }
    781 
    782 static void mainloop(void) {
    783     while (1) {
    784         struct epoll_event events[maxevents];
    785         int nevents;
    786         int i;
    787 
    788         ctrl_dfd_reopened = 0;
    789         nevents = epoll_wait(epollfd, events, maxevents, -1);
    790 
    791         if (nevents == -1) {
    792             if (errno == EINTR)
    793                 continue;
    794             ALOGE("epoll_wait failed (errno=%d)", errno);
    795             continue;
    796         }
    797 
    798         for (i = 0; i < nevents; ++i) {
    799             if (events[i].events & EPOLLERR)
    800                 ALOGD("EPOLLERR on event #%d", i);
    801             if (events[i].data.ptr)
    802                 (*(void (*)(uint32_t))events[i].data.ptr)(events[i].events);
    803         }
    804     }
    805 }
    806 
    807 int main(int argc __unused, char **argv __unused) {
    808     struct sched_param param = {
    809             .sched_priority = 1,
    810     };
    811 
    812     mlockall(MCL_FUTURE);
    813     sched_setscheduler(0, SCHED_FIFO, &param);
    814     if (!init())
    815         mainloop();
    816 
    817     ALOGI("exiting");
    818     return 0;
    819 }
    820