Merge remote-tracking branch 'origin/clustered' into aks_dev_clus
[projects/modsched/linux.git] / include / linux / pcn_kmsg.h
1 #ifndef __LINUX_PCN_KMSG_H
2 #define __LINUX_PCN_KMSG_H
3 /*
4  * Header file for Popcorn inter-kernel messaging layer
5  *
6  * (C) Ben Shelton <beshelto@vt.edu> 2013
7  */
8
9 #include <linux/list.h>
10 #include <linux/multikernel.h>
11 #include <linux/types.h>
12
13 /* LOCKING / SYNCHRONIZATION */
14 #define pcn_cpu_relax() __asm__ ("pause":::"memory")
15 //#define pcn_barrier() __asm__ __volatile__("":::"memory")
16 #define pcn_barrier() mb()
17
18 /* BOOKKEEPING */
19
20 #define POPCORN_MAX_MCAST_CHANNELS 32
21
22 struct pcn_kmsg_mcast_wininfo {
23         volatile unsigned char lock;
24         unsigned char owner_cpu;
25         volatile unsigned char is_closing;
26         unsigned long mask;
27         unsigned int num_members;
28         unsigned long phys_addr;
29 };
30
31 struct pcn_kmsg_rkinfo {
32         unsigned long phys_addr[POPCORN_MAX_CPUS];
33         struct pcn_kmsg_mcast_wininfo mcast_wininfo[POPCORN_MAX_MCAST_CHANNELS];
34 };
35
36 enum pcn_kmsg_wq_ops {
37         PCN_KMSG_WQ_OP_MAP_MSG_WIN,
38         PCN_KMSG_WQ_OP_UNMAP_MSG_WIN,
39         PCN_KMSG_WQ_OP_MAP_MCAST_WIN,
40         PCN_KMSG_WQ_OP_UNMAP_MCAST_WIN
41 };
42
43 typedef unsigned long pcn_kmsg_mcast_id;
44
45 typedef struct {
46         struct work_struct work;
47         enum pcn_kmsg_wq_ops op;
48         int from_cpu;
49         int cpu_to_add;
50         pcn_kmsg_mcast_id id_to_join;
51 } pcn_kmsg_work_t;
52
53 /* MESSAGING */
54
55 /* Enum for message types.  Modules should add types after
56    PCN_KMSG_END. */
57 enum pcn_kmsg_type {
58         PCN_KMSG_TYPE_TEST,
59         PCN_KMSG_TYPE_TEST_LONG,
60         PCN_KMSG_TYPE_CHECKIN,
61         PCN_KMSG_TYPE_MCAST,
62         PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_REQUEST,
63         PCN_KMSG_TYPE_REMOTE_PROC_CPUINFO_RESPONSE,
64         PCN_KMSG_TYPE_REMOTE_PROC_MEMINFO_REQUEST,
65         PCN_KMSG_TYPE_REMOTE_PROC_MEMINFO_RESPONSE,
66         PCN_KMSG_TYPE_REMOTE_PROC_STAT_REQUEST,
67         PCN_KMSG_TYPE_REMOTE_PROC_STAT_RESPONSE,
68         PCN_KMSG_TYPE_REMOTE_PID_REQUEST,
69         PCN_KMSG_TYPE_REMOTE_PID_RESPONSE,
70         PCN_KMSG_TYPE_REMOTE_PID_STAT_REQUEST,
71         PCN_KMSG_TYPE_REMOTE_PID_STAT_RESPONSE,
72         PCN_KMSG_TYPE_REMOTE_PID_CPUSET_REQUEST,
73         PCN_KMSG_TYPE_REMOTE_PID_CPUSET_RESPONSE,
74         PCN_KMSG_TYPE_REMOTE_SENDSIG_REQUEST,
75         PCN_KMSG_TYPE_REMOTE_SENDSIG_RESPONSE,
76         PCN_KMSG_TYPE_REMOTE_SENDSIGPROCMASK_REQUEST,
77         PCN_KMSG_TYPE_REMOTE_SENDSIGPROCMASK_RESPONSE,
78         PCN_KMSG_TYPE_REMOTE_SENDSIGACTION_REQUEST,
79         PCN_KMSG_TYPE_REMOTE_SENDSIGACTION_RESPONSE,
80         PCN_KMSG_TYPE_REMOTE_IPC_SEMGET_REQUEST,
81         PCN_KMSG_TYPE_REMOTE_IPC_SEMGET_RESPONSE,
82         PCN_KMSG_TYPE_REMOTE_IPC_SEMCTL_REQUEST,
83         PCN_KMSG_TYPE_REMOTE_IPC_SEMCTL_RESPONSE,
84         PCN_KMSG_TYPE_REMOTE_IPC_SHMGET_REQUEST,
85         PCN_KMSG_TYPE_REMOTE_IPC_SHMGET_RESPONSE,
86         PCN_KMSG_TYPE_REMOTE_IPC_SHMAT_REQUEST,
87         PCN_KMSG_TYPE_REMOTE_IPC_SHMAT_RESPONSE,
88         PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_REQUEST,
89         PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_WAKE_RESPONSE,
90         PCN_KMSG_TYPE_REMOTE_PFN_REQUEST,
91         PCN_KMSG_TYPE_REMOTE_PFN_RESPONSE,
92         PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_REQUEST,
93         PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_KEY_RESPONSE,
94         PCN_KMSG_TYPE_REMOTE_IPC_FUTEX_TOKEN_REQUEST,
95     PCN_KMSG_TYPE_PROC_SRV_CLONE_REQUEST,
96     PCN_KMSG_TYPE_PROC_SRV_CREATE_PROCESS_PAIRING,
97     PCN_KMSG_TYPE_PROC_SRV_EXIT_PROCESS,
98     PCN_KMSG_TYPE_PROC_SRV_EXIT_GROUP,
99     PCN_KMSG_TYPE_PROC_SRV_EXIT_SHADOW,
100     PCN_KMSG_TYPE_PROC_SRV_VMA_TRANSFER,
101     PCN_KMSG_TYPE_PROC_SRV_PTE_TRANSFER,
102     PCN_KMSG_TYPE_PROC_SRV_MAPPING_REQUEST,
103     PCN_KMSG_TYPE_PROC_SRV_MAPPING_RESPONSE,
104     PCN_KMSG_TYPE_PROC_SRV_INVALID_DATA,
105     PCN_KMSG_TYPE_PROC_SRV_ACK_DATA,
106     PCN_KMSG_TYPE_PROC_SRV_THREAD_COUNT_REQUEST,
107     PCN_KMSG_TYPE_PROC_SRV_THREAD_COUNT_RESPONSE,
108     PCN_KMSG_TYPE_PROC_SRV_THREAD_GROUP_EXITED_NOTIFICATION,
109         PCN_KMSG_TYPE_PROC_SRV_MAPPING_RESPONSE_NONPRESENT,
110         PCN_KMSG_TYPE_PROC_SRV_MPROTECT_RESPONSE,
111         PCN_KMSG_TYPE_PROC_SRV_MPROTECT_REQUEST,
112         PCN_KMSG_TYPE_PROC_SRV_MUNMAP_REQUEST,
113         PCN_KMSG_TYPE_PROC_SRV_MUNMAP_RESPONSE,
114     PCN_KMSG_TYPE_PROC_SRV_BACK_MIGRATION,
115         PCN_KMSG_TYPE_PCN_PERF_START_MESSAGE,
116         PCN_KMSG_TYPE_PCN_PERF_END_MESSAGE,
117         PCN_KMSG_TYPE_PCN_PERF_CONTEXT_MESSAGE,
118         PCN_KMSG_TYPE_PCN_PERF_ENTRY_MESSAGE,
119         PCN_KMSG_TYPE_PCN_PERF_END_ACK_MESSAGE,
120     PCN_KMSG_TYPE_START_TEST,
121     PCN_KMSG_TYPE_REQUEST_TEST,
122     PCN_KMSG_TYPE_ANSWER_TEST,
123         PCN_KMSG_TYPE_MCAST_CLOSE,
124         PCN_KMSG_TYPE_SHMTUN,
125         PCN_KMSG_TYPE_MAX
126 };
127
128 /* Enum for message priority. */
129 enum pcn_kmsg_prio {
130         PCN_KMSG_PRIO_HIGH,
131         PCN_KMSG_PRIO_NORMAL
132 };
133
134 #define __READY_SIZE 1
135 #define LG_SEQNUM_SIZE  (8 - __READY_SIZE)
136
137 /* Message header */
138 struct pcn_kmsg_hdr {
139         unsigned int from_cpu   :8; // b0
140         
141         enum pcn_kmsg_type type :8; // b1
142         
143         enum pcn_kmsg_prio prio :5; // b2
144         unsigned int is_lg_msg  :1;
145         unsigned int lg_start   :1;
146         unsigned int lg_end     :1;
147
148         unsigned long long_number; // b3 .. b10
149         
150         unsigned int lg_seqnum  :LG_SEQNUM_SIZE; // b11
151         unsigned int __ready    :__READY_SIZE;
152 }__attribute__((packed));
153
154 //#if ( &((struct pcn_kmsg_hdr*)0)->ready != 12 )
155 //# error "ready is not the last byte of the struct"
156 //#endif
157
158 // TODO cache size can be retrieved by the compiler, put it here
159 #define CACHE_LINE_SIZE 64
160 //#define PCN_KMSG_PAYLOAD_SIZE 60
161 #define PCN_KMSG_PAYLOAD_SIZE (CACHE_LINE_SIZE - sizeof(struct pcn_kmsg_hdr))
162
163 #define MAX_CHUNKS ((1 << LG_SEQNUM_SIZE) -1)
164 #define PCN_KMSG_LONG_PAYLOAD_SIZE (MAX_CHUNKS*PCN_KMSG_PAYLOAD_SIZE)
165
166 /* The actual messages.  The expectation is that developers will create their
167    own message structs with the payload replaced with their own fields, and then
168    cast them to a struct pcn_kmsg_message.  See the checkin message below for
169    an example of how to do this. */
170
171 /* Struct for the actual messages.  Note that hdr and payload are flipped
172    when this actually goes out, so the receiver can poll on the ready bit
173    in the header. */
174 struct pcn_kmsg_message {
175         struct pcn_kmsg_hdr hdr;
176         unsigned char payload[PCN_KMSG_PAYLOAD_SIZE];
177 }__attribute__((packed)) __attribute__((aligned(CACHE_LINE_SIZE)));
178
179 struct pcn_kmsg_reverse_message {
180         unsigned char payload[PCN_KMSG_PAYLOAD_SIZE];
181         struct pcn_kmsg_hdr hdr;
182         volatile unsigned long last_ticket;
183         volatile unsigned char ready;
184 }__attribute__((packed)) __attribute__((aligned(CACHE_LINE_SIZE)));
185
186 /* Struct for sending long messages (>60 bytes payload) */
187 struct pcn_kmsg_long_message {
188         struct pcn_kmsg_hdr hdr;
189         unsigned char payload[PCN_KMSG_LONG_PAYLOAD_SIZE];
190 }__attribute__((packed));
191
192 /* List entry to copy message into and pass around in receiving kernel */
193 struct pcn_kmsg_container {
194         struct list_head list;
195         struct pcn_kmsg_message msg;
196 }__attribute__((packed));
197
198
199
200 /* TYPES OF MESSAGES */
201
202 /* Message struct for guest kernels to check in with each other. */
203 struct pcn_kmsg_checkin_message {
204         struct pcn_kmsg_hdr hdr;
205         unsigned long window_phys_addr;
206         unsigned char cpu_to_add;
207         char pad[51];
208 }__attribute__((packed)) __attribute__((aligned(CACHE_LINE_SIZE)));
209
210
211
212 /* WINDOW / BUFFERING */
213
214 #define PCN_KMSG_RBUF_SIZE 64
215
216 struct pcn_kmsg_window {
217         volatile unsigned long head;
218         volatile unsigned long tail;
219         volatile unsigned char int_enabled;
220         volatile struct pcn_kmsg_reverse_message buffer[PCN_KMSG_RBUF_SIZE];
221         volatile int second_buffer[PCN_KMSG_RBUF_SIZE];
222 }__attribute__((packed));
223
224 /* Typedef for function pointer to callback functions */
225 typedef int (*pcn_kmsg_cbftn)(struct pcn_kmsg_message *);
226
227 /* FUNCTIONS */
228
229 /* SETUP */
230
231 /* Register a callback function to handle a new message type.  Intended to
232    be called when a kernel module is loaded. */
233 int pcn_kmsg_register_callback(enum pcn_kmsg_type type,
234                                pcn_kmsg_cbftn callback);
235
236 /* Unregister a callback function for a message type.  Intended to
237    be called when a kernel module is unloaded. */
238 int pcn_kmsg_unregister_callback(enum pcn_kmsg_type type);
239
240 /* MESSAGING */
241
242 /* Send a message to the specified destination CPU. */
243 int pcn_kmsg_send(unsigned int dest_cpu, struct pcn_kmsg_message *msg);
244
245 /* Send a long message to the specified destination CPU. */
246 int pcn_kmsg_send_long(unsigned int dest_cpu,
247                        struct pcn_kmsg_long_message *lmsg,
248                        unsigned int payload_size);
249
250 /* Free a received message (called at the end of the callback function) */
251 inline void pcn_kmsg_free_msg(void *msg);
252
253 /* MULTICAST GROUPS */
254
255 /* Enum for mcast message type. */
256 enum pcn_kmsg_mcast_type {
257         PCN_KMSG_MCAST_OPEN,
258         PCN_KMSG_MCAST_ADD_MEMBERS,
259         PCN_KMSG_MCAST_DEL_MEMBERS,
260         PCN_KMSG_MCAST_CLOSE,
261         PCN_KMSG_MCAST_MAX
262 };
263
264 /* Message struct for guest kernels to check in with each other. */
265 struct pcn_kmsg_mcast_message {
266         struct pcn_kmsg_hdr hdr;
267         enum pcn_kmsg_mcast_type type :32;
268         pcn_kmsg_mcast_id id;
269         unsigned long mask;
270         unsigned int num_members;
271         unsigned long window_phys_addr;
272         char pad[28];
273 }__attribute__((packed)) __attribute__((aligned(CACHE_LINE_SIZE)));
274
275 struct pcn_kmsg_mcast_window {
276         volatile unsigned long head;
277         volatile unsigned long tail;
278         atomic_t read_counter[PCN_KMSG_RBUF_SIZE];
279         volatile struct pcn_kmsg_reverse_message buffer[PCN_KMSG_RBUF_SIZE];
280 }__attribute__((packed));
281
282 struct pcn_kmsg_mcast_local {
283         struct pcn_kmsg_mcast_window * mcastvirt;
284         unsigned long local_tail;
285 };
286
287 /* Open a multicast group containing the CPUs specified in the mask. */
288 int pcn_kmsg_mcast_open(pcn_kmsg_mcast_id *id, unsigned long mask);
289
290 /* Add new members to a multicast group. */
291 int pcn_kmsg_mcast_add_members(pcn_kmsg_mcast_id id, unsigned long mask);
292
293 /* Remove existing members from a multicast group. */
294 int pcn_kmsg_mcast_delete_members(pcn_kmsg_mcast_id id, unsigned long mask);
295
296 /* Close a multicast group. */
297 int pcn_kmsg_mcast_close(pcn_kmsg_mcast_id id);
298
299 /* Send a message to the specified multicast group. */
300 int pcn_kmsg_mcast_send(pcn_kmsg_mcast_id id, struct pcn_kmsg_message *msg);
301
302 /* Send a long message to the specified multicast group. */
303 int pcn_kmsg_mcast_send_long(pcn_kmsg_mcast_id id,
304                              struct pcn_kmsg_long_message *msg,
305                              unsigned int payload_size);
306
307 #endif /* __LINUX_PCN_KMSG_H */