Rename EVENT_FALLBACK -> EVENT_SPAM_INDIR (XCC)
[akaros.git] / Documentation / kernel_messages.txt
1 kernel_messages.txt
2 Barret Rhoden
3 2010-03-19
4 Updated 2012-11-14
5
6 This document explains the basic ideas behind our "kernel messages" (KMSGs) and
7 some of the arcane bits behind the implementation.  These were formerly called
8 active messages, since they were an implementation of the low-level hardware
9 messaging.
10
11 Overview:
12 --------------------------------
13 Our kernel messages are just work that is shipped remotely, delayed in time, or
14 both.  They currently consist of a function pointer and a few arguments.  Kernel
15 messages of a given type will be executed in order, with guaranteed delivery.
16
17 Initially, they were meant to be a way to immediately execute code on another
18 core (once interrupts are enabled), in the order in which the messages were
19 sent.  This is insufficient (and wasn't what we wanted for the task,
20 incidentally).  We simply want to do work on another core, but not necessarily
21 instantly.  And not necessarily on another core.
22
23 Currently, there are two types, distinguished by which list they are sent to per
24 core: immediate and routine.   Routine messages are often referred to as RKMs.
25 Immediate messages will get executed as soon as possible (once interrupts are
26 enabled).  Routine messages will be executed at convenient points in the kernel.
27 This includes when the kernel is about to pop back to userspace
28 (proc_restartcore()), or smp_idle()ing.  Routine messages are necessary when
29 their function does not return, such as a __launch_kthread.  They should also be
30 used if the work is not worth fully interrupting the kernel.  (An IPI will still
31 be sent, but the work will be delayed).  Finally, they should be used if their
32 work could affect currently executing kernel code (like a syscall).
33
34 For example, some older KMSGs such as __startcore used to not return and would
35 pop directly into user space.  This complicted the KMSG code quite a bit.  While
36 these functions now return, they still can't be immediate messages.  Proc
37 management KMSGs change the cur_ctx out from under a syscall, which can lead to
38 a bunch of issues.
39
40 Immediate kernel messages are executed in interrupt context, with interrupts
41 disabled.  Routine messages are only executed from places in the code where the
42 kernel doesn't care if the functions don't return or otherwise cause trouble.
43 This means RKMs aren't run in interrupt context in the kernel (or if the kernel
44 code itself traps).  We don't have a 'process context' like Linux does, instead
45 its more of a 'default context'.  That's where RKMs run, and they run with IRQs
46 disabled.
47
48 RKMs can enable IRQs, or otherwise cause IRQs to be enabled.  __launch_kthread
49 is a good example: it runs a kthread, which may have had IRQs enabled.
50
51 With RKMs, there are no concerns about the kernel holding locks or otherwise
52 "interrupting" its own execution.  Routine messages are a little different than
53 just trapping into the kernel, since the functions don't have to return and may
54 result in clobbering the kernel stack.  Also note that this behavior is
55 dependent on where we call process_routine_kmsg().  Don't call it somewhere you
56 need to return to.
57
58 An example of an immediate message would be a TLB_shootdown.  Check current,
59 flush if applicable, and return.  It doesn't harm the kernel at all.  Another
60 example would be certain debug routines.
61
62 History:
63 --------------------------------
64 KMSGs have a long history tied to process management code.  The main issues were
65 related to which KMSG functions return and which ones mess with local state (like
66 clobbering cur_ctx or the owning_proc).  Returning was a big deal because you
67 can't just arbitrarily abandon a kernel context (locks or refcnts could be held,
68 etc).  This is why immediates must return.  Likewise, there are certain
69 invariants about what a core is doing that shouldn't be changed by an IRQ
70 handler (which is what an immed message really is).  See all the old proc
71 management commits if you want more info (check for changes to __startcore).
72
73 Other Uses:
74 --------------------------------
75 Kernel messages will also be the basis for the alarm system.  All it is is
76 expressing work that needs to be done.  That being said, the k_msg struct will
77 probably receive a timestamp field, among other things.  Routine messages also
78 will replace the old workqueue, which hasn't really been used in 40 months or
79 so.
80
81 Blocking:
82 --------------------------------
83 If a routine kernel message blocks (or has a chance to block), it must
84 smp_idle() at the end.  If it were to return to PRKM(), it could be on a new
85 core, due to kthread migration.  We might have a way to enforce this later.
86
87 To Return or Not:
88 --------------------------------
89 Routine k_msgs do not have to return.  Immediate messages must.  The distinction
90 is in how they are sent (send_kernel_message() will take a flag), so be careful.
91
92 To retain some sort of sanity, the functions that do not return must adhere to
93 some rules.  At some point they need to end in a place where they check routine
94 messages or enable interrupts.  Simply calling smp_idle() will do this.  The
95 idea behind this is that routine messages will get processed once the kernel is
96 able to (at a convenient place). 
97
98 Missing Routine Messages:
99 --------------------------------
100 It's important that the kernel always checks for routine messages before leaving
101 the kernel, either to halt the core or to pop into userspace.  There is a race
102 involved with messages getting posted after we check the list, but before we
103 pop/halt.  In that time, we send an IPI.  This IPI will force us back into the
104 kernel at some point in the code before process_routine_kmsg(), thus keeping us
105 from missing the RKM.
106
107 In the future, if we know the kernel code on a particular core is not attempting
108 to halt/pop, then we could avoid sending this IPI.  This is the essence of the
109 optimization in send_kernel_message() where we don't IPI ourselves.  A more
110 formal/thorough way to do this would be useful, both to avoid bugs and to
111 improve cross-core KMSG performance.
112
113 IRQ Trickiness:
114 --------------------------------
115 You cannot enable interrupts in the handle_kmsg_ipi() handler, either in the
116 code or in any immediate kmsg.  Since we send the EOI before running the handler
117 (on x86), another IPI could cause us to reenter the handler, which would spin on
118 the lock the previous context is holding (nested IRQ stacks).  Using irqsave
119 locks is not sufficient, since they assume IRQs are not turned on in the middle
120 of their operation (such as in the body of an immediate kmsg).
121
122 Other Notes:
123 --------------------------------
124 Unproven hunch, but the main performance bottleneck with multiple senders and
125 receivers of k_msgs will be the slab allocator.  We use the slab so we can
126 dynamically create the k_msgs (can pass them around easily, delay with them
127 easily (alarms), and most importantly we can't deadlock by running out of room
128 in a static buffer).
129
130 Architecture Dependence:
131 --------------------------------
132 Some details will differ, based on architectural support.  For instance,
133 immediate messages can be implemented with true active messages.  Other systems
134 with maskable IPI vectors can use a different IPI for routine messages, and that
135 interrupt can get masked whenever we enter the kernel (note, that means making
136 every trap gate an interrupt gate), and we unmask that interrupt when we want to
137 process routine messages.
138
139 However, given the main part of kmsgs is arch-independent, I've consolidated all
140 of it in one location until we need to have separate parts of the implementation.