Deleted Added
full compact
vm_glue.c (15534) vm_glue.c (15809)
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 45 unchanged lines hidden (view full) ---

54 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
55 * School of Computer Science
56 * Carnegie Mellon University
57 * Pittsburgh PA 15213-3890
58 *
59 * any improvements or extensions that they make and grant Carnegie the
60 * rights to redistribute these changes.
61 *
1/*
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * The Mach Operating System project at Carnegie-Mellon University.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 45 unchanged lines hidden (view full) ---

54 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
55 * School of Computer Science
56 * Carnegie Mellon University
57 * Pittsburgh PA 15213-3890
58 *
59 * any improvements or extensions that they make and grant Carnegie the
60 * rights to redistribute these changes.
61 *
62 * $Id: vm_glue.c,v 1.47 1996/04/09 04:36:58 dyson Exp $
62 * $Id: vm_glue.c,v 1.48 1996/05/02 09:34:51 phk Exp $
63 */
64
65#include "opt_ddb.h"
66
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/proc.h>
70#include <sys/resourcevar.h>

--- 120 unchanged lines hidden (view full) ---

191 * after cpu_fork returns in the child process. We do nothing here
192 * after cpu_fork returns.
193 */
194int
195vm_fork(p1, p2)
196 register struct proc *p1, *p2;
197{
198 register struct user *up;
63 */
64
65#include "opt_ddb.h"
66
67#include <sys/param.h>
68#include <sys/systm.h>
69#include <sys/proc.h>
70#include <sys/resourcevar.h>

--- 120 unchanged lines hidden (view full) ---

191 * after cpu_fork returns in the child process. We do nothing here
192 * after cpu_fork returns.
193 */
194int
195vm_fork(p1, p2)
196 register struct proc *p1, *p2;
197{
198 register struct user *up;
199 vm_offset_t addr, ptaddr, ptpa;
200 int error, i;
199 int error, i;
201 vm_map_t map;
202 pmap_t pvp;
200 pmap_t pvp;
203 vm_page_t stkm;
201 vm_object_t upobj;
204
205 while ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min) {
206 VM_WAIT;
207 }
208
202
203 while ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_free_min) {
204 VM_WAIT;
205 }
206
207#if 0
209 /*
210 * avoid copying any of the parent's pagetables or other per-process
211 * objects that reside in the map by marking all of them
212 * non-inheritable
213 */
214 (void) vm_map_inherit(&p1->p_vmspace->vm_map,
215 UPT_MIN_ADDRESS - UPAGES * PAGE_SIZE, VM_MAX_ADDRESS, VM_INHERIT_NONE);
208 /*
209 * avoid copying any of the parent's pagetables or other per-process
210 * objects that reside in the map by marking all of them
211 * non-inheritable
212 */
213 (void) vm_map_inherit(&p1->p_vmspace->vm_map,
214 UPT_MIN_ADDRESS - UPAGES * PAGE_SIZE, VM_MAX_ADDRESS, VM_INHERIT_NONE);
215#endif
216 p2->p_vmspace = vmspace_fork(p1->p_vmspace);
217
218 if (p1->p_vmspace->vm_shm)
219 shmfork(p1, p2);
220
221 /*
222 * Allocate a wired-down (for now) pcb and kernel stack for the
223 * process
224 */
225
216 p2->p_vmspace = vmspace_fork(p1->p_vmspace);
217
218 if (p1->p_vmspace->vm_shm)
219 shmfork(p1, p2);
220
221 /*
222 * Allocate a wired-down (for now) pcb and kernel stack for the
223 * process
224 */
225
226 addr = (vm_offset_t) kstack;
227
228 map = &p2->p_vmspace->vm_map;
229 pvp = &p2->p_vmspace->vm_pmap;
230
231 /*
232 * allocate object for the upages
233 */
226 pvp = &p2->p_vmspace->vm_pmap;
227
228 /*
229 * allocate object for the upages
230 */
234 p2->p_vmspace->vm_upages_obj = vm_object_allocate( OBJT_DEFAULT,
231 p2->p_vmspace->vm_upages_obj = upobj = vm_object_allocate( OBJT_DEFAULT,
235 UPAGES);
236
232 UPAGES);
233
237 /*
238 * put upages into the address space
239 */
240 error = vm_map_find(map, p2->p_vmspace->vm_upages_obj, 0,
241 &addr, UPT_MIN_ADDRESS - addr, FALSE, VM_PROT_ALL,
242 VM_PROT_ALL, 0);
243 if (error != KERN_SUCCESS)
244 panic("vm_fork: vm_map_find (UPAGES) failed, addr=0x%x, error=%d", addr, error);
245
246 addr += UPAGES * PAGE_SIZE;
247 /* allocate space for page tables */
248 error = vm_map_find(map, NULL, 0, &addr, UPT_MAX_ADDRESS - addr, FALSE,
249 VM_PROT_ALL, VM_PROT_ALL, 0);
250 if (error != KERN_SUCCESS)
251 panic("vm_fork: vm_map_find (PTES) failed, addr=0x%x, error=%d", addr, error);
252
253 /* get a kernel virtual address for the UPAGES for this proc */
254 up = (struct user *) kmem_alloc_pageable(u_map, UPAGES * PAGE_SIZE);
255 if (up == NULL)
256 panic("vm_fork: u_map allocation failed");
257
234 /* get a kernel virtual address for the UPAGES for this proc */
235 up = (struct user *) kmem_alloc_pageable(u_map, UPAGES * PAGE_SIZE);
236 if (up == NULL)
237 panic("vm_fork: u_map allocation failed");
238
258 /*
259 * create a pagetable page for the UPAGES in the process address space
260 */
261 ptaddr = trunc_page((u_int) vtopte(kstack));
262 (void) vm_fault(map, ptaddr, VM_PROT_READ|VM_PROT_WRITE, FALSE);
263 ptpa = pmap_extract(pvp, ptaddr);
264 if (ptpa == 0) {
265 panic("vm_fork: no pte for UPAGES");
266 }
267
268 /*
269 * hold the page table page for the kernel stack, and fault them in
270 */
271 stkm = PHYS_TO_VM_PAGE(ptpa);
272 vm_page_hold(stkm);
273
274 for(i=0;i<UPAGES;i++) {
275 vm_page_t m;
276
277 /*
278 * Get a kernel stack page
279 */
239 for(i=0;i<UPAGES;i++) {
240 vm_page_t m;
241
242 /*
243 * Get a kernel stack page
244 */
280 while ((m = vm_page_alloc(p2->p_vmspace->vm_upages_obj,
245 while ((m = vm_page_alloc(upobj,
281 i, VM_ALLOC_NORMAL)) == NULL) {
282 VM_WAIT;
283 }
284
285 /*
286 * Wire the page
287 */
288 vm_page_wire(m);
246 i, VM_ALLOC_NORMAL)) == NULL) {
247 VM_WAIT;
248 }
249
250 /*
251 * Wire the page
252 */
253 vm_page_wire(m);
289 m->flags &= ~PG_BUSY;
254 PAGE_WAKEUP(m);
290
291 /*
292 * Enter the page into both the kernel and the process
293 * address space.
294 */
295 pmap_enter( pvp, (vm_offset_t) kstack + i * PAGE_SIZE,
255
256 /*
257 * Enter the page into both the kernel and the process
258 * address space.
259 */
260 pmap_enter( pvp, (vm_offset_t) kstack + i * PAGE_SIZE,
296 VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, 1);
261 VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, TRUE);
297 pmap_kenter(((vm_offset_t) up) + i * PAGE_SIZE,
298 VM_PAGE_TO_PHYS(m));
299 m->flags &= ~PG_ZERO;
262 pmap_kenter(((vm_offset_t) up) + i * PAGE_SIZE,
263 VM_PAGE_TO_PHYS(m));
264 m->flags &= ~PG_ZERO;
265 m->flags |= PG_MAPPED;
300 m->valid = VM_PAGE_BITS_ALL;
301 }
266 m->valid = VM_PAGE_BITS_ALL;
267 }
302 /*
303 * The page table page for the kernel stack should be held in memory
304 * now.
305 */
306 vm_page_unhold(stkm);
307
308 p2->p_addr = up;
309
310 /*
311 * p_stats and p_sigacts currently point at fields in the user struct
312 * but not at &u, instead at p_addr. Copy p_sigacts and parts of
313 * p_stats; zero the rest of p_stats (statistics).
314 */

--- 51 unchanged lines hidden (view full) ---

366faultin(p)
367 struct proc *p;
368{
369 vm_offset_t i;
370 vm_offset_t ptaddr;
371 int s;
372
373 if ((p->p_flag & P_INMEM) == 0) {
268
269 p2->p_addr = up;
270
271 /*
272 * p_stats and p_sigacts currently point at fields in the user struct
273 * but not at &u, instead at p_addr. Copy p_sigacts and parts of
274 * p_stats; zero the rest of p_stats (statistics).
275 */

--- 51 unchanged lines hidden (view full) ---

327faultin(p)
328 struct proc *p;
329{
330 vm_offset_t i;
331 vm_offset_t ptaddr;
332 int s;
333
334 if ((p->p_flag & P_INMEM) == 0) {
374 vm_map_t map = &p->p_vmspace->vm_map;
375 pmap_t pmap = &p->p_vmspace->vm_pmap;
376 vm_page_t stkm, m;
335 pmap_t pmap = &p->p_vmspace->vm_pmap;
336 vm_page_t stkm, m;
377 vm_offset_t ptpa;
378 int error;
337 int error;
338 vm_object_t upobj = p->p_vmspace->vm_upages_obj;
379
380 ++p->p_lock;
381#if defined(SWAP_DEBUG)
382 printf("swapping in %d\n", p->p_pid);
383#endif
384
339
340 ++p->p_lock;
341#if defined(SWAP_DEBUG)
342 printf("swapping in %d\n", p->p_pid);
343#endif
344
385 ptaddr = trunc_page((u_int) vtopte(kstack));
386 (void) vm_fault(map, ptaddr, VM_PROT_READ|VM_PROT_WRITE, FALSE);
387 ptpa = pmap_extract(&p->p_vmspace->vm_pmap, ptaddr);
388 if (ptpa == 0) {
389 panic("vm_fork: no pte for UPAGES");
390 }
391 stkm = PHYS_TO_VM_PAGE(ptpa);
392 vm_page_hold(stkm);
393
394 for(i=0;i<UPAGES;i++) {
395 int s;
345 for(i=0;i<UPAGES;i++) {
346 int s;
396 s = splhigh();
397
347 s = splvm();
398retry:
348retry:
399 if ((m = vm_page_lookup(p->p_vmspace->vm_upages_obj, i)) == NULL) {
400 if ((m = vm_page_alloc(p->p_vmspace->vm_upages_obj, i, VM_ALLOC_NORMAL)) == NULL) {
349 if ((m = vm_page_lookup(upobj, i)) == NULL) {
350 if ((m = vm_page_alloc(upobj, i, VM_ALLOC_NORMAL)) == NULL) {
401 VM_WAIT;
402 goto retry;
403 }
404 } else {
405 if ((m->flags & PG_BUSY) || m->busy) {
406 m->flags |= PG_WANTED;
407 tsleep(m, PVM, "swinuw",0);
408 goto retry;
409 }
351 VM_WAIT;
352 goto retry;
353 }
354 } else {
355 if ((m->flags & PG_BUSY) || m->busy) {
356 m->flags |= PG_WANTED;
357 tsleep(m, PVM, "swinuw",0);
358 goto retry;
359 }
360 m->flags |= PG_BUSY;
410 }
411 vm_page_wire(m);
361 }
362 vm_page_wire(m);
412 if (m->valid == VM_PAGE_BITS_ALL)
413 m->flags &= ~PG_BUSY;
414 splx(s);
415
416 pmap_enter( pmap, (vm_offset_t) kstack + i * PAGE_SIZE,
417 VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, TRUE);
418 pmap_kenter(((vm_offset_t) p->p_addr) + i * PAGE_SIZE,
419 VM_PAGE_TO_PHYS(m));
420 if (m->valid != VM_PAGE_BITS_ALL) {
421 int rv;
363 splx(s);
364
365 pmap_enter( pmap, (vm_offset_t) kstack + i * PAGE_SIZE,
366 VM_PAGE_TO_PHYS(m), VM_PROT_READ|VM_PROT_WRITE, TRUE);
367 pmap_kenter(((vm_offset_t) p->p_addr) + i * PAGE_SIZE,
368 VM_PAGE_TO_PHYS(m));
369 if (m->valid != VM_PAGE_BITS_ALL) {
370 int rv;
422 rv = vm_pager_get_pages(p->p_vmspace->vm_upages_obj,
371 rv = vm_pager_get_pages(upobj,
423 &m, 1, 0);
424 if (rv != VM_PAGER_OK)
425 panic("faultin: cannot get upages for proc: %d\n", p->p_pid);
426 m->valid = VM_PAGE_BITS_ALL;
372 &m, 1, 0);
373 if (rv != VM_PAGER_OK)
374 panic("faultin: cannot get upages for proc: %d\n", p->p_pid);
375 m->valid = VM_PAGE_BITS_ALL;
427 m->flags &= ~PG_BUSY;
428 }
376 }
377 PAGE_WAKEUP(m);
378 m->flags |= PG_MAPPED;
429 }
379 }
430 vm_page_unhold(stkm);
431
432
433 s = splhigh();
434
435 if (p->p_stat == SRUN)
436 setrunqueue(p);
437
438 p->p_flag |= P_INMEM;
439

--- 82 unchanged lines hidden (view full) ---

522 struct proc *outp, *outp2;
523 int outpri, outpri2;
524 int didswap = 0;
525
526 outp = outp2 = NULL;
527 outpri = outpri2 = INT_MIN;
528retry:
529 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
380
381 s = splhigh();
382
383 if (p->p_stat == SRUN)
384 setrunqueue(p);
385
386 p->p_flag |= P_INMEM;
387

--- 82 unchanged lines hidden (view full) ---

470 struct proc *outp, *outp2;
471 int outpri, outpri2;
472 int didswap = 0;
473
474 outp = outp2 = NULL;
475 outpri = outpri2 = INT_MIN;
476retry:
477 for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) {
478 struct vmspace *vm;
530 if (!swappable(p))
531 continue;
479 if (!swappable(p))
480 continue;
481
482 vm = p->p_vmspace;
483
532 switch (p->p_stat) {
533 default:
534 continue;
535
536 case SSLEEP:
537 case SSTOP:
538 /*
539 * do not swapout a realtime process

--- 4 unchanged lines hidden (view full) ---

544 /*
545 * do not swapout a process waiting on a critical
546 * event of some kind
547 */
548 if (((p->p_priority & 0x7f) < PSOCK) ||
549 (p->p_slptime <= 4))
550 continue;
551
484 switch (p->p_stat) {
485 default:
486 continue;
487
488 case SSLEEP:
489 case SSTOP:
490 /*
491 * do not swapout a realtime process

--- 4 unchanged lines hidden (view full) ---

496 /*
497 * do not swapout a process waiting on a critical
498 * event of some kind
499 */
500 if (((p->p_priority & 0x7f) < PSOCK) ||
501 (p->p_slptime <= 4))
502 continue;
503
552 vm_map_reference(&p->p_vmspace->vm_map);
504 ++vm->vm_refcnt;
505 vm_map_reference(&vm->vm_map);
553 /*
554 * do not swapout a process that is waiting for VM
555 * datastructures there is a possible deadlock.
556 */
506 /*
507 * do not swapout a process that is waiting for VM
508 * datastructures there is a possible deadlock.
509 */
557 if (!lock_try_write(&p->p_vmspace->vm_map.lock)) {
558 vm_map_deallocate(&p->p_vmspace->vm_map);
510 if (!lock_try_write(&vm->vm_map.lock)) {
511 vm_map_deallocate(&vm->vm_map);
512 vmspace_free(vm);
559 continue;
560 }
513 continue;
514 }
561 vm_map_unlock(&p->p_vmspace->vm_map);
515 vm_map_unlock(&vm->vm_map);
562 /*
563 * If the process has been asleep for awhile and had
564 * most of its pages taken away already, swap it out.
565 */
566 swapout(p);
516 /*
517 * If the process has been asleep for awhile and had
518 * most of its pages taken away already, swap it out.
519 */
520 swapout(p);
567 vm_map_deallocate(&p->p_vmspace->vm_map);
521 vm_map_deallocate(&vm->vm_map);
522 vmspace_free(vm);
568 didswap++;
569 goto retry;
570 }
571 }
572 /*
573 * If we swapped something out, and another process needed memory,
574 * then wakeup the sched process.
575 */

--- 31 unchanged lines hidden (view full) ---

607 * let the upages be paged
608 */
609 for(i=0;i<UPAGES;i++) {
610 vm_page_t m;
611 if ((m = vm_page_lookup(p->p_vmspace->vm_upages_obj, i)) == NULL)
612 panic("swapout: upage already missing???");
613 m->dirty = VM_PAGE_BITS_ALL;
614 vm_page_unwire(m);
523 didswap++;
524 goto retry;
525 }
526 }
527 /*
528 * If we swapped something out, and another process needed memory,
529 * then wakeup the sched process.
530 */

--- 31 unchanged lines hidden (view full) ---

562 * let the upages be paged
563 */
564 for(i=0;i<UPAGES;i++) {
565 vm_page_t m;
566 if ((m = vm_page_lookup(p->p_vmspace->vm_upages_obj, i)) == NULL)
567 panic("swapout: upage already missing???");
568 m->dirty = VM_PAGE_BITS_ALL;
569 vm_page_unwire(m);
570 vm_page_deactivate(m);
615 pmap_kremove( (vm_offset_t) p->p_addr + PAGE_SIZE * i);
616 }
617 pmap_remove(pmap, (vm_offset_t) kstack,
618 (vm_offset_t) kstack + PAGE_SIZE * UPAGES);
619
620 p->p_flag &= ~P_SWAPPING;
621 p->p_swtime = 0;
622}

--- 34 unchanged lines hidden ---
571 pmap_kremove( (vm_offset_t) p->p_addr + PAGE_SIZE * i);
572 }
573 pmap_remove(pmap, (vm_offset_t) kstack,
574 (vm_offset_t) kstack + PAGE_SIZE * UPAGES);
575
576 p->p_flag &= ~P_SWAPPING;
577 p->p_swtime = 0;
578}

--- 34 unchanged lines hidden ---