Skip to content

Commit c614fd6

Browse files
authored
Use new FreeBSD API to largely eliminate object locking
Propagate changes in HEAD that mostly eliminate object locking. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Matt Macy <[email protected]> Closes #10205
1 parent 9249f12 commit c614fd6

File tree

3 files changed

+56
-39
lines changed

3 files changed

+56
-39
lines changed

include/os/freebsd/spl/sys/vm.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ void zfs_vmobject_assert_wlocked(vm_object_t object);
4141
void zfs_vmobject_wlock(vm_object_t object);
4242
void zfs_vmobject_wunlock(vm_object_t object);
4343

44+
#if __FreeBSD_version >= 1300081
45+
#define zfs_vmobject_assert_wlocked_12(x)
46+
#define zfs_vmobject_wlock_12(x)
47+
#define zfs_vmobject_wunlock_12(x)
48+
#else
49+
#define zfs_vmobject_assert_wlocked_12(x) \
50+
zfs_vmobject_assert_wlocked((x))
51+
#define zfs_vmobject_wlock_12(x) \
52+
zfs_vmobject_wlock(x)
53+
#define zfs_vmobject_wunlock_12(x) \
54+
zfs_vmobject_wunlock(x)
55+
#define vm_page_grab_unlocked(obj, idx, flags) \
56+
vm_page_grab((obj), (idx), (flags))
57+
#define vm_page_grab_valid_unlocked(m, obj, idx, flags) \
58+
vm_page_grab_valid((m), (obj), (idx), (flags))
59+
#endif
4460
static inline caddr_t
4561
zfs_map_page(vm_page_t pp, struct sf_buf **sfp)
4662
{

module/os/freebsd/zfs/dmu_os.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,11 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
186186
#endif
187187

188188
vmobj = ma[0]->object;
189-
zfs_vmobject_wlock(vmobj);
189+
zfs_vmobject_wlock_12(vmobj);
190190

191191
db = dbp[0];
192192
for (i = 0; i < *rbehind; i++) {
193-
m = vm_page_grab(vmobj, ma[0]->pindex - 1 - i,
193+
m = vm_page_grab_unlocked(vmobj, ma[0]->pindex - 1 - i,
194194
VM_ALLOC_NORMAL | VM_ALLOC_NOWAIT | VM_ALLOC_BUSY_FLAGS);
195195
if (m == NULL)
196196
break;
@@ -200,7 +200,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
200200
break;
201201
}
202202
ASSERT(m->dirty == 0);
203-
ASSERT(!pmap_page_is_mapped(m));
203+
ASSERT(!pmap_page_is_write_mapped(m));
204204

205205
ASSERT(db->db_size > PAGE_SIZE);
206206
bufoff = IDX_TO_OFF(m->pindex) % db->db_size;
@@ -227,7 +227,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
227227
vm_page_assert_xbusied(m);
228228
ASSERT(vm_page_none_valid(m));
229229
ASSERT(m->dirty == 0);
230-
ASSERT(!pmap_page_is_mapped(m));
230+
ASSERT(!pmap_page_is_write_mapped(m));
231231
va = zfs_map_page(m, &sf);
232232
}
233233
}
@@ -306,7 +306,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
306306
}
307307

308308
for (i = 0; i < *rahead; i++) {
309-
m = vm_page_grab(vmobj, ma[count - 1]->pindex + 1 + i,
309+
m = vm_page_grab_unlocked(vmobj, ma[count - 1]->pindex + 1 + i,
310310
VM_ALLOC_NORMAL | VM_ALLOC_NOWAIT | VM_ALLOC_BUSY_FLAGS);
311311
if (m == NULL)
312312
break;
@@ -339,7 +339,7 @@ dmu_read_pages(objset_t *os, uint64_t object, vm_page_t *ma, int count,
339339
vm_page_do_sunbusy(m);
340340
}
341341
*rahead = i;
342-
zfs_vmobject_wunlock(vmobj);
342+
zfs_vmobject_wunlock_12(vmobj);
343343

344344
dmu_buf_rele_array(dbp, numbufs, FTAG);
345345
return (0);

module/os/freebsd/zfs/zfs_vnops.c

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes)
394394
nbytes = end - off;
395395

396396
obj = vp->v_object;
397-
zfs_vmobject_assert_wlocked(obj);
397+
zfs_vmobject_assert_wlocked_12(obj);
398398
#if __FreeBSD_version < 1300050
399399
for (;;) {
400400
if ((pp = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL &&
@@ -427,8 +427,9 @@ page_busy(vnode_t *vp, int64_t start, int64_t off, int64_t nbytes)
427427
break;
428428
}
429429
#else
430-
vm_page_grab_valid(&pp, obj, OFF_TO_IDX(start), VM_ALLOC_NOCREAT |
431-
VM_ALLOC_SBUSY | VM_ALLOC_NORMAL | VM_ALLOC_IGN_SBUSY);
430+
vm_page_grab_valid_unlocked(&pp, obj, OFF_TO_IDX(start),
431+
VM_ALLOC_NOCREAT | VM_ALLOC_SBUSY | VM_ALLOC_NORMAL |
432+
VM_ALLOC_IGN_SBUSY);
432433
if (pp != NULL) {
433434
ASSERT3U(pp->valid, ==, VM_PAGE_BITS_ALL);
434435
vm_object_pip_add(obj, 1);
@@ -460,10 +461,9 @@ page_hold(vnode_t *vp, int64_t start)
460461
vm_page_t m;
461462

462463
obj = vp->v_object;
463-
zfs_vmobject_assert_wlocked(obj);
464-
465-
vm_page_grab_valid(&m, obj, OFF_TO_IDX(start), VM_ALLOC_NOCREAT |
466-
VM_ALLOC_WIRED | VM_ALLOC_IGN_SBUSY | VM_ALLOC_NOBUSY);
464+
vm_page_grab_valid_unlocked(&m, obj, OFF_TO_IDX(start),
465+
VM_ALLOC_NOCREAT | VM_ALLOC_WIRED | VM_ALLOC_IGN_SBUSY |
466+
VM_ALLOC_NOBUSY);
467467
return (m);
468468
}
469469
#else
@@ -541,7 +541,7 @@ update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid,
541541
ASSERT(obj != NULL);
542542

543543
off = start & PAGEOFFSET;
544-
zfs_vmobject_wlock(obj);
544+
zfs_vmobject_wlock_12(obj);
545545
#if __FreeBSD_version >= 1300041
546546
vm_object_pip_add(obj, 1);
547547
#endif
@@ -550,14 +550,14 @@ update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid,
550550
int nbytes = imin(PAGESIZE - off, len);
551551

552552
if ((pp = page_busy(vp, start, off, nbytes)) != NULL) {
553-
zfs_vmobject_wunlock(obj);
553+
zfs_vmobject_wunlock_12(obj);
554554

555555
va = zfs_map_page(pp, &sf);
556556
(void) dmu_read(os, oid, start+off, nbytes,
557557
va+off, DMU_READ_PREFETCH);
558558
zfs_unmap_page(sf);
559559

560-
zfs_vmobject_wlock(obj);
560+
zfs_vmobject_wlock_12(obj);
561561
page_unbusy(pp);
562562
}
563563
len -= nbytes;
@@ -568,7 +568,7 @@ update_pages(vnode_t *vp, int64_t start, int len, objset_t *os, uint64_t oid,
568568
#else
569569
vm_object_pip_wakeupn(obj, 0);
570570
#endif
571-
zfs_vmobject_wunlock(obj);
571+
zfs_vmobject_wunlock_12(obj);
572572
}
573573

574574
/*
@@ -599,36 +599,37 @@ mappedread_sf(vnode_t *vp, int nbytes, uio_t *uio)
599599
ASSERT(obj != NULL);
600600
ASSERT((uio->uio_loffset & PAGEOFFSET) == 0);
601601

602-
zfs_vmobject_wlock(obj);
602+
zfs_vmobject_wlock_12(obj);
603603
for (start = uio->uio_loffset; len > 0; start += PAGESIZE) {
604604
int bytes = MIN(PAGESIZE, len);
605605

606-
pp = vm_page_grab(obj, OFF_TO_IDX(start), VM_ALLOC_SBUSY |
607-
VM_ALLOC_NORMAL | VM_ALLOC_IGN_SBUSY);
606+
pp = vm_page_grab_unlocked(obj, OFF_TO_IDX(start),
607+
VM_ALLOC_SBUSY | VM_ALLOC_NORMAL | VM_ALLOC_IGN_SBUSY);
608608
if (vm_page_none_valid(pp)) {
609-
zfs_vmobject_wunlock(obj);
609+
zfs_vmobject_wunlock_12(obj);
610610
va = zfs_map_page(pp, &sf);
611611
error = dmu_read(os, zp->z_id, start, bytes, va,
612612
DMU_READ_PREFETCH);
613613
if (bytes != PAGESIZE && error == 0)
614614
bzero(va + bytes, PAGESIZE - bytes);
615615
zfs_unmap_page(sf);
616-
zfs_vmobject_wlock(obj);
617-
vm_page_do_sunbusy(pp);
618-
#if __FreeBSD_version >= 1300047 && __FreeBSD_version < 1300051
619-
#error "unsupported version window"
620-
#elif __FreeBSD_version >= 1300051
616+
zfs_vmobject_wlock_12(obj);
617+
#if __FreeBSD_version >= 1300081
621618
if (error == 0) {
622619
vm_page_valid(pp);
623-
vm_page_lock(pp);
624620
vm_page_activate(pp);
625-
vm_page_unlock(pp);
621+
vm_page_do_sunbusy(pp);
622+
} else {
623+
zfs_vmobject_wlock(obj);
624+
if (!vm_page_wired(pp) && pp->valid == 0 &&
625+
vm_page_busy_tryupgrade(pp))
626+
vm_page_free(pp);
627+
else
628+
vm_page_sunbusy(pp);
629+
zfs_vmobject_wunlock(obj);
626630
}
627-
vm_page_do_sunbusy(pp);
628-
if (error != 0 && !vm_page_wired(pp) == 0 &&
629-
pp->valid == 0 && vm_page_tryxbusy(pp))
630-
vm_page_free(pp);
631631
#else
632+
vm_page_do_sunbusy(pp);
632633
vm_page_lock(pp);
633634
if (error) {
634635
if (pp->wire_count == 0 && pp->valid == 0 &&
@@ -650,7 +651,7 @@ mappedread_sf(vnode_t *vp, int nbytes, uio_t *uio)
650651
uio->uio_offset += bytes;
651652
len -= bytes;
652653
}
653-
zfs_vmobject_wunlock(obj);
654+
zfs_vmobject_wunlock_12(obj);
654655
return (error);
655656
}
656657

@@ -680,7 +681,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio)
680681

681682
start = uio->uio_loffset;
682683
off = start & PAGEOFFSET;
683-
zfs_vmobject_wlock(obj);
684+
zfs_vmobject_wlock_12(obj);
684685
for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
685686
vm_page_t pp;
686687
uint64_t bytes = MIN(PAGESIZE - off, len);
@@ -689,24 +690,24 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio)
689690
struct sf_buf *sf;
690691
caddr_t va;
691692

692-
zfs_vmobject_wunlock(obj);
693+
zfs_vmobject_wunlock_12(obj);
693694
va = zfs_map_page(pp, &sf);
694695
error = vn_io_fault_uiomove(va + off, bytes, uio);
695696
zfs_unmap_page(sf);
696-
zfs_vmobject_wlock(obj);
697+
zfs_vmobject_wlock_12(obj);
697698
page_unhold(pp);
698699
} else {
699-
zfs_vmobject_wunlock(obj);
700+
zfs_vmobject_wunlock_12(obj);
700701
error = dmu_read_uio_dbuf(sa_get_db(zp->z_sa_hdl),
701702
uio, bytes);
702-
zfs_vmobject_wlock(obj);
703+
zfs_vmobject_wlock_12(obj);
703704
}
704705
len -= bytes;
705706
off = 0;
706707
if (error)
707708
break;
708709
}
709-
zfs_vmobject_wunlock(obj);
710+
zfs_vmobject_wunlock_12(obj);
710711
return (error);
711712
}
712713

0 commit comments

Comments
 (0)