Author: kib
Date: Sat Aug 29 21:53:08 2009
New Revision: 196648
URL: http://svn.freebsd.org/changeset/base/196648

Log:
  Reverse r196640 and r196644 for now.

Modified:
  head/sys/arm/arm/vm_machdep.c
  head/sys/kern/kern_fork.c
  head/sys/kern/kern_kthread.c
  head/sys/kern/kern_proc.c
  head/sys/kern/kern_thr.c
  head/sys/kern/kern_thread.c
  head/sys/sys/proc.h
  head/sys/vm/vm_extern.h
  head/sys/vm/vm_glue.c

Modified: head/sys/arm/arm/vm_machdep.c
==============================================================================
--- head/sys/arm/arm/vm_machdep.c       Sat Aug 29 19:49:17 2009        
(r196647)
+++ head/sys/arm/arm/vm_machdep.c       Sat Aug 29 21:53:08 2009        
(r196648)
@@ -119,6 +119,9 @@ cpu_fork(register struct thread *td1, re
 #ifdef __XSCALE__
 #ifndef CPU_XSCALE_CORE3
        pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE);
+       if (td2->td_altkstack)
+               pmap_use_minicache(td2->td_altkstack, td2->td_altkstack_pages *
+                   PAGE_SIZE);
 #endif
 #endif
        td2->td_pcb = pcb2;

Modified: head/sys/kern/kern_fork.c
==============================================================================
--- head/sys/kern/kern_fork.c   Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/kern/kern_fork.c   Sat Aug 29 21:53:08 2009        (r196648)
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_kdtrace.h"
 #include "opt_ktrace.h"
-#include "opt_kstack_pages.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -277,29 +276,25 @@ norfproc_fail:
 
        mem_charged = 0;
        vm2 = NULL;
-       if (pages == 0)
-               pages = KSTACK_PAGES;
        /* Allocate new proc. */
        newproc = uma_zalloc(proc_zone, M_WAITOK);
-       td2 = FIRST_THREAD_IN_PROC(newproc);
-       if (td2 == NULL) {
-               td2 = thread_alloc(pages);
+       if (TAILQ_EMPTY(&newproc->p_threads)) {
+               td2 = thread_alloc();
                if (td2 == NULL) {
                        error = ENOMEM;
                        goto fail1;
                }
                proc_linkup(newproc, td2);
-       } else {
-               if (td2->td_kstack == 0 || td2->td_kstack_pages != pages) {
-                       if (td2->td_kstack != 0)
-                               vm_thread_dispose(td2);
-                       if (!thread_alloc_stack(td2, pages)) {
-                               error = ENOMEM;
-                               goto fail1;
-                       }
+       } else
+               td2 = FIRST_THREAD_IN_PROC(newproc);
+
+       /* Allocate and switch to an alternate kstack if specified. */
+       if (pages != 0) {
+               if (!vm_thread_new_altkstack(td2, pages)) {
+                       error = ENOMEM;
+                       goto fail1;
                }
        }
-
        if ((flags & RFMEM) == 0) {
                vm2 = vmspace_fork(p1->p_vmspace, &mem_charged);
                if (vm2 == NULL) {

Modified: head/sys/kern/kern_kthread.c
==============================================================================
--- head/sys/kern/kern_kthread.c        Sat Aug 29 19:49:17 2009        
(r196647)
+++ head/sys/kern/kern_kthread.c        Sat Aug 29 21:53:08 2009        
(r196648)
@@ -256,7 +256,7 @@ kthread_add(void (*func)(void *), void *
        }
 
        /* Initialize our new td  */
-       newtd = thread_alloc(pages);
+       newtd = thread_alloc();
        if (newtd == NULL)
                return (ENOMEM);
 
@@ -282,6 +282,9 @@ kthread_add(void (*func)(void *), void *
 
        newtd->td_pflags |= TDP_KTHREAD;
        newtd->td_ucred = crhold(p->p_ucred);
+       /* Allocate and switch to an alternate kstack if specified. */
+       if (pages != 0)
+               vm_thread_new_altkstack(newtd, pages);
 
        /* this code almost the same as create_thread() in kern_thr.c */
        PROC_LOCK(p);

Modified: head/sys/kern/kern_proc.c
==============================================================================
--- head/sys/kern/kern_proc.c   Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/kern/kern_proc.c   Sat Aug 29 21:53:08 2009        (r196648)
@@ -203,6 +203,14 @@ proc_dtor(void *mem, int size, void *arg
 #endif
                /* Free all OSD associated to this thread. */
                osd_thread_exit(td);
+
+               /* Dispose of an alternate kstack, if it exists.
+                * XXX What if there are more than one thread in the proc?
+                *     The first thread in the proc is special and not
+                *     freed, so you gotta do this here.
+                */
+               if (((p->p_flag & P_KTHREAD) != 0) && (td->td_altkstack != 0))
+                       vm_thread_dispose_altkstack(td);
        }
        EVENTHANDLER_INVOKE(process_dtor, p);
        if (p->p_ksi != NULL)
@@ -759,6 +767,8 @@ fill_kinfo_proc_only(struct proc *p, str
                FOREACH_THREAD_IN_PROC(p, td0) {
                        if (!TD_IS_SWAPPED(td0))
                                kp->ki_rssize += td0->td_kstack_pages;
+                       if (td0->td_altkstack_obj != NULL)
+                               kp->ki_rssize += td0->td_altkstack_pages;
                }
                kp->ki_swrss = vm->vm_swrss;
                kp->ki_tsize = vm->vm_tsize;

Modified: head/sys/kern/kern_thr.c
==============================================================================
--- head/sys/kern/kern_thr.c    Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/kern/kern_thr.c    Sat Aug 29 21:53:08 2009        (r196648)
@@ -176,7 +176,7 @@ create_thread(struct thread *td, mcontex
        }
 
        /* Initialize our td */
-       newtd = thread_alloc(0);
+       newtd = thread_alloc();
        if (newtd == NULL)
                return (ENOMEM);
 

Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/kern/kern_thread.c Sat Aug 29 21:53:08 2009        (r196648)
@@ -283,7 +283,7 @@ thread_reap(void)
  * Allocate a thread.
  */
 struct thread *
-thread_alloc(int pages)
+thread_alloc(void)
 {
        struct thread *td;
 
@@ -291,7 +291,7 @@ thread_alloc(int pages)
 
        td = (struct thread *)uma_zalloc(thread_zone, M_WAITOK);
        KASSERT(td->td_kstack == 0, ("thread_alloc got thread with kstack"));
-       if (!vm_thread_new(td, pages)) {
+       if (!vm_thread_new(td, 0)) {
                uma_zfree(thread_zone, td);
                return (NULL);
        }
@@ -299,17 +299,6 @@ thread_alloc(int pages)
        return (td);
 }
 
-int
-thread_alloc_stack(struct thread *td, int pages)
-{
-
-       KASSERT(td->td_kstack == 0,
-           ("thread_alloc_stack called on a thread with kstack"));
-       if (!vm_thread_new(td, pages))
-               return (0);
-       cpu_thread_alloc(td);
-       return (1);
-}
 
 /*
  * Deallocate a thread.
@@ -323,6 +312,8 @@ thread_free(struct thread *td)
                cpuset_rel(td->td_cpuset);
        td->td_cpuset = NULL;
        cpu_thread_free(td);
+       if (td->td_altkstack != 0)
+               vm_thread_dispose_altkstack(td);
        if (td->td_kstack != 0)
                vm_thread_dispose(td);
        uma_zfree(thread_zone, td);

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/sys/proc.h Sat Aug 29 21:53:08 2009        (r196648)
@@ -267,6 +267,9 @@ struct thread {
        struct vm_object *td_kstack_obj;/* (a) Kstack object. */
        vm_offset_t     td_kstack;      /* (a) Kernel VA of kstack. */
        int             td_kstack_pages; /* (a) Size of the kstack. */
+       struct vm_object *td_altkstack_obj;/* (a) Alternate kstack object. */
+       vm_offset_t     td_altkstack;   /* (a) Kernel VA of alternate kstack. */
+       int             td_altkstack_pages; /* (a) Size of alternate kstack. */
        volatile u_int  td_critnest;    /* (k*) Critical section nest level. */
        struct mdthread td_md;          /* (k) Any machine-dependent fields. */
        struct td_sched *td_sched;      /* (*) Scheduler-specific data. */
@@ -847,8 +850,7 @@ void        cpu_thread_exit(struct thread *);
 void   cpu_thread_free(struct thread *);
 void   cpu_thread_swapin(struct thread *);
 void   cpu_thread_swapout(struct thread *);
-struct thread *thread_alloc(int pages);
-int    thread_alloc_stack(struct thread *, int pages);
+struct thread *thread_alloc(void);
 void   thread_exit(void) __dead2;
 void   thread_free(struct thread *td);
 void   thread_link(struct thread *td, struct proc *p);

Modified: head/sys/vm/vm_extern.h
==============================================================================
--- head/sys/vm/vm_extern.h     Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/vm/vm_extern.h     Sat Aug 29 21:53:08 2009        (r196648)
@@ -80,7 +80,9 @@ int vm_fault_quick(caddr_t v, int prot);
 struct sf_buf *vm_imgact_map_page(vm_object_t object, vm_ooffset_t offset);
 void vm_imgact_unmap_page(struct sf_buf *sf);
 void vm_thread_dispose(struct thread *td);
+void vm_thread_dispose_altkstack(struct thread *td);
 int vm_thread_new(struct thread *td, int pages);
+int vm_thread_new_altkstack(struct thread *td, int pages);
 void vm_thread_swapin(struct thread *td);
 void vm_thread_swapout(struct thread *td);
 #endif                         /* _KERNEL */

Modified: head/sys/vm/vm_glue.c
==============================================================================
--- head/sys/vm/vm_glue.c       Sat Aug 29 19:49:17 2009        (r196647)
+++ head/sys/vm/vm_glue.c       Sat Aug 29 21:53:08 2009        (r196648)
@@ -77,7 +77,6 @@ __FBSDID("$FreeBSD$");
 #include <sys/sx.h>
 #include <sys/sysctl.h>
 
-#include <sys/eventhandler.h>
 #include <sys/kernel.h>
 #include <sys/ktr.h>
 #include <sys/unistd.h>
@@ -309,20 +308,6 @@ vm_imgact_unmap_page(struct sf_buf *sf)
        vm_page_unlock_queues();
 }
 
-struct kstack_cache_entry {
-       vm_object_t ksobj;
-       struct kstack_cache_entry *next_ks_entry;
-};
-
-static struct kstack_cache_entry *kstack_cache;
-static int kstack_cache_size = 128;
-static int kstacks;
-static struct mtx kstack_cache_mtx;
-SYSCTL_INT(_vm, OID_AUTO, kstack_cache_size, CTLFLAG_RW, &kstack_cache_size, 0,
-    "");
-SYSCTL_INT(_vm, OID_AUTO, kstacks, CTLFLAG_RD, &kstacks, 0,
-    "");
-
 #ifndef KSTACK_MAX_PAGES
 #define KSTACK_MAX_PAGES 32
 #endif
@@ -338,7 +323,6 @@ vm_thread_new(struct thread *td, int pag
        vm_object_t ksobj;
        vm_offset_t ks;
        vm_page_t m, ma[KSTACK_MAX_PAGES];
-       struct kstack_cache_entry *ks_ce;
        int i;
 
        /* Bounds check */
@@ -346,22 +330,6 @@ vm_thread_new(struct thread *td, int pag
                pages = KSTACK_PAGES;
        else if (pages > KSTACK_MAX_PAGES)
                pages = KSTACK_MAX_PAGES;
-
-       if (pages == KSTACK_PAGES) {
-               mtx_lock(&kstack_cache_mtx);
-               if (kstack_cache != NULL) {
-                       ks_ce = kstack_cache;
-                       kstack_cache = ks_ce->next_ks_entry;
-                       mtx_unlock(&kstack_cache_mtx);
-
-                       td->td_kstack_obj = ks_ce->ksobj;
-                       td->td_kstack = (vm_offset_t)ks_ce;
-                       td->td_kstack_pages = KSTACK_PAGES;
-                       return (1);
-               }
-               mtx_unlock(&kstack_cache_mtx);
-       }
-
        /*
         * Allocate an object for the kstack.
         */
@@ -377,8 +345,7 @@ vm_thread_new(struct thread *td, int pag
                vm_object_deallocate(ksobj);
                return (0);
        }
-
-       atomic_add_int(&kstacks, 1);
+       
        if (KSTACK_GUARD_PAGES != 0) {
                pmap_qremove(ks, KSTACK_GUARD_PAGES);
                ks += KSTACK_GUARD_PAGES * PAGE_SIZE;
@@ -409,13 +376,20 @@ vm_thread_new(struct thread *td, int pag
        return (1);
 }
 
-static void
-vm_thread_stack_dispose(vm_object_t ksobj, vm_offset_t ks, int pages)
+/*
+ * Dispose of a thread's kernel stack.
+ */
+void
+vm_thread_dispose(struct thread *td)
 {
+       vm_object_t ksobj;
+       vm_offset_t ks;
        vm_page_t m;
-       int i;
+       int i, pages;
 
-       atomic_add_int(&kstacks, -1);
+       pages = td->td_kstack_pages;
+       ksobj = td->td_kstack_obj;
+       ks = td->td_kstack;
        pmap_qremove(ks, pages);
        VM_OBJECT_LOCK(ksobj);
        for (i = 0; i < pages; i++) {
@@ -431,66 +405,9 @@ vm_thread_stack_dispose(vm_object_t ksob
        vm_object_deallocate(ksobj);
        kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE),
            (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE);
-}
-
-/*
- * Dispose of a thread's kernel stack.
- */
-void
-vm_thread_dispose(struct thread *td)
-{
-       vm_object_t ksobj;
-       vm_offset_t ks;
-       struct kstack_cache_entry *ks_ce;
-       int pages;
-
-       pages = td->td_kstack_pages;
-       ksobj = td->td_kstack_obj;
-       ks = td->td_kstack;
-       if (pages == KSTACK_PAGES && kstacks <= kstack_cache_size) {
-               ks_ce = (struct kstack_cache_entry *)ks;
-               ks_ce->ksobj = ksobj;
-               mtx_lock(&kstack_cache_mtx);
-               ks_ce->next_ks_entry = ks_ce;
-               kstack_cache = ks_ce;
-               mtx_unlock(&kstack_cache_mtx);
-               return;
-       }
-       vm_thread_stack_dispose(ksobj, ks, pages);
        td->td_kstack = 0;
-       td->td_kstack_pages = 0;
-}
-
-static void
-vm_thread_stack_lowmem(void *nulll)
-{
-       struct kstack_cache_entry *ks_ce, *ks_ce1;
-
-       mtx_lock(&kstack_cache_mtx);
-       ks_ce = kstack_cache;
-       kstack_cache = NULL;
-       mtx_unlock(&kstack_cache_mtx);
-
-       while (ks_ce != NULL) {
-               ks_ce1 = ks_ce;
-               ks_ce = ks_ce->next_ks_entry;
-
-               vm_thread_stack_dispose(ks_ce1->ksobj, (vm_offset_t)ks_ce1,
-                   KSTACK_PAGES);
-       }
-}
-
-static void
-kstack_cache_init(void *nulll)
-{
-
-       EVENTHANDLER_REGISTER(vm_lowmem, vm_thread_stack_lowmem, NULL,
-           EVENTHANDLER_PRI_ANY);
 }
 
-MTX_SYSINIT(kstack_cache, &kstack_cache_mtx, "kstkch", MTX_DEF);
-SYSINIT(vm_kstacks, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, kstack_cache_init, 
NULL);
-
 /*
  * Allow a thread's kernel stack to be paged out.
  */
@@ -551,6 +468,37 @@ vm_thread_swapin(struct thread *td)
 }
 
 /*
+ * Set up a variable-sized alternate kstack.
+ */
+int
+vm_thread_new_altkstack(struct thread *td, int pages)
+{
+
+       td->td_altkstack = td->td_kstack;
+       td->td_altkstack_obj = td->td_kstack_obj;
+       td->td_altkstack_pages = td->td_kstack_pages;
+
+       return (vm_thread_new(td, pages));
+}
+
+/*
+ * Restore the original kstack.
+ */
+void
+vm_thread_dispose_altkstack(struct thread *td)
+{
+
+       vm_thread_dispose(td);
+
+       td->td_kstack = td->td_altkstack;
+       td->td_kstack_obj = td->td_altkstack_obj;
+       td->td_kstack_pages = td->td_altkstack_pages;
+       td->td_altkstack = 0;
+       td->td_altkstack_obj = NULL;
+       td->td_altkstack_pages = 0;
+}
+
+/*
  * Implement fork's actions on an address space.
  * Here we arrange for the address space to be copied or referenced,
  * allocate a user struct (pcb and kernel stack), then call the
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to