Deleted Added
full compact
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 ---