From owner-dev-commits-src-branches@freebsd.org Sat May 22 09:46:46 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 863A164927D; Sat, 22 May 2021 09:46:46 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FnJXM5tmbz3lkf; Sat, 22 May 2021 09:46:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4822E225B3; Sat, 22 May 2021 09:46:41 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 14M9kfPZ012681; Sat, 22 May 2021 09:46:41 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 14M9kfBA012680; Sat, 22 May 2021 09:46:41 GMT (envelope-from git) Date: Sat, 22 May 2021 09:46:41 GMT Message-Id: <202105220946.14M9kfBA012680@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: 2f5321c1709a - stable/13 - vm: Add KPI to dynamically register pagers MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 2f5321c1709a742edc06f7f66fe4c92828fa8a87 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 22 May 2021 09:46:46 -0000 The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=2f5321c1709a742edc06f7f66fe4c92828fa8a87 commit 2f5321c1709a742edc06f7f66fe4c92828fa8a87 Author: Konstantin Belousov AuthorDate: 2021-05-07 19:06:16 +0000 Commit: Konstantin Belousov CommitDate: 2021-05-22 09:38:30 +0000 vm: Add KPI to dynamically register pagers (cherry picked from commit b730fd30b78f502ed5dd08e5285cb2c951495d65) --- sys/vm/vm.h | 1 + sys/vm/vm_object.c | 15 +++++++++- sys/vm/vm_object.h | 1 + sys/vm/vm_pager.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++------- sys/vm/vm_pager.h | 3 ++ 5 files changed, 91 insertions(+), 11 deletions(-) diff --git a/sys/vm/vm.h b/sys/vm/vm.h index 10bf3d46f2c0..f44affac69f1 100644 --- a/sys/vm/vm.h +++ b/sys/vm/vm.h @@ -98,6 +98,7 @@ enum obj_type { OBJT_SG, OBJT_MGTDEVICE, OBJT_SWAP_TMPFS, + OBJT_FIRST_DYN, }; typedef u_char objtype_t; diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 8cb4c0006c59..73cbdfb1ece4 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -430,7 +430,8 @@ vm_object_allocate(objtype_t type, vm_pindex_t size) flags = 0; break; default: - panic("vm_object_allocate: type %d is undefined", type); + panic("vm_object_allocate: type %d is undefined or dynamic", + type); } object = (vm_object_t)uma_zalloc(obj_zone, M_WAITOK); _vm_object_allocate(type, size, flags, object, NULL); @@ -438,6 +439,18 @@ vm_object_allocate(objtype_t type, vm_pindex_t size) return (object); } +vm_object_t +vm_object_allocate_dyn(objtype_t dyntype, vm_pindex_t size, u_short flags) +{ + vm_object_t object; + + MPASS(dyntype >= OBJT_FIRST_DYN /* && dyntype < nitems(pagertab) */); + object = (vm_object_t)uma_zalloc(obj_zone, M_WAITOK); + _vm_object_allocate(dyntype, size, flags, object, NULL); + + return (object); +} + /* * vm_object_allocate_anon: * diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 0e1ed321255f..7e99288e0ff2 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -356,6 +356,7 @@ extern int umtx_shm_vnobj_persistent; vm_object_t vm_object_allocate (objtype_t, vm_pindex_t); vm_object_t vm_object_allocate_anon(vm_pindex_t, vm_object_t, struct ucred *, vm_size_t); +vm_object_t vm_object_allocate_dyn(objtype_t, vm_pindex_t, u_short); boolean_t vm_object_coalesce(vm_object_t, vm_ooffset_t, vm_size_t, vm_size_t, boolean_t); void vm_object_collapse (vm_object_t); diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c index 9476058a75bf..432a948cfe81 100644 --- a/sys/vm/vm_pager.c +++ b/sys/vm/vm_pager.c @@ -165,7 +165,7 @@ static const struct pagerops deadpagerops = { .pgo_getvp = dead_pager_getvp, }; -const struct pagerops *pagertab[] __read_mostly = { +const struct pagerops *pagertab[16] __read_mostly = { [OBJT_DEFAULT] = &defaultpagerops, [OBJT_SWAP] = &swappagerops, [OBJT_VNODE] = &vnodepagerops, @@ -176,18 +176,24 @@ const struct pagerops *pagertab[] __read_mostly = { [OBJT_MGTDEVICE] = &mgtdevicepagerops, [OBJT_SWAP_TMPFS] = &swaptmpfspagerops, }; +static struct mtx pagertab_lock; void vm_pager_init(void) { const struct pagerops **pgops; + int i; + + mtx_init(&pagertab_lock, "dynpag", NULL, MTX_DEF); /* * Initialize known pagers */ - for (pgops = pagertab; pgops < &pagertab[nitems(pagertab)]; pgops++) + for (i = 0; i < OBJT_FIRST_DYN; i++) { + pgops = &pagertab[i]; if ((*pgops)->pgo_init != NULL) (*(*pgops)->pgo_init)(); + } } static int nswbuf_max; @@ -245,15 +251,9 @@ vm_object_t vm_pager_allocate(objtype_t type, void *handle, vm_ooffset_t size, vm_prot_t prot, vm_ooffset_t off, struct ucred *cred) { - vm_object_t ret; - const struct pagerops *ops; + MPASS(type < nitems(pagertab)); - ops = pagertab[type]; - if (ops) - ret = (*ops->pgo_alloc)(handle, size, prot, off, cred); - else - ret = NULL; - return (ret); + return ((*pagertab[type]->pgo_alloc)(handle, size, prot, off, cred)); } /* @@ -264,6 +264,7 @@ vm_pager_deallocate(vm_object_t object) { VM_OBJECT_ASSERT_WLOCKED(object); + MPASS(object->type < nitems(pagertab)); (*pagertab[object->type]->pgo_dealloc) (object); } @@ -315,6 +316,7 @@ vm_pager_get_pages(vm_object_t object, vm_page_t *m, int count, int *rbehind, #endif int r; + MPASS(object->type < nitems(pagertab)); vm_pager_assert_in(object, m, count); r = (*pagertab[object->type]->pgo_getpages)(object, m, count, rbehind, @@ -348,6 +350,7 @@ vm_pager_get_pages_async(vm_object_t object, vm_page_t *m, int count, int *rbehind, int *rahead, pgo_getpages_iodone_t iodone, void *arg) { + MPASS(object->type < nitems(pagertab)); vm_pager_assert_in(object, m, count); return ((*pagertab[object->type]->pgo_getpages_async)(object, m, @@ -385,6 +388,60 @@ vm_pager_object_lookup(struct pagerlst *pg_list, void *handle) return (object); } +int +vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type) +{ + int res; + + mtx_lock(&pagertab_lock); + MPASS(base_type == -1 || + (base_type >= OBJT_DEFAULT && base_type < nitems(pagertab))); + for (res = OBJT_FIRST_DYN; res < nitems(pagertab); res++) { + if (pagertab[res] == NULL) + break; + } + if (res == nitems(pagertab)) { + mtx_unlock(&pagertab_lock); + return (-1); + } + if (base_type != -1) { + MPASS(pagertab[base_type] != NULL); +#define FIX(n) \ + if (ops->pgo_##n == NULL) \ + ops->pgo_##n = pagertab[base_type]->pgo_##n + FIX(init); + FIX(alloc); + FIX(dealloc); + FIX(getpages); + FIX(getpages_async); + FIX(putpages); + FIX(haspage); + FIX(populate); + FIX(pageunswapped); + FIX(update_writecount); + FIX(release_writecount); + FIX(set_writeable_dirty); + FIX(mightbedirty); + FIX(getvp); + FIX(freespace); +#undef FIX + } + pagertab[res] = ops; /* XXXKIB should be rel, but acq is too much */ + mtx_unlock(&pagertab_lock); + return (res); +} + +void +vm_pager_free_dyn_type(objtype_t type) +{ + MPASS(type >= OBJT_FIRST_DYN && type < nitems(pagertab)); + + mtx_lock(&pagertab_lock); + MPASS(pagertab[type] != NULL); + pagertab[type] = NULL; + mtx_unlock(&pagertab_lock); +} + static int pbuf_ctor(void *mem, int size, void *arg, int flags) { @@ -517,6 +574,8 @@ vm_object_set_writeable_dirty(vm_object_t object) { pgo_set_writeable_dirty_t *method; + MPASS(object->type < nitems(pagertab)); + method = pagertab[object->type]->pgo_set_writeable_dirty; if (method != NULL) method(object); @@ -527,6 +586,8 @@ vm_object_mightbedirty(vm_object_t object) { pgo_mightbedirty_t *method; + MPASS(object->type < nitems(pagertab)); + method = pagertab[object->type]->pgo_mightbedirty; if (method == NULL) return (false); @@ -541,6 +602,7 @@ int vm_object_kvme_type(vm_object_t object, struct vnode **vpp) { VM_OBJECT_ASSERT_LOCKED(object); + MPASS(object->type < nitems(pagertab)); if (vpp != NULL) *vpp = vm_object_vnode(object); diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h index 5e0261f818cf..098d48ea3d9d 100644 --- a/sys/vm/vm_pager.h +++ b/sys/vm/vm_pager.h @@ -249,6 +249,9 @@ vm_pager_freespace(vm_object_t object, vm_pindex_t start, method(object, start, size); } +int vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type); +void vm_pager_free_dyn_type(objtype_t type); + struct cdev_pager_ops { int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset, int prot, vm_page_t *mres);