Index: conf/files =================================================================== RCS file: /cvs/src/sys/conf/files,v diff -u -p -r1.734 files --- conf/files 13 Jul 2024 13:20:44 -0000 1.734 +++ conf/files 4 Oct 2024 00:46:42 -0000 @@ -746,6 +746,7 @@ file kern/subr_log.c file kern/subr_percpu.c file kern/subr_poison.c diagnostic file kern/subr_pool.c +file kern/subr_pond.c file kern/subr_tree.c file kern/dma_alloc.c file kern/subr_prf.c Index: sys/pond.h =================================================================== RCS file: sys/pond.h diff -N sys/pond.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/pond.h 4 Oct 2024 00:46:42 -0000 @@ -0,0 +1,48 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2024 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _SYS_POND_H_ +#define _SYS_POND_H_ + +struct pond_free_entry { + void *v; +}; + +struct pond { + struct mutex p_mtx; + const char *p_name; + + size_t p_size; + unsigned int p_align; + + unsigned int p_free_max; + unsigned int p_free_idx; + struct pond_free_entry *p_free_ring; +}; + +#ifdef _KERNEL + +void pond_init(struct pond *, size_t, u_int, int, int, + const char *, struct pool_allocator *); + +void *pond_get(struct pond *, int) __malloc; +void pond_put(struct pond *, void *); + +#endif /* _KERNEL */ + +#endif /* _SYS_POND_H_ */ Index: kern/subr_pond.c =================================================================== RCS file: kern/subr_pond.c diff -N kern/subr_pond.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ kern/subr_pond.c 4 Oct 2024 00:46:42 -0000 @@ -0,0 +1,94 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2024 David Gwynne + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define POND_FREE_MAX_DEFAULT 8192 + +void +pond_init(struct pond *pp, size_t size, u_int align, int ipl, int flags, + const char *name, struct pool_allocator *palloc) +{ + KASSERT(size <= PAGE_SIZE); + KASSERT(align == 0); + KASSERT(!ISSET(flags, PR_RWLOCK)); + KASSERT(palloc == NULL); + + mtx_init(&pp->p_mtx, ipl); + pp->p_name = name; + pp->p_size = size; + pp->p_align = align; + + pp->p_free_max = POND_FREE_MAX_DEFAULT; + pp->p_free_idx = 0; + pp->p_free_ring = mallocarray(pp->p_free_max, sizeof(*pp->p_free_ring), + M_MEMDESC, M_WAITOK|M_ZERO); +} + +void * +pond_get(struct pond *pp, int flags) +{ + const struct kmem_dyn_mode *kd; + + switch (flags & (PR_WAITOK|PR_NOWAIT)) { + case PR_WAITOK: + kd = &kd_waitok; + break; + case PR_NOWAIT: + kd = &kd_nowait; + break; + default: + panic("invalid combination of PR_WAITOK and PR_NOWAIT"); + /* NOTREACHED */ + } + + return km_alloc(PAGE_SIZE, &kv_page, + ISSET(flags, PR_ZERO) ? &kp_zero : &kp_dirty, kd); +} + +void +pond_put(struct pond *pp, void *v) +{ + void *ov; + unsigned int idx; + struct pond_free_entry *e; + vaddr_t va = (vaddr_t)v; + + pmap_protect(pmap_kernel(), va, va + PAGE_SIZE, PROT_NONE); + + mtx_enter(&pp->p_mtx); + idx = pp->p_free_idx++; + idx %= pp->p_free_max; + e = &pp->p_free_ring[idx % pp->p_free_max]; + + ov = e->v; + e->v = v; + mtx_leave(&pp->p_mtx); + + if (ov != NULL) + km_free(ov, PAGE_SIZE, &kv_page, &kp_dirty); +} Index: kern/vfs_subr.c =================================================================== RCS file: /cvs/src/sys/kern/vfs_subr.c,v diff -u -p -r1.322 vfs_subr.c --- kern/vfs_subr.c 13 Jul 2024 14:37:55 -0000 1.322 +++ kern/vfs_subr.c 4 Oct 2024 00:46:42 -0000 @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include @@ -124,7 +125,7 @@ void vfs_unmountall(void); void printlockedvnodes(void); #endif -struct pool vnode_pool; +struct pond vnode_pool; struct pool uvm_vnode_pool; static inline int rb_buf_compare(const struct buf *b1, const struct buf *b2); @@ -148,7 +149,7 @@ vntblinit(void) { /* buffer cache may need a vnode for each buffer */ maxvnodes = 2 * initialvnodes; - pool_init(&vnode_pool, sizeof(struct vnode), 0, IPL_NONE, + pond_init(&vnode_pool, sizeof(struct vnode), 0, IPL_NONE, PR_WAITOK, "vnodes", NULL); pool_init(&uvm_vnode_pool, sizeof(struct uvm_vnode), 0, IPL_NONE, PR_WAITOK, "uvmvnodes", NULL); @@ -406,7 +407,7 @@ getnewvnode(enum vtagtype tag, struct mo ((TAILQ_FIRST(listhd = &vnode_free_list) == NULL) && ((TAILQ_FIRST(listhd = &vnode_hold_list) == NULL) || toggle))) { splx(s); - vp = pool_get(&vnode_pool, PR_WAITOK | PR_ZERO); + vp = pond_get(&vnode_pool, PR_WAITOK | PR_ZERO); vp->v_uvm = pool_get(&uvm_vnode_pool, PR_WAITOK | PR_ZERO); vp->v_uvm->u_vnode = vp; uvm_obj_init(&vp->v_uvm->u_obj, &uvm_vnodeops, 0);