1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57#include "default_pager_internal.h"
58#include <default_pager/default_pager_object_server.h>
59#include <kern/host.h>
60#include <kern/ledger.h>
61#include <mach/host_info.h>
62#include <mach/host_priv.h>
63#include <mach/vm_map.h>
64#include <ipc/ipc_space.h>
65#include <vm/vm_kern.h>
66#include <vm/vm_map.h>
67#include <vm/vm_protos.h>
68
69char my_name[] = "(default pager): ";
70
71#if DEFAULT_PAGER_DEBUG
72int debug_mask = 0;
73#endif
74
75
76
77
78
79
80vm_size_t cthread_stack_size = 16 *1024;
81extern vm_size_t cthread_wait_stack_size;
82
83unsigned long long vm_page_mask;
84int vm_page_shift;
85
86int norma_mk;
87
88boolean_t verbose;
89
90
91mutex_t dpt_lock;
92default_pager_thread_t **dpt_array;
93
94memory_object_default_t default_pager_object;
95
96MACH_PORT_FACE default_pager_default_set;
97MACH_PORT_FACE default_pager_internal_set;
98MACH_PORT_FACE default_pager_external_set;
99
100#define DEFAULT_PAGER_INTERNAL_COUNT (4)
101
102
103
104#define DEFAULT_PAGER_EXTERNAL_COUNT (2)
105
106int default_pager_internal_count = DEFAULT_PAGER_INTERNAL_COUNT;
107
108int default_pager_external_count = DEFAULT_PAGER_EXTERNAL_COUNT;
109
110
111
112
113
114boolean_t default_pager_notify_server(mach_msg_header_t *,
115 mach_msg_header_t *);
116boolean_t default_pager_demux_object(mach_msg_header_t *,
117 mach_msg_header_t *);
118boolean_t default_pager_demux_default(mach_msg_header_t *,
119 mach_msg_header_t *);
120default_pager_thread_t *start_default_pager_thread(int, boolean_t);
121void default_pager(void);
122void default_pager_thread(void *);
123void default_pager_initialize(void);
124boolean_t dp_parse_argument(char *);
125unsigned int d_to_i(char *);
126boolean_t strprefix(register const char *s1, register const char *s2);
127
128
129extern int vstruct_def_clshift;
130
131
132
133
134
135void
136default_pager(void)
137{
138 int i, id;
139 __unused static char here[] = "default_pager";
140 default_pager_thread_t dpt;
141 kern_return_t kr;
142
143
144
145
146
147
148 i = default_pager_internal_count + default_pager_external_count + 1;
149 dpt_array = (default_pager_thread_t **)
150 kalloc(i * sizeof(default_pager_thread_t *));
151 memset(dpt_array, 0, i * sizeof(default_pager_thread_t *));
152
153
154 id = 0;
155 dpt.dpt_buffer = 0;
156 dpt.dpt_internal = FALSE;
157 dpt.dpt_initialized_p = TRUE;
158 dpt_array[0] = &dpt;
159
160
161
162
163
164
165 for (i = 0; i < default_pager_internal_count; i++) {
166 dpt_array[id] = (default_pager_thread_t *)
167 kalloc(sizeof (default_pager_thread_t));
168 if (dpt_array[id] == NULL)
169 Panic("alloc pager thread");
170 kr = vm_allocate(kernel_map, &((dpt_array[id])->dpt_buffer),
171 vm_page_size << vstruct_def_clshift, VM_FLAGS_ANYWHERE);
172 if (kr != KERN_SUCCESS)
173 Panic("alloc thread buffer");
174 kr = vm_map_wire(kernel_map, (dpt_array[id])->dpt_buffer,
175 ((dpt_array[id])->dpt_buffer)
176 +(vm_page_size << vstruct_def_clshift),
177 VM_PROT_DEFAULT,
178 FALSE);
179 if (kr != KERN_SUCCESS)
180 Panic("wire thread buffer");
181 (dpt_array[id])->dpt_internal = TRUE;
182 (dpt_array[id])->dpt_initialized_p = TRUE;
183 (dpt_array[id])->checked_out = FALSE;
184 id++;
185 }
186 DPT_LOCK_INIT(dpt_lock);
187}
188
189
190
191
192
193
194
195int
196local_log2(
197 unsigned int n)
198{
199 register int i = 0;
200
201 if(n == 0) return 0;
202
203 while ((n & 1) == 0) {
204 i++;
205 n >>= 1;
206 }
207 return i;
208}
209
210
211
212
213
214
215
216unsigned int
217d_to_i(char * arg)
218{
219 unsigned int rval = 0;
220 char ch;
221
222 while ((ch = *arg++) && ch >= '0' && ch <= '9') {
223 rval *= 10;
224 rval += ch - '0';
225 }
226 return(rval);
227}
228
229
230
231
232
233
234
235
236
237boolean_t dp_parse_argument(char *av)
238{
239 char *rhs = av;
240 __unused static char here[] = "dp_parse_argument";
241
242
243
244 if (av[0] == '-' && av[1] == 'v' && av[2] == 0) {
245 verbose = TRUE ;
246 return TRUE;
247 }
248
249
250
251
252
253 while (*rhs && *rhs != '=')
254 rhs++;
255 if (*rhs && *++rhs) {
256
257 if (strprefix(av,"cl")) {
258 if (!bs_set_default_clsize(d_to_i(rhs)))
259 dprintf(("Bad argument (%s) - ignored\n", av));
260 return(TRUE);
261 }
262
263
264
265
266 }
267 return(FALSE);
268}
269
270int
271start_def_pager( __unused char *bs_device )
272{
273
274
275
276
277
278
279
280
281 __unused static char here[] = "main";
282
283
284
285
286
287
288
289
290
291
292
293
294#if NORMA_VM
295 norma_mk = 1;
296#else
297 norma_mk = 0;
298#endif
299
300
301
302 default_pager_initialize();
303 default_pager();
304
305
306 default_pager_backing_store_monitor_callout =
307 thread_call_allocate(default_pager_backing_store_monitor, NULL);
308 if (!default_pager_backing_store_monitor_callout)
309 panic("can't start backing store monitor thread");
310 thread_call_enter(default_pager_backing_store_monitor_callout);
311}
312
313
314
315
316boolean_t
317strprefix(register const char *s1, register const char *s2)
318{
319 register int c;
320
321 while ((c = *s2++) != '\0') {
322 if (c != *s1++)
323 return (FALSE);
324 }
325 return (TRUE);
326}
327
328
329kern_return_t
330default_pager_info(
331 memory_object_default_t pager,
332 default_pager_info_t *infop)
333{
334 vm_size_t pages_total, pages_free;
335
336 if (pager != default_pager_object)
337 return KERN_INVALID_ARGUMENT;
338
339 bs_global_info(&pages_total, &pages_free);
340
341 infop->dpi_total_space = ptoa_32(pages_total);
342 infop->dpi_free_space = ptoa_32(pages_free);
343 infop->dpi_page_size = vm_page_size;
344
345 return KERN_SUCCESS;
346}
347
348
349kern_return_t
350default_pager_info_64(
351 memory_object_default_t pager,
352 default_pager_info_64_t *infop)
353{
354 vm_size_t pages_total, pages_free;
355
356 if (pager != default_pager_object)
357 return KERN_INVALID_ARGUMENT;
358
359 bs_global_info(&pages_total, &pages_free);
360
361 infop->dpi_total_space = ptoa_64(pages_total);
362 infop->dpi_free_space = ptoa_64(pages_free);
363 infop->dpi_page_size = vm_page_size;
364 infop->dpi_flags = 0;
365 if (dp_encryption_inited && dp_encryption == TRUE) {
366 infop->dpi_flags |= DPI_ENCRYPTED;
367 }
368
369 return KERN_SUCCESS;
370}
371
372
373void
374default_pager_initialize()
375{
376 kern_return_t kr;
377 __unused static char here[] = "default_pager_initialize";
378
379
380
381
382
383 vm_page_mask = vm_page_size - 1;
384 vm_page_shift = local_log2(vm_page_size);
385
386
387
388
389 vstruct_zone = zinit(sizeof(struct vstruct),
390 10000 * sizeof(struct vstruct),
391 8192, "vstruct zone");
392 VSL_LOCK_INIT();
393 queue_init(&vstruct_list.vsl_queue);
394 vstruct_list.vsl_count = 0;
395
396 VSTATS_LOCK_INIT(&global_stats.gs_lock);
397
398 bs_initialize();
399
400
401
402
403 default_pager_object = ipc_port_alloc_kernel();
404
405
406
407
408
409#ifdef USER_PAGER
410 if ((kr = netname_check_in(name_server_port, "UserPager",
411 default_pager_self,
412 default_pager_object))
413 != KERN_SUCCESS) {
414 dprintf(("netname_check_in returned 0x%x\n", kr));
415 exit(1);
416 }
417#else
418 {
419 int clsize;
420 memory_object_default_t dmm;
421
422 dmm = default_pager_object;
423 clsize = (vm_page_size << vstruct_def_clshift);
424 kr = host_default_memory_manager(host_priv_self(), &dmm, clsize);
425 if ((kr != KERN_SUCCESS) ||
426 (dmm != MEMORY_OBJECT_DEFAULT_NULL))
427 Panic("default memory manager");
428
429 }
430#endif
431
432
433}
434
435