Module Name: src Committed By: thorpej Date: Sun Dec 3 19:34:08 UTC 2023
Modified Files: src/sys/kern: subr_vmem.c src/sys/sys: vmem.h vmem_impl.h Log Message: Add the notion of "private boundary tags" to vmem. This allows vmem to be used VERY early in boot; such consumers statically allocate the vmem arena and boundary tags, and then explicitly add those static, private boundary tags to the arena tag free list using the new function vmem_add_bts(). Vmem arenas that use private boundary tags will NOT consume the statically allocated bootstrap tags used by the vmem system itself; the assumption is that the consumer of such an arena knows what they're doing, and is responsible for all necessary resource management. A macro, VMEM_EST_BTCOUNT(), is provided to help such consumers size the static boundary tag store based on the expected number of spans and early allocations. Once the private tags are exhausted, the arena will dynamically allocate tags as usual. To generate a diff of this commit: cvs rdiff -u -r1.114 -r1.115 src/sys/kern/subr_vmem.c cvs rdiff -u -r1.24 -r1.25 src/sys/sys/vmem.h cvs rdiff -u -r1.7 -r1.8 src/sys/sys/vmem_impl.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_vmem.c diff -u src/sys/kern/subr_vmem.c:1.114 src/sys/kern/subr_vmem.c:1.115 --- src/sys/kern/subr_vmem.c:1.114 Sun Dec 3 15:06:45 2023 +++ src/sys/kern/subr_vmem.c Sun Dec 3 19:34:08 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_vmem.c,v 1.114 2023/12/03 15:06:45 thorpej Exp $ */ +/* $NetBSD: subr_vmem.c,v 1.115 2023/12/03 19:34:08 thorpej Exp $ */ /*- * Copyright (c)2006,2007,2008,2009 YAMAMOTO Takashi, @@ -46,7 +46,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.114 2023/12/03 15:06:45 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_vmem.c,v 1.115 2023/12/03 19:34:08 thorpej Exp $"); #if defined(_KERNEL) && defined(_KERNEL_OPT) #include "opt_ddb.h" @@ -252,7 +252,8 @@ bt_refill_locked(vmem_t *vm) mutex_enter(&vmem_btag_lock); while (!LIST_EMPTY(&vmem_btag_freelist) && - vm->vm_nfreetags <= BT_MINRESERVE) { + vm->vm_nfreetags <= BT_MINRESERVE && + (vm->vm_flags & VM_PRIVTAGS) == 0) { bt = LIST_FIRST(&vmem_btag_freelist); LIST_REMOVE(bt, bt_freelist); bt->bt_flags = 0; @@ -360,6 +361,9 @@ bt_freetrim(vmem_t *vm, int freelimit) if (vm->vm_nfreetags <= freelimit) { break; } + if (bt->bt_flags & BT_F_PRIVATE) { + continue; + } LIST_REMOVE(bt, bt_freelist); vm->vm_nfreetags--; if (bt >= static_bts @@ -381,6 +385,24 @@ bt_freetrim(vmem_t *vm, int freelimit) pool_put(&vmem_btag_pool, bt); } } + +/* + * Add private boundary tags (statically-allocated by the caller) + * to a vmem arena's free tag list. + */ +void +vmem_add_bts(vmem_t *vm, struct vmem_btag *bts, unsigned int nbts) +{ + VMEM_LOCK(vm); + while (nbts != 0) { + bts->bt_flags = BT_F_PRIVATE; + LIST_INSERT_HEAD(&vm->vm_freetags, bts, bt_freelist); + vm->vm_nfreetags++; + bts++; + nbts--; + } + VMEM_UNLOCK(vm); +} #endif /* defined(_KERNEL) */ /* Index: src/sys/sys/vmem.h diff -u src/sys/sys/vmem.h:1.24 src/sys/sys/vmem.h:1.25 --- src/sys/sys/vmem.h:1.24 Sat Dec 2 21:02:12 2023 +++ src/sys/sys/vmem.h Sun Dec 3 19:34:08 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: vmem.h,v 1.24 2023/12/02 21:02:12 thorpej Exp $ */ +/* $NetBSD: vmem.h,v 1.25 2023/12/03 19:34:08 thorpej Exp $ */ /*- * Copyright (c)2006 YAMAMOTO Takashi, @@ -93,6 +93,7 @@ void vmem_printall(const char *, void ( #define VM_POPULATING 0x00040000 #define VM_LARGEIMPORT 0x00080000 #define VM_XIMPORT 0x00100000 +#define VM_PRIVTAGS 0x00200000 /* vmem_size typemask */ #define VMEM_ALLOC 0x01 Index: src/sys/sys/vmem_impl.h diff -u src/sys/sys/vmem_impl.h:1.7 src/sys/sys/vmem_impl.h:1.8 --- src/sys/sys/vmem_impl.h:1.7 Sun Dec 3 15:06:45 2023 +++ src/sys/sys/vmem_impl.h Sun Dec 3 19:34:08 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: vmem_impl.h,v 1.7 2023/12/03 15:06:45 thorpej Exp $ */ +/* $NetBSD: vmem_impl.h,v 1.8 2023/12/03 19:34:08 thorpej Exp $ */ /*- * Copyright (c)2006 YAMAMOTO Takashi, @@ -138,10 +138,22 @@ struct vmem_btag { #define BT_TYPE_BUSY 4 #define BT_ISSPAN_P(bt) ((bt)->bt_type <= BT_TYPE_SPAN_STATIC) +#define BT_F_PRIVATE 0x0001 + #define BT_END(bt) ((bt)->bt_start + (bt)->bt_size - 1) +/* + * Provide an estimated number of boundary tags needed for a given + * number of allocations from the vmem arena. This estimate is + * based on 2 boundary tags per allocation (see vmem_xalloc()) and + * 2 boundary tags per added span (one to describe the span, one to + * describe the span's free space; see vmem_add1()). + */ +#define VMEM_EST_BTCOUNT(ns, na) (((ns) * 2) + ((na) * 2)) + vmem_t * vmem_init(vmem_t *, const char *, vmem_addr_t, vmem_size_t, vmem_size_t, vmem_import_t *, vmem_release_t *, vmem_t *, vmem_size_t, vm_flag_t, int); +void vmem_add_bts(vmem_t *, struct vmem_btag *, unsigned int); #endif /* !_SYS_VMEM_IMPL_H_ */