diff options
35 files changed, 394 insertions, 100 deletions
diff --git a/sys/alpha/alpha/pmap.c b/sys/alpha/alpha/pmap.c index 72db2bf..df7f181 100644 --- a/sys/alpha/alpha/pmap.c +++ b/sys/alpha/alpha/pmap.c @@ -898,12 +898,16 @@ retry: return m; } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack for a new thread. * This routine directly affects the fork perf for a process and thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { int i; vm_object_t ksobj; @@ -911,15 +915,21 @@ pmap_new_thread(struct thread *td) vm_page_t m; pt_entry_t *ptek, oldpte; + /* Bounds check */ + if (pages <= 1) + pages = KSTACK_PAGES; + else if (pages > KSTACK_MAX_PAGES) + pages = KSTACK_MAX_PAGES; + /* * allocate object for the kstack */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; #ifdef KSTACK_GUARD /* get a kernel virtual address for the kstack for this thread */ - ks = kmem_alloc_nofault(kernel_map, (KSTACK_PAGES + 1) * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, (pages + 1) * PAGE_SIZE); if (ks == NULL) panic("pmap_new_thread: kstack allocation failed"); @@ -935,17 +945,23 @@ pmap_new_thread(struct thread *td) ptek++; #else /* get a kernel virtual address for the kstack for this thread */ - ks = kmem_alloc_nofault(kernel_map, KSTACK_PAGES * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, pages * PAGE_SIZE); if (ks == NULL) panic("pmap_new_thread: kstack allocation failed"); td->td_kstack = ks; ptek = vtopte(ks); #endif /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + + /* * For the length of the stack, link in a real page of ram for each * page of stack. */ - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { /* * Get a kernel stack page */ @@ -976,15 +992,17 @@ pmap_dispose_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; pt_entry_t *ptek; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; ptek = vtopte(ks); - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_dispose_thread: kstack already missing?"); @@ -1002,14 +1020,43 @@ pmap_dispose_thread(td) * address map. */ #ifdef KSTACK_GUARD - kmem_free(kernel_map, ks - PAGE_SIZE, (KSTACK_PAGES + 1) * PAGE_SIZE); + kmem_free(kernel_map, ks - PAGE_SIZE, (pages + 1) * PAGE_SIZE); #else - kmem_free(kernel_map, ks, KSTACK_PAGES * PAGE_SIZE); + kmem_free(kernel_map, ks, pages * PAGE_SIZE); #endif vm_object_deallocate(ksobj); } /* + * Set up a variable sized alternate kstack. + */ +void +pmap_new_altkstack(struct thread *td, int pages) +{ + /* shuffle the original stack */ + td->td_altkstack_obj = td->td_kstack_obj; + td->td_altkstack = td->td_kstack; + td->td_altkstack_pages = td->td_kstack_pages; + + pmap_new_thread(td, pages); +} + +void +pmap_dispose_altkstack(td) + struct thread *td; +{ + pmap_dispose_thread(td); + + /* restore the original kstack */ + 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; +} + +/* * Allow the kernel stack for a thread to be prejudicially paged out. */ void @@ -1017,6 +1064,7 @@ pmap_swapout_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; @@ -1026,9 +1074,10 @@ pmap_swapout_thread(td) */ alpha_fpstate_save(td, 1); + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_swapout_thread: kstack already missing?"); @@ -1048,13 +1097,15 @@ pmap_swapin_thread(td) struct thread *td; { int i, rv; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); pmap_kenter(ks + i * PAGE_SIZE, VM_PAGE_TO_PHYS(m)); if (m->valid != VM_PAGE_BITS_ALL) { diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 0c9a2c7..b68ff09 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -934,29 +934,39 @@ retry: return m; } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack (including pcb for i386) for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { int i; - vm_page_t ma[KSTACK_PAGES]; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_page_t m; vm_offset_t ks; + /* Bounds check */ + if (pages <= 1) + pages = KSTACK_PAGES; + else if (pages > KSTACK_MAX_PAGES) + pages = KSTACK_MAX_PAGES; + /* * allocate object for the kstack */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* get a kernel virtual address for the kstack for this thread */ #ifdef KSTACK_GUARD - ks = kmem_alloc_nofault(kernel_map, (KSTACK_PAGES + 1) * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, (pages + 1) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); if (*vtopte(ks) != 0) @@ -965,16 +975,22 @@ pmap_new_thread(struct thread *td) td->td_kstack = ks; #else /* get a kernel virtual address for the kstack for this thread */ - ks = kmem_alloc_nofault(kernel_map, KSTACK_PAGES * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, pages * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); td->td_kstack = ks; #endif + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + /* * For the length of the stack, link in a real page of ram for each * page of stack. */ - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { /* * Get a kernel stack page */ @@ -986,7 +1002,7 @@ pmap_new_thread(struct thread *td) vm_page_flag_clear(m, PG_ZERO); m->valid = VM_PAGE_BITS_ALL; } - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /* @@ -998,14 +1014,16 @@ pmap_dispose_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - pmap_qremove(ks, KSTACK_PAGES); - for (i = 0; i < KSTACK_PAGES; i++) { + pmap_qremove(ks, pages); + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_dispose_thread: kstack already missing?"); @@ -1020,14 +1038,44 @@ pmap_dispose_thread(td) * address map. */ #ifdef KSTACK_GUARD - kmem_free(kernel_map, ks - PAGE_SIZE, (KSTACK_PAGES + 1) * PAGE_SIZE); + kmem_free(kernel_map, ks - PAGE_SIZE, (pages + 1) * PAGE_SIZE); #else - kmem_free(kernel_map, ks, KSTACK_PAGES * PAGE_SIZE); + kmem_free(kernel_map, ks, pages * PAGE_SIZE); #endif vm_object_deallocate(ksobj); } /* + * Set up a variable sized alternate kstack. Though it may look MI, it may + * need to be different on certain arches like ia64. + */ +void +pmap_new_altkstack(struct thread *td, int pages) +{ + /* shuffle the original stack */ + td->td_altkstack_obj = td->td_kstack_obj; + td->td_altkstack = td->td_kstack; + td->td_altkstack_pages = td->td_kstack_pages; + + pmap_new_thread(td, pages); +} + +void +pmap_dispose_altkstack(td) + struct thread *td; +{ + pmap_dispose_thread(td); + + /* restore the original kstack */ + 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; +} + +/* * Allow the Kernel stack for a thread to be prejudicially paged out. */ void @@ -1035,14 +1083,16 @@ pmap_swapout_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - pmap_qremove(ks, KSTACK_PAGES); - for (i = 0; i < KSTACK_PAGES; i++) { + pmap_qremove(ks, pages); + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_swapout_thread: kstack already missing?"); @@ -1061,14 +1111,16 @@ pmap_swapin_thread(td) struct thread *td; { int i, rv; - vm_page_t ma[KSTACK_PAGES]; + int pages; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { rv = vm_pager_get_pages(ksobj, &m, 1, 0); @@ -1083,7 +1135,7 @@ pmap_swapin_thread(td) vm_page_wakeup(m); vm_page_unlock_queues(); } - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /*************************************************** diff --git a/sys/conf/NOTES b/sys/conf/NOTES index c625246..df321f6 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -2253,6 +2253,8 @@ options SHOW_BUSYBUFS # List buffers that prevent root unmount options SLIP_IFF_OPTS options VFS_BIO_DEBUG # VFS buffer I/O debugging +options KSTACK_MAX_PAGES=32 # Maximum pages to give the kernel stack + # Yet more undocumented options for linting. options AAC_DEBUG options ACD_DEBUG diff --git a/sys/conf/options b/sys/conf/options index 079d77b..20aa5af 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -89,6 +89,7 @@ GDBSPEED opt_ddb.h GEOM HW_WDOG KSTACK_PAGES +KSTACK_MAX_PAGES KTRACE KTRACE_REQUEST_POOL opt_ktrace.h LIBICONV diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 0ad1d83..2e1dbf1 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -312,7 +312,7 @@ aac_attach(struct aac_softc *sc) /* Create the AIF thread */ #if __FreeBSD_version > 500005 if (kthread_create((void(*)(void *))aac_host_command, sc, - &sc->aifthread, 0, "aac%daif", unit)) + &sc->aifthread, 0, 0, "aac%daif", unit)) #else if (kthread_create((void(*)(void *))aac_host_command, sc, &sc->aifthread, "aac%daif", unit)) diff --git a/sys/dev/acpica/Osd/OsdSchedule.c b/sys/dev/acpica/Osd/OsdSchedule.c index d8aca62..f402a02 100644 --- a/sys/dev/acpica/Osd/OsdSchedule.c +++ b/sys/dev/acpica/Osd/OsdSchedule.c @@ -148,7 +148,7 @@ acpi_task_thread_init(void) for (i = 0; i < ACPI_MAX_THREADS; i++) { err = kthread_create(acpi_task_thread, NULL, &acpi_kthread_proc, - 0, "acpi_task%d", i); + 0, 0, "acpi_task%d", i); if (err != 0) { printf("%s: kthread_create failed(%d)\n", __func__, err); break; diff --git a/sys/dev/acpica/acpi_thermal.c b/sys/dev/acpica/acpi_thermal.c index d781272..74fc962 100644 --- a/sys/dev/acpica/acpi_thermal.c +++ b/sys/dev/acpica/acpi_thermal.c @@ -263,7 +263,7 @@ acpi_tz_attach(device_t dev) */ if (acpi_tz_proc == NULL) { error = kthread_create(acpi_tz_thread, NULL, &acpi_tz_proc, - RFHIGHPID, "acpi_thermal"); + RFHIGHPID, 0, "acpi_thermal"); if (error != 0) { device_printf(sc->tz_dev, "could not create thread - %d", error); goto out; diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index f1afcc7..2c3fb19 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -463,7 +463,7 @@ ata_raid_rebuild(int array) return ENXIO; if (rdp->flags & AR_F_REBUILDING) return EBUSY; - return kthread_create(ar_rebuild, rdp, &rdp->pid, RFNOWAIT, + return kthread_create(ar_rebuild, rdp, &rdp->pid, RFNOWAIT, 0, "rebuilding ar%d", array); } diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index af93d20..c80c32c 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -148,7 +148,7 @@ isp_attach(struct ispsoftc *isp) /* XXX: LOCK VIOLATION */ cv_init(&isp->isp_osinfo.kthread_cv, "isp_kthread_cv"); if (kthread_create(isp_kthread, isp, &isp->isp_osinfo.kproc, - RFHIGHPID, "%s: fc_thrd", + RFHIGHPID, 0, "%s: fc_thrd", device_get_nameunit(isp->isp_dev))) { xpt_bus_deregister(cam_sim_path(sim)); cam_sim_free(sim, TRUE); diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index ae1953d..7836ced 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -646,7 +646,7 @@ mdnew(int unit) sc = (struct md_s *)malloc(sizeof *sc, M_MD, M_WAITOK | M_ZERO); sc->unit = unit; sprintf(sc->name, "md%d", unit); - error = kthread_create(md_kthread, sc, &sc->procp, 0, "%s", sc->name); + error = kthread_create(md_kthread, sc, &sc->procp, 0, 0,"%s", sc->name); if (error) { free(sc, M_MD); return (NULL); diff --git a/sys/dev/pccbb/pccbb.c b/sys/dev/pccbb/pccbb.c index 8d26665..cf3ff52 100644 --- a/sys/dev/pccbb/pccbb.c +++ b/sys/dev/pccbb/pccbb.c @@ -680,7 +680,7 @@ cbb_attach(device_t brdev) cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT)); /* Start the thread */ - if (kthread_create(cbb_event_thread, sc, &sc->event_thread, 0, + if (kthread_create(cbb_event_thread, sc, &sc->event_thread, 0, 0, "%s%d", device_get_name(sc->dev), device_get_unit(sc->dev))) { device_printf (sc->dev, "unable to create event thread.\n"); panic ("cbb_create_event_thread"); diff --git a/sys/dev/pcic/i82365.c b/sys/dev/pcic/i82365.c index 02ca122..387927b 100644 --- a/sys/dev/pcic/i82365.c +++ b/sys/dev/pcic/i82365.c @@ -487,7 +487,7 @@ pcic_create_event_thread(void *arg) } if (kthread_create(pcic_event_thread, h, &h->event_thread, - 0, "%s,%s", device_get_name(PCIC_H2SOFTC(h)->dev), cs)) { + 0, 0, "%s,%s", device_get_name(PCIC_H2SOFTC(h)->dev), cs)) { device_printf(PCIC_H2SOFTC(h)->dev, "cannot create event thread for sock 0x%02x\n", h->sock); panic("pcic_create_event_thread"); diff --git a/sys/dev/random/randomdev.c b/sys/dev/random/randomdev.c index e018428..d965cbc 100644 --- a/sys/dev/random/randomdev.c +++ b/sys/dev/random/randomdev.c @@ -282,7 +282,7 @@ random_modevent(module_t mod __unused, int type, void *data __unused) /* Start the hash/reseed thread */ error = kthread_create(random_kthread, NULL, - &random_kthread_proc, RFHIGHPID, "random"); + &random_kthread_proc, RFHIGHPID, 0, "random"); if (error != 0) return error; diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h index cbf90fd..1894b9a 100644 --- a/sys/dev/usb/usb_port.h +++ b/sys/dev/usb/usb_port.h @@ -365,9 +365,9 @@ typedef struct thread *usb_proc_ptr; #define memcpy(d, s, l) bcopy((s),(d),(l)) #define memset(d, v, l) bzero((d),(l)) #define usb_kthread_create1(f, s, p, a0, a1) \ - kthread_create((f), (s), (p), RFHIGHPID, (a0), (a1)) + kthread_create((f), (s), (p), RFHIGHPID, 0, (a0), (a1)) #define usb_kthread_create2(f, s, p, a0) \ - kthread_create((f), (s), (p), RFHIGHPID, (a0)) + kthread_create((f), (s), (p), RFHIGHPID, 0, (a0)) #define usb_kthread_create kthread_create #define config_pending_incr() diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 0c9a2c7..b68ff09 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -934,29 +934,39 @@ retry: return m; } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack (including pcb for i386) for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { int i; - vm_page_t ma[KSTACK_PAGES]; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_page_t m; vm_offset_t ks; + /* Bounds check */ + if (pages <= 1) + pages = KSTACK_PAGES; + else if (pages > KSTACK_MAX_PAGES) + pages = KSTACK_MAX_PAGES; + /* * allocate object for the kstack */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* get a kernel virtual address for the kstack for this thread */ #ifdef KSTACK_GUARD - ks = kmem_alloc_nofault(kernel_map, (KSTACK_PAGES + 1) * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, (pages + 1) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); if (*vtopte(ks) != 0) @@ -965,16 +975,22 @@ pmap_new_thread(struct thread *td) td->td_kstack = ks; #else /* get a kernel virtual address for the kstack for this thread */ - ks = kmem_alloc_nofault(kernel_map, KSTACK_PAGES * PAGE_SIZE); + ks = kmem_alloc_nofault(kernel_map, pages * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); td->td_kstack = ks; #endif + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + /* * For the length of the stack, link in a real page of ram for each * page of stack. */ - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { /* * Get a kernel stack page */ @@ -986,7 +1002,7 @@ pmap_new_thread(struct thread *td) vm_page_flag_clear(m, PG_ZERO); m->valid = VM_PAGE_BITS_ALL; } - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /* @@ -998,14 +1014,16 @@ pmap_dispose_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - pmap_qremove(ks, KSTACK_PAGES); - for (i = 0; i < KSTACK_PAGES; i++) { + pmap_qremove(ks, pages); + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_dispose_thread: kstack already missing?"); @@ -1020,14 +1038,44 @@ pmap_dispose_thread(td) * address map. */ #ifdef KSTACK_GUARD - kmem_free(kernel_map, ks - PAGE_SIZE, (KSTACK_PAGES + 1) * PAGE_SIZE); + kmem_free(kernel_map, ks - PAGE_SIZE, (pages + 1) * PAGE_SIZE); #else - kmem_free(kernel_map, ks, KSTACK_PAGES * PAGE_SIZE); + kmem_free(kernel_map, ks, pages * PAGE_SIZE); #endif vm_object_deallocate(ksobj); } /* + * Set up a variable sized alternate kstack. Though it may look MI, it may + * need to be different on certain arches like ia64. + */ +void +pmap_new_altkstack(struct thread *td, int pages) +{ + /* shuffle the original stack */ + td->td_altkstack_obj = td->td_kstack_obj; + td->td_altkstack = td->td_kstack; + td->td_altkstack_pages = td->td_kstack_pages; + + pmap_new_thread(td, pages); +} + +void +pmap_dispose_altkstack(td) + struct thread *td; +{ + pmap_dispose_thread(td); + + /* restore the original kstack */ + 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; +} + +/* * Allow the Kernel stack for a thread to be prejudicially paged out. */ void @@ -1035,14 +1083,16 @@ pmap_swapout_thread(td) struct thread *td; { int i; + int pages; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - pmap_qremove(ks, KSTACK_PAGES); - for (i = 0; i < KSTACK_PAGES; i++) { + pmap_qremove(ks, pages); + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_swapout_thread: kstack already missing?"); @@ -1061,14 +1111,16 @@ pmap_swapin_thread(td) struct thread *td; { int i, rv; - vm_page_t ma[KSTACK_PAGES]; + int pages; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { rv = vm_pager_get_pages(ksobj, &m, 1, 0); @@ -1083,7 +1135,7 @@ pmap_swapin_thread(td) vm_page_wakeup(m); vm_page_unlock_queues(); } - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /*************************************************** diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index 56952cb..c468d89 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -342,7 +342,7 @@ linux_clone(struct thread *td, struct linux_clone_args *args) ff |= RFFDG; mtx_lock(&Giant); - error = fork1(td, ff, &p2); + error = fork1(td, ff, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 49bb739..66b58d2 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -685,7 +685,7 @@ create_init(const void *udata __unused) struct ucred *newcred, *oldcred; int error; - error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, &initproc); + error = fork1(&thread0, RFFDG | RFPROC | RFSTOPPED, 0, &initproc); if (error) panic("cannot fork init: %d\n", error); /* divorce init's credentials from the kernel's */ diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index da7ca7d..9fbf602 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -118,7 +118,7 @@ fork(td, uap) struct proc *p2; mtx_lock(&Giant); - error = fork1(td, RFFDG | RFPROC, &p2); + error = fork1(td, RFFDG | RFPROC, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -140,7 +140,7 @@ vfork(td, uap) struct proc *p2; mtx_lock(&Giant); - error = fork1(td, RFFDG | RFPROC | RFPPWAIT | RFMEM, &p2); + error = fork1(td, RFFDG | RFPROC | RFPPWAIT | RFMEM, 0, &p2); if (error == 0) { td->td_retval[0] = p2->p_pid; td->td_retval[1] = 0; @@ -164,7 +164,7 @@ rfork(td, uap) if ((uap->flags & RFKERNELONLY) != 0) return (EINVAL); mtx_lock(&Giant); - error = fork1(td, uap->flags, &p2); + error = fork1(td, uap->flags, 0, &p2); if (error == 0) { td->td_retval[0] = p2 ? p2->p_pid : 0; td->td_retval[1] = 0; @@ -215,9 +215,10 @@ SYSCTL_PROC(_kern, OID_AUTO, randompid, CTLTYPE_INT|CTLFLAG_RW, 0, 0, sysctl_kern_randompid, "I", "Random PID modulus"); int -fork1(td, flags, procp) +fork1(td, flags, pages, procp) struct thread *td; /* parent proc */ int flags; + int pages; struct proc **procp; /* child proc */ { struct proc *p2, *pptr; @@ -471,6 +472,10 @@ again: kg2 = FIRST_KSEGRP_IN_PROC(p2); ke2 = FIRST_KSE_IN_KSEGRP(kg2); + /* Allocate and switch to an alternate kstack if specified */ + if (pages != 0) + pmap_new_altkstack(td2, pages); + #define RANGEOF(type, start, end) (offsetof(type, end) - offsetof(type, start)) bzero(&p2->p_startzero, diff --git a/sys/kern/kern_idle.c b/sys/kern/kern_idle.c index b0f4fda..bf8e922 100644 --- a/sys/kern/kern_idle.c +++ b/sys/kern/kern_idle.c @@ -46,7 +46,7 @@ idle_setup(void *dummy) #ifdef SMP SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { error = kthread_create(idle_proc, NULL, &p, - RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid); + RFSTOPPED | RFHIGHPID, 0, "idle: cpu%d", pc->pc_cpuid); pc->pc_idlethread = FIRST_THREAD_IN_PROC(p); if (pc->pc_curthread == NULL) { pc->pc_curthread = pc->pc_idlethread; @@ -54,7 +54,7 @@ idle_setup(void *dummy) } #else error = kthread_create(idle_proc, NULL, &p, - RFSTOPPED | RFHIGHPID, "idle"); + RFSTOPPED | RFHIGHPID, 0, "idle"); PCPU_SET(idlethread, FIRST_THREAD_IN_PROC(p)); #endif if (error) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index 61f6579..2d7b160 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -188,7 +188,7 @@ ithread_create(struct ithd **ithread, int vector, int flags, va_end(ap); error = kthread_create(ithread_loop, ithd, &p, RFSTOPPED | RFHIGHPID, - "%s", ithd->it_name); + 0, "%s", ithd->it_name); if (error) { mtx_destroy(&ithd->it_lock); free(ithd, M_ITHREAD); diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 907eba7..7123616 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -142,7 +142,7 @@ thread_init(void *mem, int size) td = (struct thread *)mem; mtx_lock(&Giant); - pmap_new_thread(td); + pmap_new_thread(td, 0); mtx_unlock(&Giant); cpu_thread_setup(td); } diff --git a/sys/kern/kern_kthread.c b/sys/kern/kern_kthread.c index 08ef71f..e785d0b 100644 --- a/sys/kern/kern_kthread.c +++ b/sys/kern/kern_kthread.c @@ -55,7 +55,7 @@ kproc_start(udata) int error; error = kthread_create((void (*)(void *))kp->func, NULL, - kp->global_procpp, 0, "%s", kp->arg0); + kp->global_procpp, 0, 0, "%s", kp->arg0); if (error) panic("kproc_start: %s: error %d", kp->arg0, error); } @@ -72,7 +72,7 @@ kproc_start(udata) */ int kthread_create(void (*func)(void *), void *arg, - struct proc **newpp, int flags, const char *fmt, ...) + struct proc **newpp, int flags, int pages, const char *fmt, ...) { int error; va_list ap; @@ -83,7 +83,7 @@ kthread_create(void (*func)(void *), void *arg, panic("kthread_create called too soon"); error = fork1(&thread0, RFMEM | RFFDG | RFPROC | RFSTOPPED | flags, - &p2); + pages, &p2); if (error) return error; diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 0ad2df3..bb4642c 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -134,7 +134,7 @@ ktrace_init(void *dummy) req = malloc(sizeof(struct ktr_request), M_KTRACE, M_WAITOK); STAILQ_INSERT_HEAD(&ktr_free, req, ktr_list); } - kthread_create(ktr_loop, NULL, NULL, RFHIGHPID, "ktrace"); + kthread_create(ktr_loop, NULL, NULL, RFHIGHPID, 0, "ktrace"); } SYSINIT(ktrace_init, SI_SUB_KTRACE, SI_ORDER_ANY, ktrace_init, NULL); diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 633c66e..9f20562 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -164,6 +164,15 @@ proc_dtor(void *mem, int size, void *arg) KASSERT((kg != NULL), ("proc_dtor: bad kg pointer")); ke = FIRST_KSE_IN_KSEGRP(kg); KASSERT((ke != NULL), ("proc_dtor: bad ke pointer")); + + /* 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)) + pmap_dispose_altkstack(td); + /* * We want to make sure we know the initial linkages. * so for now tear them down and remake them. diff --git a/sys/kern/kern_thread.c b/sys/kern/kern_thread.c index 907eba7..7123616 100644 --- a/sys/kern/kern_thread.c +++ b/sys/kern/kern_thread.c @@ -142,7 +142,7 @@ thread_init(void *mem, int size) td = (struct thread *)mem; mtx_lock(&Giant); - pmap_new_thread(td); + pmap_new_thread(td, 0); mtx_unlock(&Giant); cpu_thread_setup(td); } diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c index b3a2670..d4230cb 100644 --- a/sys/kern/vfs_aio.c +++ b/sys/kern/vfs_aio.c @@ -1001,7 +1001,7 @@ aio_newproc() int error; struct proc *p; - error = kthread_create(aio_daemon, curproc, &p, RFNOWAIT, "aiod%d", + error = kthread_create(aio_daemon, curproc, &p, RFNOWAIT, 0, "aiod%d", num_aio_procs); if (error) return error; diff --git a/sys/netsmb/smb_iod.c b/sys/netsmb/smb_iod.c index 38c8184..7edbc1b 100644 --- a/sys/netsmb/smb_iod.c +++ b/sys/netsmb/smb_iod.c @@ -676,7 +676,7 @@ smb_iod_create(struct smb_vc *vcp) smb_sl_init(&iod->iod_evlock, "90evl"); STAILQ_INIT(&iod->iod_evlist); error = kthread_create(smb_iod_thread, iod, &iod->iod_p, - RFNOWAIT, "smbiod%d", iod->iod_id); + RFNOWAIT, 0, "smbiod%d", iod->iod_id); if (error) { SMBERROR("can't start smbiod: %d", error); free(iod, M_SMBIOD); diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index 4a3d0f7..8762b16 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -170,7 +170,7 @@ nfs_nfsiodnew(void) if (newiod == -1) return (-1); error = kthread_create(nfssvc_iod, nfs_asyncdaemon + i, NULL, RFHIGHPID, - "nfsiod %d", newiod); + 0, "nfsiod %d", newiod); if (error) return (-1); nfs_numasync++; diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index bd15689..8802cfb 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -1532,13 +1532,17 @@ pmap_remove_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva) pmap_remove(pm, sva, eva); } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { vm_object_t ksobj; vm_offset_t ks; @@ -1548,21 +1552,27 @@ pmap_new_thread(struct thread *td) /* * Allocate object for the kstack. */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for the kstack for this thread. */ ks = kmem_alloc_nofault(kernel_map, - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); TLBIE(ks); ks += KSTACK_GUARD_PAGES * PAGE_SIZE; td->td_kstack = ks; - for (i = 0; i < KSTACK_PAGES; i++) { + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + + for (i = 0; i < pages; i++) { /* * Get a kernel stack page. */ @@ -1587,6 +1597,18 @@ pmap_dispose_thread(struct thread *td) } void +pmap_new_altkstack(struct thread *td, int pages) +{ + TODO; +} + +void +pmap_dispose_altkstack(struct thread *td) +{ + TODO; +} + +void pmap_swapin_thread(struct thread *td) { TODO; diff --git a/sys/powerpc/powerpc/mmu_oea.c b/sys/powerpc/powerpc/mmu_oea.c index bd15689..8802cfb 100644 --- a/sys/powerpc/powerpc/mmu_oea.c +++ b/sys/powerpc/powerpc/mmu_oea.c @@ -1532,13 +1532,17 @@ pmap_remove_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva) pmap_remove(pm, sva, eva); } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { vm_object_t ksobj; vm_offset_t ks; @@ -1548,21 +1552,27 @@ pmap_new_thread(struct thread *td) /* * Allocate object for the kstack. */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for the kstack for this thread. */ ks = kmem_alloc_nofault(kernel_map, - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); TLBIE(ks); ks += KSTACK_GUARD_PAGES * PAGE_SIZE; td->td_kstack = ks; - for (i = 0; i < KSTACK_PAGES; i++) { + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + + for (i = 0; i < pages; i++) { /* * Get a kernel stack page. */ @@ -1587,6 +1597,18 @@ pmap_dispose_thread(struct thread *td) } void +pmap_new_altkstack(struct thread *td, int pages) +{ + TODO; +} + +void +pmap_dispose_altkstack(struct thread *td) +{ + TODO; +} + +void pmap_swapin_thread(struct thread *td) { TODO; diff --git a/sys/powerpc/powerpc/pmap.c b/sys/powerpc/powerpc/pmap.c index bd15689..8802cfb 100644 --- a/sys/powerpc/powerpc/pmap.c +++ b/sys/powerpc/powerpc/pmap.c @@ -1532,13 +1532,17 @@ pmap_remove_pages(pmap_t pm, vm_offset_t sva, vm_offset_t eva) pmap_remove(pm, sva, eva); } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { vm_object_t ksobj; vm_offset_t ks; @@ -1548,21 +1552,27 @@ pmap_new_thread(struct thread *td) /* * Allocate object for the kstack. */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for the kstack for this thread. */ ks = kmem_alloc_nofault(kernel_map, - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); TLBIE(ks); ks += KSTACK_GUARD_PAGES * PAGE_SIZE; td->td_kstack = ks; - for (i = 0; i < KSTACK_PAGES; i++) { + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + + for (i = 0; i < pages; i++) { /* * Get a kernel stack page. */ @@ -1587,6 +1597,18 @@ pmap_dispose_thread(struct thread *td) } void +pmap_new_altkstack(struct thread *td, int pages) +{ + TODO; +} + +void +pmap_dispose_altkstack(struct thread *td) +{ + TODO; +} + +void pmap_swapin_thread(struct thread *td) { TODO; diff --git a/sys/sparc64/sparc64/pmap.c b/sys/sparc64/sparc64/pmap.c index 4485a55..60c264d 100644 --- a/sys/sparc64/sparc64/pmap.c +++ b/sys/sparc64/sparc64/pmap.c @@ -951,31 +951,41 @@ pmap_qremove(vm_offset_t sva, int count) tlb_range_demap(kernel_pmap, sva, sva + (count * PAGE_SIZE) - 1); } +#ifndef KSTACK_MAX_PAGES +#define KSTACK_MAX_PAGES 32 +#endif + /* * Create the kernel stack and pcb for a new thread. * This routine directly affects the fork perf for a process and * create performance for a thread. */ void -pmap_new_thread(struct thread *td) +pmap_new_thread(struct thread *td, int pages) { - vm_page_t ma[KSTACK_PAGES]; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; u_int i; + /* Bounds check */ + if (pages <= 1) + pages = KSTACK_PAGES; + else if (pages > KSTACK_MAX_PAGES) + pages = KSTACK_MAX_PAGES; + /* * Allocate object for the kstack, */ - ksobj = vm_object_allocate(OBJT_DEFAULT, KSTACK_PAGES); + ksobj = vm_object_allocate(OBJT_DEFAULT, pages); td->td_kstack_obj = ksobj; /* * Get a kernel virtual address for the kstack for this thread. */ ks = kmem_alloc_nofault(kernel_map, - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); if (ks == 0) panic("pmap_new_thread: kstack allocation failed"); if (KSTACK_GUARD_PAGES != 0) { @@ -984,7 +994,13 @@ pmap_new_thread(struct thread *td) } td->td_kstack = ks; - for (i = 0; i < KSTACK_PAGES; i++) { + /* + * Knowing the number of pages allocated is useful when you + * want to deallocate them. + */ + td->td_kstack_pages = pages; + + for (i = 0; i < pages; i++) { /* * Get a kernel stack page. */ @@ -1000,7 +1016,7 @@ pmap_new_thread(struct thread *td) /* * Enter the page into the kernel address space. */ - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /* @@ -1014,10 +1030,12 @@ pmap_dispose_thread(struct thread *td) vm_offset_t ks; vm_page_t m; int i; + int pages; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages ; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_dispose_thread: kstack already missing?"); @@ -1027,13 +1045,41 @@ pmap_dispose_thread(struct thread *td) vm_page_free(m); vm_page_unlock_queues(); } - pmap_qremove(ks, KSTACK_PAGES); + pmap_qremove(ks, pages); kmem_free(kernel_map, ks - (KSTACK_GUARD_PAGES * PAGE_SIZE), - (KSTACK_PAGES + KSTACK_GUARD_PAGES) * PAGE_SIZE); + (pages + KSTACK_GUARD_PAGES) * PAGE_SIZE); vm_object_deallocate(ksobj); } /* + * Set up a variable sized alternate kstack. + */ +void +pmap_new_altkstack(struct thread *td, int pages) +{ + /* shuffle the original stack */ + td->td_altkstack_obj = td->td_kstack_obj; + td->td_altkstack = td->td_kstack; + td->td_altkstack_pages = td->td_kstack_pages; + + pmap_new_thread(td, pages); +} + +void +pmap_dispose_altkstack(struct thread *td) +{ + pmap_dispose_thread(td); + + /* restore the original kstack */ + 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; +} + +/* * Allow the kernel stack for a thread to be prejudicially paged out. */ void @@ -1043,10 +1089,12 @@ pmap_swapout_thread(struct thread *td) vm_offset_t ks; vm_page_t m; int i; + int pages; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = (vm_offset_t)td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_lookup(ksobj, i); if (m == NULL) panic("pmap_swapout_thread: kstack already missing?"); @@ -1055,7 +1103,7 @@ pmap_swapout_thread(struct thread *td) vm_page_unwire(m, 0); vm_page_unlock_queues(); } - pmap_qremove(ks, KSTACK_PAGES); + pmap_qremove(ks, pages); } /* @@ -1064,16 +1112,18 @@ pmap_swapout_thread(struct thread *td) void pmap_swapin_thread(struct thread *td) { - vm_page_t ma[KSTACK_PAGES]; + vm_page_t ma[KSTACK_MAX_PAGES]; vm_object_t ksobj; vm_offset_t ks; vm_page_t m; int rv; int i; + int pages; + pages = td->td_kstack_pages; ksobj = td->td_kstack_obj; ks = td->td_kstack; - for (i = 0; i < KSTACK_PAGES; i++) { + for (i = 0; i < pages; i++) { m = vm_page_grab(ksobj, i, VM_ALLOC_NORMAL | VM_ALLOC_RETRY); if (m->valid != VM_PAGE_BITS_ALL) { rv = vm_pager_get_pages(ksobj, &m, 1, 0); @@ -1088,7 +1138,7 @@ pmap_swapin_thread(struct thread *td) vm_page_wakeup(m); vm_page_unlock_queues(); } - pmap_qenter(ks, ma, KSTACK_PAGES); + pmap_qenter(ks, ma, pages); } /* diff --git a/sys/sys/kthread.h b/sys/sys/kthread.h index 548c410..5f41cfc 100644 --- a/sys/sys/kthread.h +++ b/sys/sys/kthread.h @@ -45,7 +45,7 @@ struct kproc_desc { void kproc_shutdown(void *, int); void kproc_start(const void *); int kthread_create(void (*)(void *), void *, struct proc **, - int flags, const char *, ...) __printflike(5, 6); + int flags, int pages, const char *, ...) __printflike(6, 7); void kthread_exit(int) __dead2; int kthread_resume(struct proc *); /* XXXKSE */ int kthread_suspend(struct proc *, int); /* XXXKSE */ diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 74ca25d..9f4bf95 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -314,6 +314,10 @@ struct thread { struct trapframe *td_frame; /* (k) */ struct vm_object *td_kstack_obj;/* (a) Kstack object. */ vm_offset_t td_kstack; /* Kernel VA of kstack. */ + int td_kstack_pages; /* Size of the kstack */ + struct vm_object *td_altkstack_obj;/* (a) Alternate kstack object. */ + vm_offset_t td_altkstack; /* Kernel VA of alternate kstack. */ + int td_altkstack_pages; /* Size of the alternate kstack */ }; /* flags kept in td_flags */ #define TDF_UNBOUND 0x000001 /* May give away the kse, uses the kg runq. */ @@ -844,7 +848,7 @@ int enterpgrp(struct proc *p, pid_t pgid, struct pgrp *pgrp, struct session *ses int enterthispgrp(struct proc *p, struct pgrp *pgrp); void faultin(struct proc *p); void fixjobc(struct proc *p, struct pgrp *pgrp, int entering); -int fork1(struct thread *, int, struct proc **); +int fork1(struct thread *, int, int, struct proc **); void fork_exit(void (*)(void *, struct trapframe *), void *, struct trapframe *); void fork_return(struct thread *, struct trapframe *); diff --git a/sys/vm/pmap.h b/sys/vm/pmap.h index 2ea797e..69e7122 100644 --- a/sys/vm/pmap.h +++ b/sys/vm/pmap.h @@ -128,8 +128,10 @@ void pmap_zero_page_area(vm_page_t, int off, int size); void pmap_zero_page_idle(vm_page_t); void pmap_prefault(pmap_t, vm_offset_t, vm_map_entry_t); int pmap_mincore(pmap_t pmap, vm_offset_t addr); -void pmap_new_thread(struct thread *td); +void pmap_new_thread(struct thread *td, int pages); void pmap_dispose_thread(struct thread *td); +void pmap_new_altkstack(struct thread *td, int pages); +void pmap_dispose_altkstack(struct thread *td); void pmap_swapout_thread(struct thread *td); void pmap_swapin_thread(struct thread *td); void pmap_activate(struct thread *td); |