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 --- |