Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F116030501
D20931.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D20931.diff
View Options
Index: head/sys/ddb/db_ps.c
===================================================================
--- head/sys/ddb/db_ps.c
+++ head/sys/ddb/db_ps.c
@@ -42,7 +42,6 @@
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/systm.h>
-#include <sys/_kstack_cache.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -505,7 +504,6 @@
{
struct proc *p;
struct thread *td;
- struct kstack_cache_entry *ks_ce;
vm_offset_t saddr;
if (have_addr)
@@ -522,15 +520,6 @@
db_printf("Thread %p\n", td);
return;
}
- }
- }
-
- for (ks_ce = kstack_cache; ks_ce != NULL;
- ks_ce = ks_ce->next_ks_entry) {
- if ((vm_offset_t)ks_ce <= saddr && saddr < (vm_offset_t)ks_ce +
- PAGE_SIZE * kstack_pages) {
- db_printf("Cached stack %p\n", ks_ce);
- return;
}
}
}
Index: head/sys/sys/_kstack_cache.h
===================================================================
--- head/sys/sys/_kstack_cache.h
+++ head/sys/sys/_kstack_cache.h
@@ -1,49 +0,0 @@
-/*-
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * Copyright (c) 2009 Konstantin Belousov <kib@FreeBSD.org>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#ifndef _SYS__KSTACK_CACHE_H
-#define _SYS__KSTACK_CACHE_H
-
-struct kstack_cache_entry {
- struct vm_object *ksobj;
- struct kstack_cache_entry *next_ks_entry;
-};
-
-extern struct kstack_cache_entry *kstack_cache;
-
-#ifndef KSTACK_MAX_PAGES
-#define KSTACK_MAX_PAGES 32
-#endif
-
-#endif
-
-
Index: head/sys/vm/vm_glue.c
===================================================================
--- head/sys/vm/vm_glue.c
+++ head/sys/vm/vm_glue.c
@@ -84,12 +84,12 @@
#include <sys/vmem.h>
#include <sys/sx.h>
#include <sys/sysctl.h>
-#include <sys/_kstack_cache.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
#include <sys/unistd.h>
+#include <vm/uma.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -282,52 +282,39 @@
pmap_sync_icache(map->pmap, va, sz);
}
-struct kstack_cache_entry *kstack_cache;
+static uma_zone_t kstack_cache;
static int kstack_cache_size = 128;
-static int kstacks, kstack_domain_iter;
-static struct mtx kstack_cache_mtx;
-MTX_SYSINIT(kstack_cache, &kstack_cache_mtx, "kstkch", MTX_DEF);
+static int kstack_domain_iter;
-SYSCTL_INT(_vm, OID_AUTO, kstack_cache_size, CTLFLAG_RW, &kstack_cache_size, 0,
- "");
-SYSCTL_INT(_vm, OID_AUTO, kstacks, CTLFLAG_RD, &kstacks, 0,
- "");
+static int
+sysctl_kstack_cache_size(SYSCTL_HANDLER_ARGS)
+{
+ int error, newsize;
+ newsize = kstack_cache_size;
+ error = sysctl_handle_int(oidp, &newsize, 0, req);
+ if (error == 0 && req->newptr && newsize != kstack_cache_size)
+ kstack_cache_size =
+ uma_zone_set_maxcache(kstack_cache, newsize);
+ return (error);
+}
+SYSCTL_PROC(_vm, OID_AUTO, kstack_cache_size, CTLTYPE_INT|CTLFLAG_RW,
+ &kstack_cache_size, 0, sysctl_kstack_cache_size, "IU",
+ "Maximum number of cached kernel stacks");
+
/*
* 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.
*/
-int
-vm_thread_new(struct thread *td, int pages)
+static vm_offset_t
+vm_thread_stack_create(struct domainset *ds, vm_object_t *ksobjp, int pages)
{
+ vm_page_t ma[KSTACK_MAX_PAGES];
vm_object_t ksobj;
vm_offset_t ks;
- vm_page_t ma[KSTACK_MAX_PAGES];
- struct kstack_cache_entry *ks_ce;
int i;
- /* Bounds check */
- if (pages <= 1)
- pages = kstack_pages;
- else if (pages > KSTACK_MAX_PAGES)
- pages = KSTACK_MAX_PAGES;
-
- if (pages == kstack_pages && kstack_cache != NULL) {
- 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.
*/
@@ -354,30 +341,17 @@
vm_object_deallocate(ksobj);
return (0);
}
-
- /*
- * Ensure that kstack objects can draw pages from any memory
- * domain. Otherwise a local memory shortage can block a process
- * swap-in.
- */
if (vm_ndomains > 1) {
- ksobj->domain.dr_policy = DOMAINSET_RR();
+ ksobj->domain.dr_policy = ds;
ksobj->domain.dr_iter =
atomic_fetchadd_int(&kstack_domain_iter, 1);
}
- atomic_add_int(&kstacks, 1);
if (KSTACK_GUARD_PAGES != 0) {
pmap_qremove(ks, KSTACK_GUARD_PAGES);
ks += KSTACK_GUARD_PAGES * PAGE_SIZE;
}
- td->td_kstack_obj = ksobj;
- td->td_kstack = ks;
- /*
- * 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.
@@ -389,7 +363,9 @@
ma[i]->valid = VM_PAGE_BITS_ALL;
VM_OBJECT_WUNLOCK(ksobj);
pmap_qenter(ks, ma, pages);
- return (1);
+ *ksobjp = ksobj;
+
+ return (ks);
}
static void
@@ -398,7 +374,6 @@
vm_page_t m;
int i;
- atomic_add_int(&kstacks, -1);
pmap_qremove(ks, pages);
VM_OBJECT_WLOCK(ksobj);
for (i = 0; i < pages; i++) {
@@ -417,6 +392,45 @@
}
/*
+ * Allocate the kernel stack for a new thread.
+ */
+int
+vm_thread_new(struct thread *td, int pages)
+{
+ vm_object_t ksobj;
+ vm_offset_t ks;
+
+ /* Bounds check */
+ if (pages <= 1)
+ pages = kstack_pages;
+ else if (pages > KSTACK_MAX_PAGES)
+ pages = KSTACK_MAX_PAGES;
+
+ ks = 0;
+ ksobj = NULL;
+ if (pages == kstack_pages && kstack_cache != NULL) {
+ ks = (vm_offset_t)uma_zalloc(kstack_cache, M_NOWAIT);
+ if (ks != 0)
+ ksobj = PHYS_TO_VM_PAGE(pmap_kextract(ks))->object;
+ }
+
+ /*
+ * Ensure that kstack objects can draw pages from any memory
+ * domain. Otherwise a local memory shortage can block a process
+ * swap-in.
+ */
+ if (ks == 0)
+ ks = vm_thread_stack_create(DOMAINSET_PREF(PCPU_GET(domain)),
+ &ksobj, pages);
+ if (ks == 0)
+ return (0);
+ td->td_kstack_obj = ksobj;
+ td->td_kstack = ks;
+ td->td_kstack_pages = pages;
+ return (1);
+}
+
+/*
* Dispose of a thread's kernel stack.
*/
void
@@ -424,7 +438,6 @@
{
vm_object_t ksobj;
vm_offset_t ks;
- struct kstack_cache_entry *ks_ce;
int pages;
pages = td->td_kstack_pages;
@@ -432,43 +445,49 @@
ks = td->td_kstack;
td->td_kstack = 0;
td->td_kstack_pages = 0;
- 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 = kstack_cache;
- kstack_cache = ks_ce;
- mtx_unlock(&kstack_cache_mtx);
- return;
+ if (pages == kstack_pages)
+ uma_zfree(kstack_cache, (void *)ks);
+ else
+ vm_thread_stack_dispose(ksobj, ks, pages);
+}
+
+static int
+kstack_import(void *arg, void **store, int cnt, int domain, int flags)
+{
+ vm_object_t ksobj;
+ int i;
+
+ for (i = 0; i < cnt; i++) {
+ store[i] = (void *)vm_thread_stack_create(
+ DOMAINSET_PREF(domain), &ksobj, kstack_pages);
+ if (store[i] == NULL)
+ break;
}
- vm_thread_stack_dispose(ksobj, ks, pages);
+ return (i);
}
static void
-vm_thread_stack_lowmem(void *nulll)
+kstack_release(void *arg, void **store, int cnt)
{
- struct kstack_cache_entry *ks_ce, *ks_ce1;
+ vm_offset_t ks;
+ int i;
- 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);
+ for (i = 0; i < cnt; i++) {
+ ks = (vm_offset_t)store[i];
+ vm_thread_stack_dispose(
+ PHYS_TO_VM_PAGE(pmap_kextract(ks))->object,
+ ks, kstack_pages);
}
}
static void
-kstack_cache_init(void *nulll)
+kstack_cache_init(void *null)
{
-
- EVENTHANDLER_REGISTER(vm_lowmem, vm_thread_stack_lowmem, NULL,
- EVENTHANDLER_PRI_ANY);
+ kstack_cache = uma_zcache_create("kstack_cache",
+ kstack_pages * PAGE_SIZE, NULL, NULL, NULL, NULL,
+ kstack_import, kstack_release, NULL,
+ UMA_ZONE_NUMA|UMA_ZONE_MINBUCKET);
+ uma_zone_set_maxcache(kstack_cache, kstack_cache_size);
}
SYSINIT(vm_kstacks, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY, kstack_cache_init, NULL);
Index: head/sys/vm/vm_param.h
===================================================================
--- head/sys/vm/vm_param.h
+++ head/sys/vm/vm_param.h
@@ -122,6 +122,10 @@
#endif /* !SMP */
#endif /* !PA_LOCK_COUNT */
+#ifndef KSTACK_MAX_PAGES
+#define KSTACK_MAX_PAGES 32
+#endif
+
#ifndef ASSEMBLER
#ifdef _KERNEL
#define num_pages(x) \
Index: head/sys/vm/vm_swapout.c
===================================================================
--- head/sys/vm/vm_swapout.c
+++ head/sys/vm/vm_swapout.c
@@ -85,7 +85,6 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
-#include <sys/_kstack_cache.h>
#include <sys/kthread.h>
#include <sys/ktr.h>
#include <sys/mount.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, May 2, 8:16 PM (20 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17911721
Default Alt Text
D20931.diff (10 KB)
Attached To
Mode
D20931: Cache kernel stacks in UMA so that we get NUMA support, better concurrency and statistics with less redundant code.
Attached
Detach File
Event Timeline
Log In to Comment