1 // Copyright 2016 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 // This file defines:
8 // * Initialization code for kernel/object module
9 // * Singleton instances and global locks
10 // * Helper functions
11 
12 #include <inttypes.h>
13 
14 #include <trace.h>
15 
16 #include <kernel/cmdline.h>
17 
18 #include <lk/init.h>
19 
20 #include <lib/oom.h>
21 
22 #include <object/diagnostics.h>
23 #include <object/excp_port.h>
24 #include <object/job_dispatcher.h>
25 #include <object/port_dispatcher.h>
26 #include <object/process_dispatcher.h>
27 
28 #include <fbl/function.h>
29 
30 #include <zircon/types.h>
31 
32 #define LOCAL_TRACE 0
33 
34 // All jobs and processes are rooted at the |root_job|.
35 static fbl::RefPtr<JobDispatcher> root_job;
36 
GetRootJobDispatcher()37 fbl::RefPtr<JobDispatcher> GetRootJobDispatcher() {
38     return root_job;
39 }
40 
oom_lowmem(size_t shortfall_bytes)41 static void oom_lowmem(size_t shortfall_bytes) {
42     printf("OOM: oom_lowmem(shortfall_bytes=%zu) called\n", shortfall_bytes);
43 
44     bool found = false;
45     JobDispatcher::ForEachJob([&found](JobDispatcher* job) {
46         if (job->get_kill_on_oom()) {
47             // The traversal order of ForEachJob() is going to favor killing newer
48             // jobs, this helps in case more than one is eligible.
49             if (job->Kill()) {
50                 found = true;
51                 char name[ZX_MAX_NAME_LEN];
52                 job->get_name(name);
53                 printf("OOM: killing job %6" PRIu64 " '%s'\n", job->get_koid(), name);
54                 return ZX_ERR_STOP;
55             }
56         }
57         return ZX_OK;
58     });
59 
60     if (!found) {
61         printf("OOM: no alive job has a kill bit\n");
62     }
63 }
64 
object_glue_init(uint level)65 static void object_glue_init(uint level) TA_NO_THREAD_SAFETY_ANALYSIS {
66     Handle::Init();
67     root_job = JobDispatcher::CreateRootJob();
68     PortDispatcher::Init();
69     // Be sure to update kernel_cmdline.md if any of these defaults change.
70     oom_init(cmdline_get_bool("kernel.oom.enable", true),
71              ZX_SEC(cmdline_get_uint64("kernel.oom.sleep-sec", 1)),
72              cmdline_get_uint64("kernel.oom.redline-mb", 50) * MB,
73              oom_lowmem);
74 }
75 
76 LK_INIT_HOOK(libobject, object_glue_init, LK_INIT_LEVEL_THREADING);
77