Revert "FreeBSD: zfs_putpages: don't undirty pages until after write completes"

This causes async putpages to leave the pages sbusied for a long time,
which hurts concurrency.  Revert for now until we have a better
approach.

This reverts commit 238eab7dc1.

Reported by:    Ihor Antonov <ngor@hugpoint.tech>
Discussed with: Rob Norris <rob.norris@klarasystems.com>

References: freebsd/freebsd-src@738a9a7
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Reviewed-by: Mark Johnston <markj@FreeBSD.org>
Ported-by: Rob Norris <rob.norris@klarasystems.com>
Signed-off-by: Rob Norris <rob.norris@klarasystems.com>
Closes #17533
This commit is contained in:
Mark Johnston 2025-06-28 02:32:16 +00:00 committed by Alexander Motin
parent 0fe10361ba
commit a072611eef
3 changed files with 15 additions and 47 deletions

View File

@ -35,7 +35,6 @@
extern const int zfs_vm_pagerret_bad; extern const int zfs_vm_pagerret_bad;
extern const int zfs_vm_pagerret_error; extern const int zfs_vm_pagerret_error;
extern const int zfs_vm_pagerret_ok; extern const int zfs_vm_pagerret_ok;
extern const int zfs_vm_pagerret_pend;
extern const int zfs_vm_pagerput_sync; extern const int zfs_vm_pagerput_sync;
extern const int zfs_vm_pagerput_inval; extern const int zfs_vm_pagerput_inval;

View File

@ -43,7 +43,6 @@
const int zfs_vm_pagerret_bad = VM_PAGER_BAD; const int zfs_vm_pagerret_bad = VM_PAGER_BAD;
const int zfs_vm_pagerret_error = VM_PAGER_ERROR; const int zfs_vm_pagerret_error = VM_PAGER_ERROR;
const int zfs_vm_pagerret_ok = VM_PAGER_OK; const int zfs_vm_pagerret_ok = VM_PAGER_OK;
const int zfs_vm_pagerret_pend = VM_PAGER_PEND;
const int zfs_vm_pagerput_sync = VM_PAGER_PUT_SYNC; const int zfs_vm_pagerput_sync = VM_PAGER_PUT_SYNC;
const int zfs_vm_pagerput_inval = VM_PAGER_PUT_INVAL; const int zfs_vm_pagerput_inval = VM_PAGER_PUT_INVAL;

View File

@ -25,7 +25,6 @@
* Copyright (c) 2012, 2015 by Delphix. All rights reserved. * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com] * Copyright (c) 2014 Integros [integros.com]
* Copyright 2017 Nexenta Systems, Inc. * Copyright 2017 Nexenta Systems, Inc.
* Copyright (c) 2025, Klara, Inc.
*/ */
/* Portions Copyright 2007 Jeremy Teo */ /* Portions Copyright 2007 Jeremy Teo */
@ -4085,33 +4084,6 @@ zfs_freebsd_getpages(struct vop_getpages_args *ap)
ap->a_rahead)); ap->a_rahead));
} }
typedef struct {
uint_t pca_npages;
vm_page_t pca_pages[];
} putpage_commit_arg_t;
static void
zfs_putpage_commit_cb(void *arg)
{
putpage_commit_arg_t *pca = arg;
vm_object_t object = pca->pca_pages[0]->object;
zfs_vmobject_wlock(object);
for (uint_t i = 0; i < pca->pca_npages; i++) {
vm_page_t pp = pca->pca_pages[i];
vm_page_undirty(pp);
vm_page_sunbusy(pp);
}
vm_object_pip_wakeupn(object, pca->pca_npages);
zfs_vmobject_wunlock(object);
kmem_free(pca,
offsetof(putpage_commit_arg_t, pca_pages[pca->pca_npages]));
}
static int static int
zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags, zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags,
int *rtvals) int *rtvals)
@ -4213,12 +4185,10 @@ zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags,
} }
if (zp->z_blksz < PAGE_SIZE) { if (zp->z_blksz < PAGE_SIZE) {
vm_ooffset_t woff = off; for (i = 0; len > 0; off += tocopy, len -= tocopy, i++) {
size_t wlen = len; tocopy = len > PAGE_SIZE ? PAGE_SIZE : len;
for (i = 0; wlen > 0; woff += tocopy, wlen -= tocopy, i++) {
tocopy = MIN(PAGE_SIZE, wlen);
va = zfs_map_page(ma[i], &sf); va = zfs_map_page(ma[i], &sf);
dmu_write(zfsvfs->z_os, zp->z_id, woff, tocopy, va, tx); dmu_write(zfsvfs->z_os, zp->z_id, off, tocopy, va, tx);
zfs_unmap_page(sf); zfs_unmap_page(sf);
} }
} else { } else {
@ -4239,19 +4209,19 @@ zfs_putpages(struct vnode *vp, vm_page_t *ma, size_t len, int flags,
zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime); zfs_tstamp_update_setup(zp, CONTENT_MODIFIED, mtime, ctime);
err = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); err = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
ASSERT0(err); ASSERT0(err);
/*
* XXX we should be passing a callback to undirty
* but that would make the locking messier
*/
zfs_log_write(zfsvfs->z_log, tx, TX_WRITE, zp, off,
len, commit, B_FALSE, NULL, NULL);
putpage_commit_arg_t *pca = kmem_alloc( zfs_vmobject_wlock(object);
offsetof(putpage_commit_arg_t, pca_pages[ncount]), for (i = 0; i < ncount; i++) {
KM_SLEEP); rtvals[i] = zfs_vm_pagerret_ok;
pca->pca_npages = ncount; vm_page_undirty(ma[i]);
memcpy(pca->pca_pages, ma, sizeof (vm_page_t) * ncount); }
zfs_vmobject_wunlock(object);
zfs_log_write(zfsvfs->z_log, tx, TX_WRITE, zp,
off, len, commit, B_FALSE, zfs_putpage_commit_cb, pca);
for (i = 0; i < ncount; i++)
rtvals[i] = zfs_vm_pagerret_pend;
VM_CNT_INC(v_vnodeout); VM_CNT_INC(v_vnodeout);
VM_CNT_ADD(v_vnodepgsout, ncount); VM_CNT_ADD(v_vnodepgsout, ncount);
} }