vm_machdep.c (122821) | vm_machdep.c (122860) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * Copyright (c) 1989, 1990 William Jolitz 4 * Copyright (c) 1994 John Dyson 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer --- 27 unchanged lines hidden (view full) --- 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 40 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ 41 */ 42 43#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986 The Regents of the University of California. 3 * Copyright (c) 1989, 1990 William Jolitz 4 * Copyright (c) 1994 John Dyson 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * the Systems Programming Group of the University of Utah Computer --- 27 unchanged lines hidden (view full) --- 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 40 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ 41 */ 42 43#include <sys/cdefs.h> |
44__FBSDID("$FreeBSD: head/sys/i386/i386/vm_machdep.c 122821 2003-11-16 23:40:06Z alc $"); | 44__FBSDID("$FreeBSD: head/sys/i386/i386/vm_machdep.c 122860 2003-11-17 18:22:24Z alc $"); |
45 46#include "opt_npx.h" 47#ifdef PC98 48#include "opt_pc98.h" 49#endif 50#include "opt_reset.h" 51#include "opt_isa.h" 52#include "opt_kstack_pages.h" --- 42 unchanged lines hidden (view full) --- 95#ifdef SMP 96static void cpu_reset_proxy(void); 97static u_int cpu_reset_proxyid; 98static volatile u_int cpu_reset_proxy_active; 99#endif 100static void sf_buf_init(void *arg); 101SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) 102 | 45 46#include "opt_npx.h" 47#ifdef PC98 48#include "opt_pc98.h" 49#endif 50#include "opt_reset.h" 51#include "opt_isa.h" 52#include "opt_kstack_pages.h" --- 42 unchanged lines hidden (view full) --- 95#ifdef SMP 96static void cpu_reset_proxy(void); 97static u_int cpu_reset_proxyid; 98static volatile u_int cpu_reset_proxy_active; 99#endif 100static void sf_buf_init(void *arg); 101SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL) 102 |
103LIST_HEAD(sf_head, sf_buf); 104 |
|
103/* | 105/* |
104 * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the 105 * sf_freelist head with the sf_lock mutex. | 106 * A hash table of active sendfile(2) buffers |
106 */ | 107 */ |
107static struct { 108 SLIST_HEAD(, sf_buf) sf_head; 109 struct mtx sf_lock; 110} sf_freelist; | 108static struct sf_head *sf_buf_active; 109static u_long sf_buf_hashmask; |
111 | 110 |
111#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask) 112 113static struct sf_head sf_buf_freelist; |
|
112static u_int sf_buf_alloc_want; 113 | 114static u_int sf_buf_alloc_want; 115 |
116/* 117 * A lock used to synchronize access to the hash table and free list 118 */ 119static struct mtx sf_buf_lock; 120 |
|
114extern int _ucodesel, _udatasel; 115 116/* 117 * Finish a fork operation, with process p2 nearly set up. 118 * Copy and update the pcb, set up the stack so that the child 119 * ready to run and return to user mode. 120 */ 121void --- 448 unchanged lines hidden (view full) --- 570 */ 571static void 572sf_buf_init(void *arg) 573{ 574 struct sf_buf *sf_bufs; 575 vm_offset_t sf_base; 576 int i; 577 | 121extern int _ucodesel, _udatasel; 122 123/* 124 * Finish a fork operation, with process p2 nearly set up. 125 * Copy and update the pcb, set up the stack so that the child 126 * ready to run and return to user mode. 127 */ 128void --- 448 unchanged lines hidden (view full) --- 577 */ 578static void 579sf_buf_init(void *arg) 580{ 581 struct sf_buf *sf_bufs; 582 vm_offset_t sf_base; 583 int i; 584 |
578 mtx_init(&sf_freelist.sf_lock, "sf_bufs list lock", NULL, MTX_DEF); 579 SLIST_INIT(&sf_freelist.sf_head); | 585 sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask); 586 LIST_INIT(&sf_buf_freelist); |
580 sf_base = kmem_alloc_nofault(kernel_map, nsfbufs * PAGE_SIZE); 581 sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, 582 M_NOWAIT | M_ZERO); 583 for (i = 0; i < nsfbufs; i++) { 584 sf_bufs[i].kva = sf_base + i * PAGE_SIZE; | 587 sf_base = kmem_alloc_nofault(kernel_map, nsfbufs * PAGE_SIZE); 588 sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, 589 M_NOWAIT | M_ZERO); 590 for (i = 0; i < nsfbufs; i++) { 591 sf_bufs[i].kva = sf_base + i * PAGE_SIZE; |
585 SLIST_INSERT_HEAD(&sf_freelist.sf_head, &sf_bufs[i], free_list); | 592 LIST_INSERT_HEAD(&sf_buf_freelist, &sf_bufs[i], list_entry); |
586 } 587 sf_buf_alloc_want = 0; | 593 } 594 sf_buf_alloc_want = 0; |
595 mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF); |
|
588} 589 590/* 591 * Get an sf_buf from the freelist. Will block if none are available. 592 */ 593struct sf_buf * 594sf_buf_alloc(struct vm_page *m) 595{ | 596} 597 598/* 599 * Get an sf_buf from the freelist. Will block if none are available. 600 */ 601struct sf_buf * 602sf_buf_alloc(struct vm_page *m) 603{ |
604 struct sf_head *hash_list; |
|
596 struct sf_buf *sf; 597 int error; 598 | 605 struct sf_buf *sf; 606 int error; 607 |
599 mtx_lock(&sf_freelist.sf_lock); 600 while ((sf = SLIST_FIRST(&sf_freelist.sf_head)) == NULL) { | 608 hash_list = &sf_buf_active[SF_BUF_HASH(m)]; 609 mtx_lock(&sf_buf_lock); 610 LIST_FOREACH(sf, hash_list, list_entry) { 611 if (sf->m == m) { 612 sf->ref_count++; 613 goto done; 614 } 615 } 616 while ((sf = LIST_FIRST(&sf_buf_freelist)) == NULL) { |
601 sf_buf_alloc_want++; | 617 sf_buf_alloc_want++; |
602 error = msleep(&sf_freelist, &sf_freelist.sf_lock, PVM|PCATCH, | 618 error = msleep(&sf_buf_freelist, &sf_buf_lock, PVM|PCATCH, |
603 "sfbufa", 0); 604 sf_buf_alloc_want--; 605 606 /* 607 * If we got a signal, don't risk going back to sleep. 608 */ 609 if (error) | 619 "sfbufa", 0); 620 sf_buf_alloc_want--; 621 622 /* 623 * If we got a signal, don't risk going back to sleep. 624 */ 625 if (error) |
610 break; | 626 goto done; |
611 } | 627 } |
612 if (sf != NULL) { 613 SLIST_REMOVE_HEAD(&sf_freelist.sf_head, free_list); 614 sf->m = m; 615 pmap_qenter(sf->kva, &sf->m, 1); 616 } 617 mtx_unlock(&sf_freelist.sf_lock); | 628 LIST_REMOVE(sf, list_entry); 629 LIST_INSERT_HEAD(hash_list, sf, list_entry); 630 sf->ref_count = 1; 631 sf->m = m; 632 pmap_qenter(sf->kva, &sf->m, 1); 633done: 634 mtx_unlock(&sf_buf_lock); |
618 return (sf); 619} 620 621/* 622 * Detatch mapped page and release resources back to the system. 623 */ 624void 625sf_buf_free(void *addr, void *args) 626{ 627 struct sf_buf *sf; 628 struct vm_page *m; 629 630 sf = args; | 635 return (sf); 636} 637 638/* 639 * Detatch mapped page and release resources back to the system. 640 */ 641void 642sf_buf_free(void *addr, void *args) 643{ 644 struct sf_buf *sf; 645 struct vm_page *m; 646 647 sf = args; |
631 pmap_qremove((vm_offset_t)addr, 1); | 648 mtx_lock(&sf_buf_lock); |
632 m = sf->m; | 649 m = sf->m; |
650 sf->ref_count--; 651 if (sf->ref_count == 0) { 652 pmap_qremove((vm_offset_t)addr, 1); 653 sf->m = NULL; 654 LIST_REMOVE(sf, list_entry); 655 LIST_INSERT_HEAD(&sf_buf_freelist, sf, list_entry); 656 if (sf_buf_alloc_want > 0) 657 wakeup_one(&sf_buf_freelist); 658 } 659 mtx_unlock(&sf_buf_lock); 660 |
|
633 vm_page_lock_queues(); 634 vm_page_unwire(m, 0); 635 /* 636 * Check for the object going away on us. This can 637 * happen since we don't hold a reference to it. 638 * If so, we're responsible for freeing the page. 639 */ 640 if (m->wire_count == 0 && m->object == NULL) 641 vm_page_free(m); 642 vm_page_unlock_queues(); | 661 vm_page_lock_queues(); 662 vm_page_unwire(m, 0); 663 /* 664 * Check for the object going away on us. This can 665 * happen since we don't hold a reference to it. 666 * If so, we're responsible for freeing the page. 667 */ 668 if (m->wire_count == 0 && m->object == NULL) 669 vm_page_free(m); 670 vm_page_unlock_queues(); |
643 sf->m = NULL; 644 mtx_lock(&sf_freelist.sf_lock); 645 SLIST_INSERT_HEAD(&sf_freelist.sf_head, sf, free_list); 646 if (sf_buf_alloc_want > 0) 647 wakeup_one(&sf_freelist); 648 mtx_unlock(&sf_freelist.sf_lock); | |
649} 650 651/* 652 * Software interrupt handler for queued VM system processing. 653 */ 654void 655swi_vm(void *dummy) 656{ --- 29 unchanged lines hidden --- | 671} 672 673/* 674 * Software interrupt handler for queued VM system processing. 675 */ 676void 677swi_vm(void *dummy) 678{ --- 29 unchanged lines hidden --- |