summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2020-06-02 11:42:39 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2020-06-02 11:42:39 +0000
commitacc9d73392734e746e249c426a1558b911389dfb (patch)
treed7fd81266a9a2c842c257909e78eed5e1dc4e4cd
parent5cd90a78a9b9930e642ce913b44316f5a4ae6632 (diff)
parentb39b008f8a57ea7ddfd0f69b24529deba7c25ae1 (diff)
downloadillumos-joyent-acc9d73392734e746e249c426a1558b911389dfb.tar.gz
[illumos-gate merge]
commit b39b008f8a57ea7ddfd0f69b24529deba7c25ae1 12783 async unlinked drain races with ZFS unmount commit 94bce860c16a04a3d8eaeaa18807723c026e23b5 12559 zs: NULL pointer errors commit fdf1a8710a94b4953ba782ed5bdc1549b0356ddc 12804 sysevent.h: C++11 requires a space between string literal and macro commit e86372a01d2d16a5dd4a64e144ed978ba17fe7dd 12668 ZFS support for vectorized algorithms on x86 (initial support) commit 82049ff560eed6fbdf4cf222d894467f5809f9b3 12119 ndmpd: cast between incompatible function types commit 8e3a263e496f0b896b62a8ebe101c0b2b56c9a15 12750 bhyve should not hold HMA registration with no running VMs commit d0b3c59ba652f183eeec1414dd9fbdc56bf05cc8 12775 reorganize bhyve contrib headers commit e213fe2d75a0e47cc0b3f67c473e24dfa9304e0b 12545 ixgbe: IXGBE_LE32_TO_CPUS macro is missing assignment
-rw-r--r--exception_lists/check_rtime1
-rw-r--r--exception_lists/copyright9
-rw-r--r--exception_lists/cstyle8
-rw-r--r--exception_lists/hdrchk7
-rw-r--r--exception_lists/wscheck8
-rw-r--r--usr/src/Makefile.master2
-rw-r--r--usr/src/cmd/Makefile3
-rw-r--r--usr/src/cmd/bhyve/Makefile8
-rw-r--r--usr/src/cmd/bhyve/test/Makefile.com8
-rw-r--r--usr/src/cmd/bhyvectl/Makefile6
-rw-r--r--usr/src/cmd/ndmpd/include/tlm.h12
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd.h6
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_common.h6
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_data.c15
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c52
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c37
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c50
-rw-r--r--usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c89
-rw-r--r--usr/src/cmd/ndmpd/tlm/tlm_proto.h6
-rw-r--r--usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c21
-rw-r--r--usr/src/cmd/raidz_test/Makefile61
-rw-r--r--usr/src/cmd/raidz_test/raidz_bench.c228
-rw-r--r--usr/src/cmd/raidz_test/raidz_test.c761
-rw-r--r--usr/src/cmd/raidz_test/raidz_test.h117
-rw-r--r--usr/src/compat/bhyve/README9
-rw-r--r--usr/src/compat/bhyve/amd64/machine/asmacros.h (renamed from usr/src/compat/freebsd/amd64/machine/asmacros.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/atomic.h (renamed from usr/src/compat/freebsd/amd64/machine/atomic.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/clock.h (renamed from usr/src/compat/freebsd/amd64/machine/clock.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/cpu.h (renamed from usr/src/compat/freebsd/amd64/machine/cpu.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/cpufunc.h (renamed from usr/src/compat/freebsd/amd64/machine/cpufunc.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/fpu.h (renamed from usr/src/compat/freebsd/amd64/machine/fpu.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/iodev.h (renamed from usr/src/compat/freebsd/amd64/machine/iodev.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/md_var.h (renamed from usr/src/compat/freebsd/amd64/machine/md_var.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/param.h (renamed from usr/src/compat/freebsd/amd64/machine/param.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/pcb.h (renamed from usr/src/compat/freebsd/amd64/machine/pcb.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/pmap.h (renamed from usr/src/compat/freebsd/amd64/machine/pmap.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/reg.h (renamed from usr/src/compat/freebsd/amd64/machine/reg.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/segments.h (renamed from usr/src/compat/freebsd/amd64/machine/segments.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/smp.h (renamed from usr/src/compat/freebsd/amd64/machine/smp.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/specialreg.h (renamed from usr/src/compat/freebsd/amd64/machine/specialreg.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/vmm.h (renamed from usr/src/compat/freebsd/amd64/machine/vmm.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/vmm_dev.h (renamed from usr/src/compat/freebsd/amd64/machine/vmm_dev.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/vmm_instruction_emul.h (renamed from usr/src/compat/freebsd/amd64/machine/vmm_instruction_emul.h)0
-rw-r--r--usr/src/compat/bhyve/amd64/machine/vmparam.h (renamed from usr/src/compat/freebsd/amd64/machine/vmparam.h)0
-rw-r--r--usr/src/compat/bhyve/contrib/dev/acpica/include/acpi.h (renamed from usr/src/compat/freebsd/contrib/dev/acpica/include/acpi.h)0
-rw-r--r--usr/src/compat/bhyve/dev/pci/pcivar.h (renamed from usr/src/compat/freebsd/dev/pci/pcivar.h)0
-rw-r--r--usr/src/compat/bhyve/err.h (renamed from usr/src/compat/freebsd/err.h)0
-rw-r--r--usr/src/compat/bhyve/libutil.h (renamed from usr/src/compat/freebsd/libutil.h)0
-rw-r--r--usr/src/compat/bhyve/net/ethernet.h (renamed from usr/src/compat/freebsd/net/ethernet.h)0
-rw-r--r--usr/src/compat/bhyve/net/ieee_oui.h (renamed from usr/src/compat/freebsd/net/ieee_oui.h)0
-rw-r--r--usr/src/compat/bhyve/paths.h (renamed from usr/src/compat/freebsd/paths.h)0
-rw-r--r--usr/src/compat/bhyve/pthread_np.h (renamed from usr/src/compat/freebsd/pthread_np.h)0
-rw-r--r--usr/src/compat/bhyve/string.h (renamed from usr/src/compat/freebsd/string.h)0
-rw-r--r--usr/src/compat/bhyve/strings.h (renamed from usr/src/compat/freebsd/strings.h)0
-rw-r--r--usr/src/compat/bhyve/sys/_cpuset.h (renamed from usr/src/compat/freebsd/sys/_cpuset.h)0
-rw-r--r--usr/src/compat/bhyve/sys/_iovec.h (renamed from usr/src/compat/freebsd/sys/_iovec.h)0
-rw-r--r--usr/src/compat/bhyve/sys/_pthreadtypes.h (renamed from usr/src/compat/freebsd/sys/_pthreadtypes.h)0
-rw-r--r--usr/src/compat/bhyve/sys/_types.h (renamed from usr/src/compat/freebsd/sys/_types.h)0
-rw-r--r--usr/src/compat/bhyve/sys/bus.h (renamed from usr/src/compat/freebsd/sys/bus.h)0
-rw-r--r--usr/src/compat/bhyve/sys/callout.h (renamed from usr/src/compat/freebsd/sys/callout.h)0
-rw-r--r--usr/src/compat/bhyve/sys/cdefs.h (renamed from usr/src/compat/freebsd/sys/cdefs.h)0
-rw-r--r--usr/src/compat/bhyve/sys/clock.h (renamed from usr/src/compat/freebsd/sys/clock.h)0
-rw-r--r--usr/src/compat/bhyve/sys/cpuset.h (renamed from usr/src/compat/freebsd/sys/cpuset.h)0
-rw-r--r--usr/src/compat/bhyve/sys/disk.h (renamed from usr/src/compat/freebsd/sys/disk.h)0
-rw-r--r--usr/src/compat/bhyve/sys/endian.h (renamed from usr/src/compat/freebsd/sys/endian.h)0
-rw-r--r--usr/src/compat/bhyve/sys/errno.h (renamed from usr/src/compat/freebsd/sys/errno.h)0
-rw-r--r--usr/src/compat/bhyve/sys/eventhandler.h (renamed from usr/src/compat/freebsd/sys/eventhandler.h)0
-rw-r--r--usr/src/compat/bhyve/sys/fcntl.h (renamed from usr/src/compat/freebsd/sys/fcntl.h)0
-rw-r--r--usr/src/compat/bhyve/sys/ioctl.h (renamed from usr/src/compat/freebsd/sys/ioctl.h)0
-rw-r--r--usr/src/compat/bhyve/sys/kernel.h (renamed from usr/src/compat/freebsd/sys/kernel.h)0
-rw-r--r--usr/src/compat/bhyve/sys/ktr.h (renamed from usr/src/compat/freebsd/sys/ktr.h)0
-rw-r--r--usr/src/compat/bhyve/sys/libkern.h (renamed from usr/src/compat/freebsd/sys/libkern.h)0
-rw-r--r--usr/src/compat/bhyve/sys/limits.h (renamed from usr/src/compat/freebsd/sys/limits.h)0
-rw-r--r--usr/src/compat/bhyve/sys/lock.h (renamed from usr/src/compat/freebsd/sys/lock.h)0
-rw-r--r--usr/src/compat/bhyve/sys/malloc.h (renamed from usr/src/compat/freebsd/sys/malloc.h)0
-rw-r--r--usr/src/compat/bhyve/sys/module.h (renamed from usr/src/compat/freebsd/sys/module.h)0
-rw-r--r--usr/src/compat/bhyve/sys/mutex.h (renamed from usr/src/compat/freebsd/sys/mutex.h)0
-rw-r--r--usr/src/compat/bhyve/sys/param.h (renamed from usr/src/compat/freebsd/sys/param.h)0
-rw-r--r--usr/src/compat/bhyve/sys/pcpu.h (renamed from usr/src/compat/freebsd/sys/pcpu.h)0
-rw-r--r--usr/src/compat/bhyve/sys/sched.h (renamed from usr/src/compat/freebsd/sys/sched.h)0
-rw-r--r--usr/src/compat/bhyve/sys/sdt.h (renamed from usr/src/compat/freebsd/sys/sdt.h)0
-rw-r--r--usr/src/compat/bhyve/sys/select.h (renamed from usr/src/compat/freebsd/sys/select.h)0
-rw-r--r--usr/src/compat/bhyve/sys/sglist.h (renamed from usr/src/compat/freebsd/sys/sglist.h)0
-rw-r--r--usr/src/compat/bhyve/sys/smp.h (renamed from usr/src/compat/freebsd/sys/smp.h)0
-rw-r--r--usr/src/compat/bhyve/sys/socket.h (renamed from usr/src/compat/freebsd/sys/socket.h)0
-rw-r--r--usr/src/compat/bhyve/sys/sysctl.h (renamed from usr/src/compat/freebsd/sys/sysctl.h)0
-rw-r--r--usr/src/compat/bhyve/sys/systm.h (renamed from usr/src/compat/freebsd/sys/systm.h)0
-rw-r--r--usr/src/compat/bhyve/sys/time.h (renamed from usr/src/compat/freebsd/sys/time.h)0
-rw-r--r--usr/src/compat/bhyve/sys/types.h (renamed from usr/src/compat/freebsd/sys/types.h)0
-rw-r--r--usr/src/compat/bhyve/sys/uio.h (renamed from usr/src/compat/freebsd/sys/uio.h)0
-rw-r--r--usr/src/compat/bhyve/termios.h (renamed from usr/src/compat/freebsd/termios.h)0
-rw-r--r--usr/src/compat/bhyve/unistd.h (renamed from usr/src/compat/freebsd/unistd.h)0
-rw-r--r--usr/src/compat/bhyve/uuid.h (renamed from usr/src/compat/freebsd/uuid.h)0
-rw-r--r--usr/src/compat/bhyve/vm/vm.h (renamed from usr/src/compat/freebsd/vm/vm.h)0
-rw-r--r--usr/src/compat/bhyve/vm/vm_param.h (renamed from usr/src/compat/freebsd/vm/vm_param.h)0
-rw-r--r--usr/src/compat/bhyve/x86/_types.h (renamed from usr/src/compat/freebsd/x86/_types.h)0
-rw-r--r--usr/src/compat/bhyve/x86/segments.h (renamed from usr/src/compat/freebsd/x86/segments.h)0
-rw-r--r--usr/src/contrib/bhyve/README12
-rw-r--r--usr/src/contrib/bhyve/amd64/machine/_types.h (renamed from usr/contrib/freebsd/amd64/machine/_types.h)0
-rw-r--r--usr/src/contrib/bhyve/amd64/machine/pmap.h (renamed from usr/contrib/freebsd/amd64/machine/pmap.h)0
-rw-r--r--usr/src/contrib/bhyve/amd64/machine/psl.h (renamed from usr/contrib/freebsd/amd64/machine/psl.h)0
-rw-r--r--usr/src/contrib/bhyve/amd64/machine/timerreg.h (renamed from usr/contrib/freebsd/amd64/machine/timerreg.h)0
-rw-r--r--usr/src/contrib/bhyve/amd64/machine/vm.h (renamed from usr/contrib/freebsd/amd64/machine/vm.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/acpica/acpi_hpet.h (renamed from usr/contrib/freebsd/dev/acpica/acpi_hpet.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/ic/i8253reg.h (renamed from usr/contrib/freebsd/dev/ic/i8253reg.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/ic/i8259.h (renamed from usr/contrib/freebsd/dev/ic/i8259.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/ic/ns16550.h (renamed from usr/contrib/freebsd/dev/ic/ns16550.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/io/iodev.h (renamed from usr/contrib/freebsd/dev/io/iodev.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/mii/mii.h (renamed from usr/contrib/freebsd/dev/mii/mii.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/nvme/nvme.h (renamed from usr/contrib/freebsd/dev/nvme/nvme.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/pci/pcireg.h (renamed from usr/contrib/freebsd/dev/pci/pcireg.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/usb/controller/xhcireg.h (renamed from usr/contrib/freebsd/dev/usb/controller/xhcireg.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/usb/usb.h (renamed from usr/contrib/freebsd/dev/usb/usb.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/usb/usb_endian.h (renamed from usr/contrib/freebsd/dev/usb/usb_endian.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/usb/usb_freebsd.h (renamed from usr/contrib/freebsd/dev/usb/usb_freebsd.h)0
-rw-r--r--usr/src/contrib/bhyve/dev/usb/usbdi.h (renamed from usr/contrib/freebsd/dev/usb/usbdi.h)0
-rw-r--r--usr/src/contrib/bhyve/isa/isareg.h (renamed from usr/contrib/freebsd/isa/isareg.h)0
-rw-r--r--usr/src/contrib/bhyve/isa/rtc.h (renamed from usr/contrib/freebsd/isa/rtc.h)0
-rw-r--r--usr/src/contrib/bhyve/lib/libutil/expand_number.c (renamed from usr/contrib/freebsd/lib/libutil/expand_number.c)0
-rw-r--r--usr/src/contrib/bhyve/lib/libutil/humanize_number.c (renamed from usr/contrib/freebsd/lib/libutil/humanize_number.c)0
-rw-r--r--usr/src/contrib/bhyve/sys/ata.h (renamed from usr/contrib/freebsd/sys/ata.h)0
-rw-r--r--usr/src/contrib/bhyve/sys/pciio.h (renamed from usr/contrib/freebsd/sys/pciio.h)0
-rw-r--r--usr/src/contrib/bhyve/sys/queue.h (renamed from usr/contrib/freebsd/sys/queue.h)0
-rw-r--r--usr/src/contrib/bhyve/sys/tree.h (renamed from usr/contrib/freebsd/sys/tree.h)0
-rw-r--r--usr/src/contrib/bhyve/x86/apicreg.h (renamed from usr/contrib/freebsd/x86/apicreg.h)0
-rw-r--r--usr/src/contrib/bhyve/x86/mptable.h (renamed from usr/contrib/freebsd/x86/mptable.h)0
-rw-r--r--usr/src/contrib/bhyve/x86/psl.h (renamed from usr/contrib/freebsd/x86/psl.h)0
-rw-r--r--usr/src/contrib/bhyve/x86/segments.h (renamed from usr/contrib/freebsd/x86/segments.h)0
-rw-r--r--usr/src/contrib/bhyve/x86/specialreg.h (renamed from usr/contrib/freebsd/x86/specialreg.h)0
-rw-r--r--usr/src/lib/libvmm/Makefile.com4
-rw-r--r--usr/src/lib/libvmmapi/Makefile.com4
-rw-r--r--usr/src/lib/libvmmapi/amd64/Makefile2
-rw-r--r--usr/src/pkg/manifests/system-file-system-zfs-tests.mf2
-rw-r--r--usr/src/pkg/manifests/system-test-zfstest.mf5
-rw-r--r--usr/src/req.flg2
-rw-r--r--usr/src/test/zfs-tests/include/commands.cfg3
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run3
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run3
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run3
-rw-r--r--usr/src/test/zfs-tests/runfiles/smartos.run3
-rw-r--r--usr/src/test/zfs-tests/tests/functional/raidz/Makefile21
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/raidz/cleanup.ksh30
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/raidz/raidz_001_neg.ksh38
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/raidz/raidz_002_pos.ksh41
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/raidz/setup.ksh32
-rw-r--r--usr/src/uts/common/Makefile.files2
-rw-r--r--usr/src/uts/common/fs/zfs/abd.c181
-rw-r--r--usr/src/uts/common/fs/zfs/spa_misc.c3
-rw-r--r--usr/src/uts/common/fs/zfs/sys/abd.h9
-rw-r--r--usr/src/uts/common/fs/zfs/sys/simd.h40
-rw-r--r--usr/src/uts/common/fs/zfs/sys/vdev_raidz.h65
-rw-r--r--usr/src/uts/common/fs/zfs/sys/vdev_raidz_impl.h351
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_raidz.c265
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_raidz_math.c571
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_raidz_math_impl.h1477
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_raidz_math_scalar.c337
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c39
-rw-r--r--usr/src/uts/common/io/ixgbe/ixgbe_osdep.h2
-rw-r--r--usr/src/uts/common/sys/sysevent.h2
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c99
-rw-r--r--usr/src/uts/i86pc/ppt/Makefile4
-rw-r--r--usr/src/uts/i86pc/vmm/Makefile4
-rw-r--r--usr/src/uts/req.flg4
-rw-r--r--usr/src/uts/sun/io/zs_async.c143
-rw-r--r--usr/src/uts/sun/io/zs_common.c14
-rw-r--r--usr/src/uts/sun4u/zs/Makefile22
166 files changed, 4865 insertions, 507 deletions
diff --git a/exception_lists/check_rtime b/exception_lists/check_rtime
index 3d5e7bf491..308d0e35d4 100644
--- a/exception_lists/check_rtime
+++ b/exception_lists/check_rtime
@@ -232,6 +232,7 @@ FORBIDDEN libfakekernel\.so
FORBIDDEN_DEP usr/MACH(lib)/libzpool.so.1
FORBIDDEN_DEP usr/bin/amd64/ztest
FORBIDDEN_DEP usr/bin/i86/ztest
+FORBIDDEN_DEP usr/bin/raidz_test
FORBIDDEN_DEP usr/bin/sparcv7/ztest
FORBIDDEN_DEP usr/bin/sparcv9/ztest
FORBIDDEN_DEP usr/lib/MACH(smbfs)/libfknsmb.so.1
diff --git a/exception_lists/copyright b/exception_lists/copyright
index 354f7fb236..45c53c793c 100644
--- a/exception_lists/copyright
+++ b/exception_lists/copyright
@@ -546,14 +546,9 @@ usr/src/cmd/bhyve/vga.[ch]
usr/src/cmd/bhyve/virtio.[ch]
usr/src/cmd/bhyve/xmsr.[ch]
usr/src/cmd/bhyvectl/bhyvectl.c
-usr/src/compat/freebsd/*.h
-usr/src/compat/freebsd/*/*.h
-usr/src/compat/freebsd/amd64/machine/*.h
-usr/contrib/freebsd/*/*.h
-usr/contrib/freebsd/*/*/*.h
-usr/contrib/freebsd/lib/libutil/*.c
+usr/src/compat/bhyve/*
+usr/src/contrib/bhyve/*
usr/src/lib/libvmmapi/common/vmmapi.[ch]
-usr/src/tools/scripts/gensetdefs.pl
usr/src/uts/i86pc/io/vmm/amd/*.[chs]
usr/src/uts/i86pc/io/vmm/intel/*.[chs]
usr/src/uts/i86pc/io/vmm/intel/offsets.in
diff --git a/exception_lists/cstyle b/exception_lists/cstyle
index b7f0327ffe..35d79e7c69 100644
--- a/exception_lists/cstyle
+++ b/exception_lists/cstyle
@@ -1422,12 +1422,8 @@ usr/src/cmd/bhyve/virtio.[ch]
usr/src/cmd/bhyve/xmsr.[ch]
usr/src/cmd/bhyveconsole/bhyveconsole.c
usr/src/cmd/bhyvectl/bhyvectl.c
-usr/src/compat/freebsd/*.h
-usr/src/compat/freebsd/*/*.h
-usr/src/compat/freebsd/amd64/machine/*.h
-usr/contrib/freebsd/*/*.h
-usr/contrib/freebsd/*/*/*.h
-usr/contrib/freebsd/lib/libutil/*.c
+usr/src/compat/bhyve/*
+usr/src/contrib/bhyve/*
usr/src/lib/libvmmapi/common/vmmapi.[ch]
usr/src/uts/i86pc/io/vmm/amd/*.[ch]
usr/src/uts/i86pc/io/vmm/intel/*.[chs]
diff --git a/exception_lists/hdrchk b/exception_lists/hdrchk
index c6a5ffe4d3..e80a93515d 100644
--- a/exception_lists/hdrchk
+++ b/exception_lists/hdrchk
@@ -418,11 +418,8 @@ usr/src/cmd/bhyve/uart_emul.h
usr/src/cmd/bhyve/vga.h
usr/src/cmd/bhyve/virtio.h
usr/src/cmd/bhyve/xmsr.h
-usr/src/compat/freebsd/*.h
-usr/src/compat/freebsd/*/*.h
-usr/src/compat/freebsd/amd64/machine/*.h
-usr/contrib/freebsd/*/*.h
-usr/contrib/freebsd/*/*/*.h
+usr/src/compat/bhyve/*
+usr/src/contrib/bhyve/*
usr/src/lib/libvmmapi/common/vmmapi.h
usr/src/uts/i86pc/io/vmm/intel/*.h
usr/src/uts/i86pc/io/vmm/io/*.h
diff --git a/exception_lists/wscheck b/exception_lists/wscheck
index ea93389a01..cfba871041 100644
--- a/exception_lists/wscheck
+++ b/exception_lists/wscheck
@@ -176,12 +176,8 @@ usr/src/cmd/bhyve/virtio.[ch]
usr/src/cmd/bhyve/xmsr.[ch]
usr/src/cmd/bhyveconsole/bhyveconsole.c
usr/src/cmd/bhyvectl/bhyvectl.c
-usr/src/compat/freebsd/*.h
-usr/src/compat/freebsd/*/*.h
-usr/src/compat/freebsd/amd64/machine/*.h
-usr/contrib/freebsd/*/*.h
-usr/contrib/freebsd/*/*/*.h
-usr/contrib/freebsd/lib/libutil/*.c
+usr/src/compat/bhyve/*
+usr/src/contrib/bhyve/*
usr/src/lib/libvmmapi/common/vmmapi.[ch]
usr/src/uts/i86pc/io/vmm/amd/*.[ch]
usr/src/uts/i86pc/io/vmm/intel/*.[chs]
diff --git a/usr/src/Makefile.master b/usr/src/Makefile.master
index 7c036ac21a..7dc553209d 100644
--- a/usr/src/Makefile.master
+++ b/usr/src/Makefile.master
@@ -61,7 +61,7 @@ NATIVE_ADJUNCT= /usr
# Compatibility code for FreeBSD etc.
#
COMPAT= $(SRC)/compat
-CONTRIB= $(SRC)/../contrib
+CONTRIB= $(SRC)/contrib
#
# RELEASE_BUILD should be cleared for final release builds.
diff --git a/usr/src/cmd/Makefile b/usr/src/cmd/Makefile
index dd035124e9..acb3717b0a 100644
--- a/usr/src/cmd/Makefile
+++ b/usr/src/cmd/Makefile
@@ -21,7 +21,7 @@
#
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright 2019 Joyent, Inc.
+# Copyright 2020 Joyent, Inc.
# Copyright (c) 2012, 2015 by Delphix. All rights reserved.
# Copyright (c) 2013 DEY Storage Systems, Inc. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
@@ -343,6 +343,7 @@ COMMON_SUBDIRS= \
pwconv \
pwd \
raidctl \
+ raidz_test \
ramdiskadm \
rcap \
rcm_daemon \
diff --git a/usr/src/cmd/bhyve/Makefile b/usr/src/cmd/bhyve/Makefile
index ea4537596a..b766cb8357 100644
--- a/usr/src/cmd/bhyve/Makefile
+++ b/usr/src/cmd/bhyve/Makefile
@@ -111,10 +111,10 @@ MEVENT_TEST_OBJS = $(MEVENT_TEST_SRCS:.c=.o)
CLEANFILES = $(PROG) $(ZHYVE_PROG) $(MEVENT_TEST_PROG) $(MEVENT_TEST_OBJS)
CFLAGS += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration -_gcc=-Wno-parentheses
-CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \
- -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 \
- -I$(CONTRIB)/freebsd/dev/usb/controller \
- -I$(CONTRIB)/freebsd/dev/mii \
+CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \
+ -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \
+ -I$(CONTRIB)/bhyve/dev/usb/controller \
+ -I$(CONTRIB)/bhyve/dev/mii \
-I$(SRC)/uts/common/io/e1000api \
$(CPPFLAGS.master) \
-I$(ROOT)/usr/platform/i86pc/include \
diff --git a/usr/src/cmd/bhyve/test/Makefile.com b/usr/src/cmd/bhyve/test/Makefile.com
index 2bd67140f5..aeba956e12 100644
--- a/usr/src/cmd/bhyve/test/Makefile.com
+++ b/usr/src/cmd/bhyve/test/Makefile.com
@@ -28,9 +28,9 @@ CFLAGS += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration \
CFLAGS64 += $(CCVERBOSE) -_gcc=-Wimplicit-function-declaration \
-_gcc=-Wno-parentheses
CPPFLAGS = -I$(SRC)/cmd/bhyve \
- -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \
- -I$(CONTRIB)/freebsd/dev/usb/controller \
- -I$(CONTRIB)/freebsd/dev/mii \
+ -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \
+ -I$(CONTRIB)/bhyve/dev/usb/controller \
+ -I$(CONTRIB)/bhyve/dev/mii \
$(CPPFLAGS.master) \
-I$(ROOT)/usr/platform/i86pc/include \
-I$(SRC)/uts/i86pc/io/vmm \
@@ -38,7 +38,7 @@ CPPFLAGS = -I$(SRC)/cmd/bhyve \
-I$(SRC)/uts/i86pc \
-I$(SRC)/lib/libdladm/common \
-DWITHOUT_CAPSICUM
-CPPFLAGS += -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64
+CPPFLAGS += -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64
SMOFF += all_func_returns
diff --git a/usr/src/cmd/bhyvectl/Makefile b/usr/src/cmd/bhyvectl/Makefile
index 72b3cd913f..c35b590196 100644
--- a/usr/src/cmd/bhyvectl/Makefile
+++ b/usr/src/cmd/bhyvectl/Makefile
@@ -28,8 +28,8 @@ CLOBBERFILES += $(ROOTUSRSBINPROG)
.KEEP_STATE:
CFLAGS += $(CCVERBOSE)
-CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \
- -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 \
+CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \
+ -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \
$(CPPFLAGS.master) \
-I$(ROOT)/usr/platform/i86pc/include \
-I$(SRC)/uts/i86pc/io/vmm
@@ -53,6 +53,6 @@ clean:
include ../Makefile.targ
-%.o: $(CONTRIB)/freebsd/lib/libutil/%.c
+%.o: $(CONTRIB)/bhyve/lib/libutil/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
diff --git a/usr/src/cmd/ndmpd/include/tlm.h b/usr/src/cmd/ndmpd/include/tlm.h
index f382d2eca3..8c667a334b 100644
--- a/usr/src/cmd/ndmpd/include/tlm.h
+++ b/usr/src/cmd/ndmpd/include/tlm.h
@@ -11,10 +11,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -113,9 +113,9 @@ typedef struct fs_fhandle {
} fs_fhandle_t;
typedef struct scsi_link {
- struct scsi_link *sl_next;
- struct scsi_link *sl_prev;
- struct scsi_adapter *sl_sa;
+ struct scsi_link *sl_next;
+ struct scsi_link *sl_prev;
+ struct scsi_adapter *sl_sa;
unsigned int sl_sid;
unsigned int sl_lun;
unsigned int sl_requested_max_active;
@@ -427,7 +427,7 @@ typedef struct tm_ops {
int (*tm_putfile)();
int (*tm_putdir)();
int (*tm_putvol)(); /* Reserved */
- int (*tm_getfile)();
+ void * (*tm_getfile)(void *);
int (*tm_getdir)();
int (*tm_getvol)(); /* Reserved */
} tm_ops_t;
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd.h b/usr/src/cmd/ndmpd/ndmp/ndmpd.h
index 4f9fcd9a09..929a833c1c 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd.h
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd.h
@@ -11,10 +11,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -998,7 +998,7 @@ extern int ndmp_backup_extract_params(ndmpd_session_t *,
ndmpd_module_params_t *);
extern int ndmp_restore_extract_params(ndmpd_session_t *,
ndmpd_module_params_t *);
-extern int ndmp_tar_reader(ndmp_tar_reader_arg_t *);
+extern void *ndmp_tar_reader(void *);
extern int tape_open(char *, int);
extern int tape_is_at_bot(ndmpd_session_t *);
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_common.h b/usr/src/cmd/ndmpd/ndmp/ndmpd_common.h
index 846f64e66f..383d5a673c 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_common.h
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_common.h
@@ -10,10 +10,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -281,6 +281,6 @@ extern int ndmp_log_msg_id;
/*
* Module function prototypes.
*/
-typedef int module_start_func_t(void *);
+typedef void *module_start_func_t(void *);
typedef int module_abort_func_t(void *);
#endif /* _NDMP_COMMON_H */
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
index 9350cb05f7..2713f8bec2 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_data.c
@@ -11,10 +11,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -1466,7 +1466,7 @@ ndmpd_tar_start_backup_v3(ndmpd_session_t *session, char *bu_type,
* client request here.
*/
err = pthread_create(NULL, NULL,
- (funct_t)session->ns_data.dd_module.dm_start_func,
+ session->ns_data.dd_module.dm_start_func,
params);
if (err != 0) {
NDMP_LOG(LOG_ERR, "Can't start backup session.");
@@ -1595,7 +1595,7 @@ ndmpd_tar_start_recover_v3(ndmpd_session_t *session,
* client request here.
*/
err = pthread_create(NULL, NULL,
- (funct_t)session->ns_data.dd_module.dm_start_func,
+ session->ns_data.dd_module.dm_start_func,
params);
if (err != 0) {
@@ -1692,7 +1692,8 @@ ndmpd_zfs_start_op(ndmpd_session_t *session, ndmp_pval *env_val,
}
err = pthread_create(&tid, NULL,
- (funct_t)session->ns_data.dd_module.dm_start_func, ndmpd_zfs_args);
+ session->ns_data.dd_module.dm_start_func,
+ ndmpd_zfs_args);
if (err) {
NDMP_LOG(LOG_ERR, "Can't start %s session (errno %d)",
@@ -2185,7 +2186,7 @@ ndmpd_tar_start_backup_v2(ndmpd_session_t *session, char *bu_type,
* client request here.
*/
(void) pthread_create(NULL, NULL,
- (funct_t)session->ns_data.dd_module.dm_start_func,
+ session->ns_data.dd_module.dm_start_func,
params);
return (NDMP_NO_ERR);
@@ -2322,7 +2323,7 @@ ndmpd_tar_start_recover_v2(ndmpd_session_t *session, char *bu_type,
* client request here.
*/
(void) pthread_create(NULL, NULL,
- (funct_t)session->ns_data.dd_module.dm_start_func,
+ session->ns_data.dd_module.dm_start_func,
params);
return (NDMP_NO_ERR);
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
index 2f7f311e75..8428679e93 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c
@@ -10,10 +10,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -2503,8 +2503,8 @@ mover_tape_read_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
* 0: on success
* -1: otherwise
*/
-int
-mover_tape_reader(ndmpd_session_t *session)
+void *
+mover_tape_reader(void *ptr)
{
int bidx; /* buffer index */
int rv;
@@ -2513,10 +2513,11 @@ mover_tape_reader(ndmpd_session_t *session)
tlm_buffers_t *bufs;
tlm_cmd_t *lcmd; /* Local command */
tlm_commands_t *cmds; /* Commands structure */
+ ndmpd_session_t *session = ptr;
if ((nlp = ndmp_get_nlp(session)) == NULL) {
NDMP_LOG(LOG_DEBUG, "nlp == NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
cmds = &nlp->nlp_cmds;
@@ -2582,7 +2583,7 @@ mover_tape_reader(ndmpd_session_t *session)
cmds->tcs_reader_count--;
lcmd->tc_ref--;
lcmd->tc_writer = TLM_STOP;
- return (0);
+ return (NULL);
}
@@ -2652,8 +2653,8 @@ mover_socket_write_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
* 0: on success
* -1: otherwise
*/
-int
-mover_socket_writer(ndmpd_session_t *session)
+void *
+mover_socket_writer(void *ptr)
{
int bidx; /* buffer index */
ndmp_lbr_params_t *nlp;
@@ -2661,10 +2662,11 @@ mover_socket_writer(ndmpd_session_t *session)
tlm_buffers_t *bufs;
tlm_cmd_t *lcmd; /* Local command */
tlm_commands_t *cmds; /* Commands structure */
+ ndmpd_session_t *session = ptr;
if ((nlp = ndmp_get_nlp(session)) == NULL) {
NDMP_LOG(LOG_DEBUG, "nlp == NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
cmds = &nlp->nlp_cmds;
@@ -2725,7 +2727,7 @@ mover_socket_writer(ndmpd_session_t *session)
cmds->tcs_writer_count--;
lcmd->tc_ref--;
lcmd->tc_reader = TLM_STOP;
- return (0);
+ return (NULL);
}
@@ -2772,7 +2774,7 @@ start_mover_for_restore(ndmpd_session_t *session)
* must be sent to the client before probable errors are sent
* to the client.
*/
- rc = pthread_create(NULL, NULL, (funct_t)mover_tape_reader, session);
+ rc = pthread_create(NULL, NULL, mover_tape_reader, session);
if (rc == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_TAPE_READER);
} else {
@@ -2781,7 +2783,7 @@ start_mover_for_restore(ndmpd_session_t *session)
return (-1);
}
- rc = pthread_create(NULL, NULL, (funct_t)mover_socket_writer, session);
+ rc = pthread_create(NULL, NULL, mover_socket_writer, session);
if (rc == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_SOCK_WRITER);
} else {
@@ -2874,8 +2876,8 @@ mover_socket_read_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf,
* 0: on success
* -1: otherwise
*/
-int
-mover_socket_reader(ndmpd_session_t *session)
+void *
+mover_socket_reader(void *ptr)
{
int bidx; /* buffer index */
ndmp_lbr_params_t *nlp;
@@ -2883,11 +2885,12 @@ mover_socket_reader(ndmpd_session_t *session)
tlm_buffers_t *bufs;
tlm_cmd_t *lcmd; /* Local command */
tlm_commands_t *cmds; /* Commands structure */
+ ndmpd_session_t *session = ptr;
static int nr = 0;
if ((nlp = ndmp_get_nlp(session)) == NULL) {
NDMP_LOG(LOG_DEBUG, "nlp == NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
cmds = &nlp->nlp_cmds;
@@ -2951,7 +2954,7 @@ mover_socket_reader(ndmpd_session_t *session)
cmds->tcs_reader_count--;
lcmd->tc_ref--;
lcmd->tc_writer = TLM_STOP;
- return (0);
+ return (NULL);
}
@@ -3014,8 +3017,8 @@ mover_tape_write_one_buf(ndmpd_session_t *session, tlm_buffer_t *buf)
* 0: on success
* -1: otherwise
*/
-int
-mover_tape_writer(ndmpd_session_t *session)
+void *
+mover_tape_writer(void *ptr)
{
int bidx;
ndmp_lbr_params_t *nlp;
@@ -3023,11 +3026,12 @@ mover_tape_writer(ndmpd_session_t *session)
tlm_buffers_t *bufs;
tlm_cmd_t *lcmd;
tlm_commands_t *cmds;
+ ndmpd_session_t *session = ptr;
static int nw = 0;
if ((nlp = ndmp_get_nlp(session)) == NULL) {
NDMP_LOG(LOG_DEBUG, "nlp == NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
cmds = &nlp->nlp_cmds;
@@ -3096,7 +3100,7 @@ mover_tape_writer(ndmpd_session_t *session)
cmds->tcs_writer_count--;
lcmd->tc_ref--;
lcmd->tc_reader = TLM_STOP;
- return (0);
+ return (NULL);
}
@@ -3143,7 +3147,7 @@ start_mover_for_backup(ndmpd_session_t *session)
* must be sent to the client before probable errors are sent
* to the client.
*/
- rc = pthread_create(NULL, NULL, (funct_t)mover_socket_reader, session);
+ rc = pthread_create(NULL, NULL, mover_socket_reader, session);
if (rc == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_SOCK_READER);
} else {
@@ -3152,7 +3156,7 @@ start_mover_for_backup(ndmpd_session_t *session)
return (-1);
}
- rc = pthread_create(NULL, NULL, (funct_t)mover_tape_writer, session);
+ rc = pthread_create(NULL, NULL, mover_tape_writer, session);
if (rc == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_TAPE_WRITER);
} else {
@@ -3180,7 +3184,7 @@ start_mover_for_backup(ndmpd_session_t *session)
* Note: non-zero is also returned if the backup type is
* neither TAR nor DUMP. I.e. the is_writer_running()
* check does not apply in this case and things should
- * appear successful.
+ * appear successful.
*/
static boolean_t
is_writer_running(ndmpd_session_t *session)
@@ -3216,7 +3220,7 @@ is_writer_running(ndmpd_session_t *session)
* Note: non-zero is also returned if the backup type is
* neither TAR nor DUMP. I.e. the is_writer_running()
* check does not apply in this case and things should
- * appear successful.
+ * appear successful.
*/
static boolean_t
is_writer_running_v3(ndmpd_session_t *session)
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c
index 8040355eb0..89dc343051 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c
@@ -10,10 +10,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -370,8 +370,7 @@ ndmp_write_utf8magic(tlm_cmd_t *cmd)
*
*/
static boolean_t
-timecmp(bk_selector_t *bksp,
- struct stat64 *attr)
+timecmp(bk_selector_t *bksp, struct stat64 *attr)
{
ndmp_lbr_params_t *nlp;
@@ -476,7 +475,7 @@ get_dir_acl_info(char *dir, tlm_acls_t *tlm_acls, tlm_job_stats_t *js)
char *spot;
char *fil;
acl_t *aclp = NULL;
- char *acltp;
+ char *acltp;
checkpointed_dir = ndmp_malloc(TLM_MAX_PATH_NAME);
if (checkpointed_dir == NULL)
@@ -656,7 +655,7 @@ backup_work(char *bk_path, tlm_job_stats_t *job_stats,
longlong_t fsize;
bk_selector_t bks;
tlm_cmd_t *local_commands;
- long dpos;
+ long dpos;
NDMP_LOG(LOG_DEBUG, "nr_chkpnted %d nr_ldate: %u bk_path: \"%s\"",
NLP_ISCHKPNTED(nlp), nlp->nlp_ldate, bk_path);
@@ -1067,8 +1066,8 @@ read_one_buf(ndmpd_module_params_t *mod_params, tlm_buffers_t *bufs,
* file from the tape and wakes up the consumer thread to extract
* it on the disk
*/
-int
-ndmp_tar_reader(ndmp_tar_reader_arg_t *argp)
+void *
+ndmp_tar_reader(void *ptr)
{
int bidx;
int err;
@@ -1078,9 +1077,10 @@ ndmp_tar_reader(ndmp_tar_reader_arg_t *argp)
ndmpd_session_t *session;
ndmpd_module_params_t *mod_params;
tlm_commands_t *cmds;
+ ndmp_tar_reader_arg_t *argp = ptr;
if (!argp)
- return (-1);
+ return ((void *)(uintptr_t)-1);
session = argp->tr_session;
mod_params = argp->tr_mod_params;
@@ -1097,7 +1097,7 @@ ndmp_tar_reader(ndmp_tar_reader_arg_t *argp)
if (err != 0) {
tlm_cmd_signal(cmds->tcs_command, TLM_TAR_READER);
- return (err);
+ return ((void *)(uintptr_t)err);
}
lcmd = cmds->tcs_command;
@@ -1160,7 +1160,7 @@ ndmp_tar_reader(ndmp_tar_reader_arg_t *argp)
*/
cmds->tcs_reader_count--;
lcmd->tc_ref--;
- return (err);
+ return ((void *)(uintptr_t)err);
}
@@ -1314,8 +1314,7 @@ ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params,
arg.tr_mod_params = mod_params;
arg.tr_cmds = cmds;
- err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
- (void *)&arg);
+ err = pthread_create(&rdtp, NULL, ndmp_tar_reader, &arg);
if (err == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
} else {
@@ -1346,8 +1345,8 @@ ndmpd_tar_restore(ndmpd_session_t *session, ndmpd_module_params_t *mod_params,
if (tm_tar_ops.tm_getfile != NULL) {
- err = pthread_create(&wrtp, NULL,
- (funct_t)tm_tar_ops.tm_getfile, (void *)&tlm_arg);
+ err = pthread_create(&wrtp, NULL, tm_tar_ops.tm_getfile,
+ &tlm_arg);
} else {
(void) pthread_barrier_destroy(&tlm_arg.ba_barrier);
NDMP_LOG(LOG_DEBUG,
@@ -1859,7 +1858,7 @@ ndmp_restore_extract_params(ndmpd_session_t *session,
* and calls ndmp_tar_backup to perform the actual backup. It does the cleanup
* and release the snapshot at the end.
*/
-int
+void *
ndmpd_tar_backup_starter(void *arg)
{
ndmpd_module_params_t *mod_params = arg;
@@ -1933,7 +1932,7 @@ ndmpd_tar_backup_starter(void *arg)
NS_DEC(nbk);
ndmp_session_unref(session);
- return (err);
+ return ((void *)(uintptr_t)err);
}
@@ -1966,7 +1965,7 @@ ndmpd_tar_backup_abort(void *module_cookie)
* Starts the restore by running ndmpd_tar_restore function (V2 only)
*/
-int
+void *
ndmpd_tar_restore_starter(void *arg)
{
ndmpd_module_params_t *mod_params = arg;
@@ -1986,7 +1985,7 @@ ndmpd_tar_restore_starter(void *arg)
NS_DEC(nrs);
ndmp_session_unref(session);
- return (err);
+ return ((void *)(uintptr_t)err);
}
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c
index d3e89d5a3d..001368ac44 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c
@@ -10,10 +10,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -2222,8 +2222,8 @@ lbrbk_v3(void *arg, fst_node_t *pnp, fst_node_t *enp)
* 0: on success
* != 0: otherwise
*/
-static int
-backup_reader_v3(backup_reader_arg_t *argp)
+static void *
+backup_reader_v3(void *ptr)
{
int rv;
tlm_cmd_t *lcmd;
@@ -2234,9 +2234,10 @@ backup_reader_v3(backup_reader_arg_t *argp)
char *jname;
ndmp_lbr_params_t *nlp;
tlm_commands_t *cmds;
+ backup_reader_arg_t *argp = ptr;
if (!argp)
- return (-1);
+ return ((void *)(uintptr_t)-1);
jname = argp->br_jname;
nlp = argp->br_nlp;
@@ -2265,7 +2266,7 @@ backup_reader_v3(backup_reader_arg_t *argp)
bp.bp_tmp = ndmp_malloc(sizeof (char) * TLM_MAX_PATH_NAME);
if (!bp.bp_tmp)
- return (-1);
+ return ((void *)(uintptr_t)-1);
/*
* Make the checkpointed paths for traversing the
@@ -2277,7 +2278,7 @@ backup_reader_v3(backup_reader_arg_t *argp)
bp.bp_chkpnm = ndmp_malloc(sizeof (char) * TLM_MAX_PATH_NAME);
if (!bp.bp_chkpnm) {
NDMP_FREE(bp.bp_tmp);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
(void) tlm_build_snapshot_name(nlp->nlp_backup_path,
bp.bp_chkpnm, nlp->nlp_jstat->js_job_name);
@@ -2341,8 +2342,7 @@ backup_reader_v3(backup_reader_arg_t *argp)
lcmd->tc_writer = TLM_STOP;
tlm_release_reader_writer_ipc(lcmd);
tlm_un_ref_job_stats(jname);
- return (rv);
-
+ return ((void *)(uintptr_t)rv);
}
@@ -2438,8 +2438,7 @@ tar_backup_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
(void) pthread_barrier_init(&arg.br_barrier, 0, 2);
- err = pthread_create(&rdtp, NULL, (funct_t)backup_reader_v3,
- (void *)&arg);
+ err = pthread_create(&rdtp, NULL, backup_reader_v3, &arg);
if (err == 0) {
(void) pthread_barrier_wait(&arg.br_barrier);
(void) pthread_barrier_destroy(&arg.br_barrier);
@@ -2512,9 +2511,10 @@ backup_out:
* Find the estimate of backup size. This is used to get an estimate
* of the progress of backup during NDMP backup.
*/
-void
-get_backup_size(ndmp_bkup_size_arg_t *sarg)
+void *
+get_backup_size(void *ptr)
{
+ ndmp_bkup_size_arg_t *sarg = ptr;
fs_traverse_t ft;
u_longlong_t bk_size;
char spath[PATH_MAX];
@@ -2543,6 +2543,7 @@ get_backup_size(ndmp_bkup_size_arg_t *sarg)
bk_size, bk_size / 1024, bk_size /(1024 * 1024));
}
sarg->bs_session->ns_data.dd_data_size = bk_size;
+ return (NULL);
}
/*
@@ -3186,8 +3187,7 @@ ndmpd_dar_tar_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
arg.tr_mod_params = params;
arg.tr_cmds = cmds;
- err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
- (void *)&arg);
+ err = pthread_create(&rdtp, NULL, ndmp_tar_reader, &arg);
if (err == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
} else {
@@ -3445,8 +3445,8 @@ ndmp_plugin_pre_restore(ndmp_context_t *ctxp, ndmpd_module_params_t *params,
* /link-to-backup-path -> /backup/path
*
* Returns:
- * Pointer to the new path (allocated)
- * NULL if the path doesnt exist
+ * Pointer to the new path (allocated)
+ * NULL if the path doesnt exist
*/
static char *
get_absolute_path(const char *bkpath)
@@ -3548,8 +3548,7 @@ ndmpd_rs_sar_tar_v3(ndmpd_session_t *session, ndmpd_module_params_t *params,
arg.tr_session = session;
arg.tr_mod_params = params;
arg.tr_cmds = cmds;
- err = pthread_create(&rdtp, NULL, (funct_t)ndmp_tar_reader,
- (void *)&arg);
+ err = pthread_create(&rdtp, NULL, ndmp_tar_reader, &arg);
if (err == 0) {
tlm_cmd_wait(cmds->tcs_command, TLM_TAR_READER);
} else {
@@ -3746,7 +3745,7 @@ ndmp_backup_get_params_v3(ndmpd_session_t *session,
* 0: on success
* != 0: otherwise
*/
-int
+void *
ndmpd_tar_backup_starter_v3(void *arg)
{
ndmpd_module_params_t *params = arg;
@@ -3780,8 +3779,7 @@ ndmpd_tar_backup_starter_v3(void *arg)
sarg.bs_path = nlp->nlp_backup_path;
/* Get an estimate of the data size */
- if (pthread_create(&tid, NULL, (funct_t)get_backup_size,
- (void *)&sarg) == 0)
+ if (pthread_create(&tid, NULL, get_backup_size, &sarg) == 0)
(void) pthread_detach(tid);
err = ndmp_get_cur_bk_time(nlp, &nlp->nlp_cdate, jname);
@@ -3810,8 +3808,7 @@ ndmpd_tar_backup_starter_v3(void *arg)
NS_DEC(nbk);
ndmp_session_unref(session);
- return (err);
-
+ return ((void *)(uintptr_t)err);
}
@@ -3924,7 +3921,7 @@ ndmp_restore_get_params_v3(ndmpd_session_t *session,
* NDMP_NO_ERR: on success
* != NDMP_NO_ERR: otherwise
*/
-int
+void *
ndmpd_tar_restore_starter_v3(void *arg)
{
ndmpd_module_params_t *params = arg;
@@ -3948,8 +3945,7 @@ ndmpd_tar_restore_starter_v3(void *arg)
/* nlp_params is allocated in start_recover() */
NDMP_FREE(nlp->nlp_params);
ndmp_session_unref(session);
- return (err);
-
+ return ((void *)(uintptr_t)err);
}
/*
diff --git a/usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c b/usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c
index c124794fc4..72708f0475 100644
--- a/usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c
+++ b/usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c
@@ -11,10 +11,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -74,12 +74,12 @@ static void ndmpd_zfs_close_one_fd(ndmpd_zfs_args_t *, int);
static int ndmpd_zfs_header_write(ndmpd_session_t *);
static int ndmpd_zfs_header_read(ndmpd_zfs_args_t *);
-static int ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *);
-static int ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *);
+static void *ndmpd_zfs_backup_send_read(void *);
+static void *ndmpd_zfs_backup_tape_write(void *);
static int ndmpd_zfs_restore(ndmpd_zfs_args_t *);
-static int ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *);
-static int ndmpd_zfs_restore_recv_write(ndmpd_zfs_args_t *);
+static void *ndmpd_zfs_restore_tape_read(void *);
+static void *ndmpd_zfs_restore_recv_write(void *);
static int ndmpd_zfs_reader_writer(ndmpd_zfs_args_t *, int **, int **);
@@ -143,8 +143,8 @@ static int ndmpd_zfs_backup(ndmpd_zfs_args_t *);
*
* Examples:
*
- * 0.0.n/0.bob.p
- * 0.0.u/1.bob.p/0.jane.d
+ * 0.0.n/0.bob.p
+ * 0.0.u/1.bob.p/0.jane.d
*
* Note: NDMPD_ZFS_SUBPROP_MAX is calculated based on ZFS_MAXPROPLEN
*/
@@ -164,8 +164,8 @@ static int ndmpd_zfs_backup(ndmpd_zfs_args_t *);
#define NDMPD_ZFS_LOG_ZERR(ndmpd_zfs_args, ...) { \
NDMP_LOG(LOG_ERR, __VA_ARGS__); \
NDMP_LOG(LOG_ERR, "%s--%s", \
- libzfs_error_action((ndmpd_zfs_args)->nz_zlibh), \
- libzfs_error_description((ndmpd_zfs_args)->nz_zlibh)); \
+ libzfs_error_action((ndmpd_zfs_args)->nz_zlibh), \
+ libzfs_error_description((ndmpd_zfs_args)->nz_zlibh)); \
ndmpd_zfs_zerr_dma_log((ndmpd_zfs_args)); \
}
@@ -459,7 +459,7 @@ _err:
return (-1);
}
-int
+void *
ndmpd_zfs_backup_starter(void *arg)
{
ndmpd_zfs_args_t *ndmpd_zfs_args = arg;
@@ -492,7 +492,7 @@ _done:
ndmp_session_unref(session);
ndmpd_zfs_fini(ndmpd_zfs_args);
- return (err);
+ return ((void *)(uintptr_t)err);
}
static int
@@ -599,17 +599,18 @@ ndmpd_zfs_backup(ndmpd_zfs_args_t *ndmpd_zfs_args)
*
* This routine executes zfs_send() to create the backup data stream.
* The value of ZFS_MODE determines the type of zfs_send():
- * dataset ('d'): Only the dataset specified (i.e., top level) is backed up
- * recursive ('r'): The dataset and its child file systems are backed up
- * package ('p'): Same as 'r', except all intermediate snapshots are also
+ * dataset ('d'): Only the dataset specified (i.e., top level) is backed up
+ * recursive ('r'): The dataset and its child file systems are backed up
+ * package ('p'): Same as 'r', except all intermediate snapshots are also
* backed up
*
* Volumes do not have descednants, so 'd' and 'r' produce equivalent results.
*/
-static int
-ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
+static void *
+ndmpd_zfs_backup_send_read(void *ptr)
{
+ ndmpd_zfs_args_t *ndmpd_zfs_args = ptr;
ndmpd_session_t *session = (ndmpd_session_t *)
(ndmpd_zfs_params->mp_daemon_cookie);
sendflags_t flags = { 0 };
@@ -623,7 +624,7 @@ ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
if (!zhp) {
if (!session->ns_data.dd_abort)
NDMPD_ZFS_LOG_ZERR(ndmpd_zfs_args, "zfs_open");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
switch (ndmpd_zfs_args->nz_zfs_mode) {
@@ -641,14 +642,14 @@ ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
NDMP_LOG(LOG_ERR, "unknown zfs_mode: %c",
ndmpd_zfs_args->nz_zfs_mode);
zfs_close(zhp);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
if (ndmpd_zfs_is_incremental(ndmpd_zfs_args)) {
if (ndmpd_zfs_args->nz_fromsnap[0] == '\0') {
NDMP_LOG(LOG_ERR, "no fromsnap");
zfs_close(zhp);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
fromsnap = ndmpd_zfs_args->nz_fromsnap;
}
@@ -661,7 +662,7 @@ ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
zfs_close(zhp);
- return (err);
+ return ((void *)(uintptr_t)err);
}
/*
@@ -672,9 +673,10 @@ ndmpd_zfs_backup_send_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
* ndmpd_zfs_args->nz_bufsize).
*/
-static int
-ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
+static void *
+ndmpd_zfs_backup_tape_write(void *ptr)
{
+ ndmpd_zfs_args_t *ndmpd_zfs_args = ptr;
ndmpd_session_t *session = (ndmpd_session_t *)
(ndmpd_zfs_params->mp_daemon_cookie);
int bufsize = ndmpd_zfs_args->nz_bufsize;
@@ -685,7 +687,7 @@ ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
buf = ndmp_malloc(bufsize);
if (buf == NULL) {
NDMP_LOG(LOG_DEBUG, "buf NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
bytes_totalp =
@@ -704,7 +706,8 @@ ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
*bytes_totalp - bufsize, *bytes_totalp);
free(buf);
- return (ndmpd_zfs_addenv_backup_size(ndmpd_zfs_args,
+ return ((void *)(uintptr_t)
+ ndmpd_zfs_addenv_backup_size(ndmpd_zfs_args,
*bytes_totalp));
}
@@ -712,7 +715,7 @@ ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
NDMP_LOG(LOG_DEBUG, "pipe read error (errno %d)",
errno);
free(buf);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
NS_ADD(rdisk, count);
@@ -720,7 +723,7 @@ ndmpd_zfs_backup_tape_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
(void) ndmpd_zfs_abort((void *) ndmpd_zfs_args);
NDMP_LOG(LOG_ERR, "MOD_WRITE error");
free(buf);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
*bytes_totalp += count;
@@ -750,7 +753,7 @@ ndmpd_zfs_addenv_backup_size(ndmpd_zfs_args_t *ndmpd_zfs_args,
return (0);
}
-int
+void *
ndmpd_zfs_restore_starter(void *arg)
{
ndmpd_zfs_args_t *ndmpd_zfs_args = arg;
@@ -770,7 +773,7 @@ ndmpd_zfs_restore_starter(void *arg)
ndmpd_zfs_fini(ndmpd_zfs_args);
- return (err);
+ return ((void *)(uintptr_t)err);
}
static int
@@ -827,9 +830,10 @@ ndmpd_zfs_restore(ndmpd_zfs_args_t *ndmpd_zfs_args)
return (err);
}
-static int
-ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
+static void *
+ndmpd_zfs_restore_tape_read(void *ptr)
{
+ ndmpd_zfs_args_t *ndmpd_zfs_args = ptr;
ndmpd_session_t *session = (ndmpd_session_t *)
(ndmpd_zfs_params->mp_daemon_cookie);
int bufsize = ndmpd_zfs_args->nz_bufsize;
@@ -843,7 +847,7 @@ ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
buf = ndmp_malloc(bufsize);
if (buf == NULL) {
NDMP_LOG(LOG_DEBUG, "buf NULL");
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
bytes_totalp = &ndmpd_zfs_args->nz_nlp->nlp_bytes_total;
@@ -861,7 +865,7 @@ ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
NDMP_LOG(LOG_ERR, "MOD_READ error: %d; returning -1",
err);
free(buf);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
count = write(ndmpd_zfs_args->nz_pipe_fd[PIPE_TAPE], buf,
@@ -880,7 +884,7 @@ ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
}
free(buf);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
NS_ADD(wdisk, count);
@@ -889,7 +893,7 @@ ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
}
free(buf);
- return (0);
+ return (NULL);
}
/*
@@ -898,9 +902,10 @@ ndmpd_zfs_restore_tape_read(ndmpd_zfs_args_t *ndmpd_zfs_args)
* This routine executes zfs_receive() to restore the backup.
*/
-static int
-ndmpd_zfs_restore_recv_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
+static void *
+ndmpd_zfs_restore_recv_write(void *ptr)
{
+ ndmpd_zfs_args_t *ndmpd_zfs_args = ptr;
ndmpd_session_t *session = (ndmpd_session_t *)
(ndmpd_zfs_params->mp_daemon_cookie);
recvflags_t flags;
@@ -921,7 +926,7 @@ ndmpd_zfs_restore_recv_write(ndmpd_zfs_args_t *ndmpd_zfs_args)
if (err && !session->ns_data.dd_abort)
NDMPD_ZFS_LOG_ZERR(ndmpd_zfs_args, "zfs_receive: %d", err);
- return (err);
+ return ((void *)(uintptr_t)err);
}
/*
@@ -941,12 +946,12 @@ ndmpd_zfs_reader_writer(ndmpd_zfs_args_t *ndmpd_zfs_args,
switch (ndmpd_zfs_params->mp_operation) {
case NDMP_DATA_OP_BACKUP:
- sendrecv_func = (funct_t)ndmpd_zfs_backup_send_read;
- tape_func = (funct_t)ndmpd_zfs_backup_tape_write;
+ sendrecv_func = ndmpd_zfs_backup_send_read;
+ tape_func = ndmpd_zfs_backup_tape_write;
break;
case NDMP_DATA_OP_RECOVER:
- sendrecv_func = (funct_t)ndmpd_zfs_restore_recv_write;
- tape_func = (funct_t)ndmpd_zfs_restore_tape_read;
+ sendrecv_func = ndmpd_zfs_restore_recv_write;
+ tape_func = ndmpd_zfs_restore_tape_read;
break;
}
diff --git a/usr/src/cmd/ndmpd/tlm/tlm_proto.h b/usr/src/cmd/ndmpd/tlm/tlm_proto.h
index f37f206e6e..6bdd214a5d 100644
--- a/usr/src/cmd/ndmpd/tlm/tlm_proto.h
+++ b/usr/src/cmd/ndmpd/tlm/tlm_proto.h
@@ -10,10 +10,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -134,7 +134,7 @@ extern int tar_putdir(char *,
tlm_cmd_t *,
tlm_job_stats_t *);
-extern int tar_getfile(tlm_backup_restore_arg_t *);
+extern void * tar_getfile(void *);
extern int
tar_getdir(tlm_commands_t *,
diff --git a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
index 82af6967ef..f757e59deb 100644
--- a/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
+++ b/usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c
@@ -11,10 +11,10 @@
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
- * - Redistributions of source code must retain the above copyright
+ * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
- * - Redistributions in binary form must reproduce the above copyright
+ * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
@@ -286,8 +286,8 @@ tar_getdir(tlm_commands_t *commands,
long nm_end, lnk_end;
char *name, *nmp;
cstack_t *stp;
- char *bkpath;
- char *parentlnk;
+ char *bkpath;
+ char *parentlnk;
int dir_dar = 0;
/*
@@ -987,9 +987,10 @@ tar_getdir(tlm_commands_t *commands,
/*
* Main file restore function for tar (should run as a thread)
*/
-int
-tar_getfile(tlm_backup_restore_arg_t *argp)
+void *
+tar_getfile(void *ptr)
{
+ tlm_backup_restore_arg_t *argp = ptr;
tlm_job_stats_t *job_stats;
char **sels; /* list of files desired */
char **exls; /* list of files not wanted */
@@ -1012,7 +1013,7 @@ tar_getfile(tlm_backup_restore_arg_t *argp)
if (dir == NULL) {
local_commands->tc_reader = TLM_STOP;
(void) pthread_barrier_wait(&argp->ba_barrier);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
(void) strlcpy(job, argp->ba_job, TLM_MAX_BACKUP_JOB_NAME+1);
@@ -1031,7 +1032,7 @@ tar_getfile(tlm_backup_restore_arg_t *argp)
local_commands->tc_reader = TLM_STOP;
free(dir);
(void) pthread_barrier_wait(&argp->ba_barrier);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
sels = argp->ba_sels;
@@ -1039,7 +1040,7 @@ tar_getfile(tlm_backup_restore_arg_t *argp)
local_commands->tc_reader = TLM_STOP;
free(dir);
(void) pthread_barrier_wait(&argp->ba_barrier);
- return (-1);
+ return ((void *)(uintptr_t)-1);
}
exls = &list;
@@ -1081,7 +1082,7 @@ tar_getfile(tlm_backup_restore_arg_t *argp)
local_commands->tc_reader = TLM_STOP;
tlm_release_reader_writer_ipc(local_commands);
free(dir);
- return (erc);
+ return ((void *)(uintptr_t)erc);
}
/*
diff --git a/usr/src/cmd/raidz_test/Makefile b/usr/src/cmd/raidz_test/Makefile
new file mode 100644
index 0000000000..43e0c07829
--- /dev/null
+++ b/usr/src/cmd/raidz_test/Makefile
@@ -0,0 +1,61 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2020 Joyent, Inc.
+#
+
+include ../Makefile.cmd
+include ../Makefile.cmd.64
+
+PROG= raidz_test
+OBJS= raidz_test.o raidz_bench.o
+SRCS= $(OBJS:%.o=%.c)
+POFILES= $(PROG:%=%.po)
+
+# No msg catalog here.
+POFILE=
+
+LDLIBS += -lzpool -lfakekernel -lumem
+
+INCS += -I../../lib/libzpool/common
+INCS += -I../../uts/common/fs/zfs
+
+CPPFLAGS.first = -I$(SRC)/lib/libfakekernel/common -D_FAKE_KERNEL
+CPPFLAGS += -D_LARGEFILE64_SOURCE=1
+CPPFLAGS += $(INCS)
+
+CSTD = $(CSTD_GNU99)
+
+CERRWARN += -_gcc=-Wno-type-limits
+
+SMATCH=off
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $(PROG) $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTPROG)
+
+clean:
+ $(RM) $(OBJS)
+
+_msg: $(MSGDOMAIN) $(POFILES)
+ $(CP) $(POFILES) $(MSGDOMAIN)
+
+$(MSGDOMAIN):
+ $(INS.dir)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/raidz_test/raidz_bench.c b/usr/src/cmd/raidz_test/raidz_bench.c
new file mode 100644
index 0000000000..9dc22af6fd
--- /dev/null
+++ b/usr/src/cmd/raidz_test/raidz_bench.c
@@ -0,0 +1,228 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/zio.h>
+#include <sys/vdev_raidz.h>
+#include <sys/vdev_raidz_impl.h>
+#include <stdio.h>
+#include <strings.h>
+
+#include <sys/time.h>
+
+#include "raidz_test.h"
+
+#define GEN_BENCH_MEMORY (((uint64_t)1ULL)<<32)
+#define REC_BENCH_MEMORY (((uint64_t)1ULL)<<29)
+#define BENCH_ASHIFT 12
+#define MIN_CS_SHIFT BENCH_ASHIFT
+#define MAX_CS_SHIFT SPA_MAXBLOCKSHIFT
+
+static zio_t zio_bench;
+static raidz_map_t *rm_bench;
+static size_t max_data_size = SPA_MAXBLOCKSIZE;
+
+static void
+bench_init_raidz_map(void)
+{
+ zio_bench.io_offset = 0;
+ zio_bench.io_size = max_data_size;
+
+ /*
+ * To permit larger column sizes these have to be done
+ * allocated using aligned alloc instead of zio_abd_buf_alloc
+ */
+ zio_bench.io_abd = raidz_alloc(max_data_size);
+
+ init_zio_abd(&zio_bench);
+}
+
+static void
+bench_fini_raidz_maps(void)
+{
+ /* tear down golden zio */
+ raidz_free(zio_bench.io_abd, max_data_size);
+ bzero(&zio_bench, sizeof (zio_t));
+}
+
+static inline void
+run_gen_bench_impl(const char *impl)
+{
+ int fn, ncols;
+ uint64_t ds, iter_cnt, iter, disksize;
+ hrtime_t start;
+ double elapsed, d_bw;
+
+ /* Benchmark generate functions */
+ for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
+
+ for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
+ /* create suitable raidz_map */
+ ncols = rto_opts.rto_dcols + fn + 1;
+ zio_bench.io_size = 1ULL << ds;
+ rm_bench = vdev_raidz_map_alloc(&zio_bench,
+ BENCH_ASHIFT, ncols, fn+1);
+
+ /* estimate iteration count */
+ iter_cnt = GEN_BENCH_MEMORY;
+ iter_cnt /= zio_bench.io_size;
+
+ start = gethrtime();
+ for (iter = 0; iter < iter_cnt; iter++)
+ vdev_raidz_generate_parity(rm_bench);
+ elapsed = NSEC2SEC((double)(gethrtime() - start));
+
+ disksize = (1ULL << ds) / rto_opts.rto_dcols;
+ d_bw = (double)iter_cnt * (double)disksize;
+ d_bw /= (1024.0 * 1024.0 * elapsed);
+
+ LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
+ impl,
+ raidz_gen_name[fn],
+ rto_opts.rto_dcols,
+ (1ULL<<ds),
+ d_bw,
+ d_bw * (double)(ncols),
+ (unsigned)iter_cnt);
+
+ vdev_raidz_map_free(rm_bench);
+ }
+ }
+}
+
+void
+run_gen_bench(void)
+{
+ char **impl_name;
+
+ LOG(D_INFO, DBLSEP "\nBenchmarking parity generation...\n\n");
+ LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
+
+ for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
+ impl_name++) {
+
+ if (vdev_raidz_impl_set(*impl_name) != 0)
+ continue;
+
+ run_gen_bench_impl(*impl_name);
+ }
+}
+
+static void
+run_rec_bench_impl(const char *impl)
+{
+ int fn, ncols, nbad;
+ uint64_t ds, iter_cnt, iter, disksize;
+ hrtime_t start;
+ double elapsed, d_bw;
+ static const int tgt[7][3] = {
+ {1, 2, 3}, /* rec_p: bad QR & D[0] */
+ {0, 2, 3}, /* rec_q: bad PR & D[0] */
+ {0, 1, 3}, /* rec_r: bad PQ & D[0] */
+ {2, 3, 4}, /* rec_pq: bad R & D[0][1] */
+ {1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
+ {0, 3, 4}, /* rec_qr: bad P & D[0][1] */
+ {3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
+ };
+
+ for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
+ for (ds = MIN_CS_SHIFT; ds <= MAX_CS_SHIFT; ds++) {
+
+ /* create suitable raidz_map */
+ ncols = rto_opts.rto_dcols + PARITY_PQR;
+ zio_bench.io_size = 1ULL << ds;
+
+ /*
+ * raidz block is too short to test
+ * the requested method
+ */
+ if (zio_bench.io_size / rto_opts.rto_dcols <
+ (1ULL << BENCH_ASHIFT))
+ continue;
+
+ rm_bench = vdev_raidz_map_alloc(&zio_bench,
+ BENCH_ASHIFT, ncols, PARITY_PQR);
+
+ /* estimate iteration count */
+ iter_cnt = (REC_BENCH_MEMORY);
+ iter_cnt /= zio_bench.io_size;
+
+ /* calculate how many bad columns there are */
+ nbad = MIN(3, raidz_ncols(rm_bench) -
+ raidz_parity(rm_bench));
+
+ start = gethrtime();
+ for (iter = 0; iter < iter_cnt; iter++)
+ vdev_raidz_reconstruct(rm_bench, tgt[fn], nbad);
+ elapsed = NSEC2SEC((double)(gethrtime() - start));
+
+ disksize = (1ULL << ds) / rto_opts.rto_dcols;
+ d_bw = (double)iter_cnt * (double)(disksize);
+ d_bw /= (1024.0 * 1024.0 * elapsed);
+
+ LOG(D_ALL, "%10s, %8s, %zu, %10llu, %lf, %lf, %u\n",
+ impl,
+ raidz_rec_name[fn],
+ rto_opts.rto_dcols,
+ (1ULL<<ds),
+ d_bw,
+ d_bw * (double)ncols,
+ (unsigned)iter_cnt);
+
+ vdev_raidz_map_free(rm_bench);
+ }
+ }
+}
+
+void
+run_rec_bench(void)
+{
+ char **impl_name;
+
+ LOG(D_INFO, DBLSEP "\nBenchmarking data reconstruction...\n\n");
+ LOG(D_ALL, "impl, math, dcols, iosize, disk_bw, total_bw, iter\n");
+
+ for (impl_name = (char **)raidz_impl_names; *impl_name != NULL;
+ impl_name++) {
+
+ if (vdev_raidz_impl_set(*impl_name) != 0)
+ continue;
+
+ run_rec_bench_impl(*impl_name);
+ }
+}
+
+void
+run_raidz_benchmark(void)
+{
+ bench_init_raidz_map();
+
+ run_gen_bench();
+ run_rec_bench();
+
+ bench_fini_raidz_maps();
+}
diff --git a/usr/src/cmd/raidz_test/raidz_test.c b/usr/src/cmd/raidz_test/raidz_test.c
new file mode 100644
index 0000000000..8d025b479d
--- /dev/null
+++ b/usr/src/cmd/raidz_test/raidz_test.c
@@ -0,0 +1,761 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/zio.h>
+#include <umem.h>
+#include <sys/vdev_raidz.h>
+#include <sys/vdev_raidz_impl.h>
+#include <assert.h>
+#include <stdio.h>
+#include <strings.h>
+#include <unistd.h>
+#include "raidz_test.h"
+
+static int *rand_data;
+raidz_test_opts_t rto_opts;
+
+static char gdb[256];
+static const char gdb_tmpl[] = "gdb -ex \"set pagination 0\" -p %d";
+
+#define boot_ncpus (sysconf(_SC_NPROCESSORS_ONLN))
+
+static void print_opts(raidz_test_opts_t *opts, boolean_t force)
+{
+ char *verbose;
+ switch (opts->rto_v) {
+ case 0:
+ verbose = "no";
+ break;
+ case 1:
+ verbose = "info";
+ break;
+ default:
+ verbose = "debug";
+ break;
+ }
+
+ if (force || opts->rto_v >= D_INFO) {
+ (void) fprintf(stdout, DBLSEP "Running with options:\n"
+ " (-a) zio ashift : %zu\n"
+ " (-o) zio offset : 1 << %zu\n"
+ " (-d) number of raidz data columns : %zu\n"
+ " (-s) size of DATA : 1 << %zu\n"
+ " (-S) sweep parameters : %s \n"
+ " (-v) verbose : %s \n\n",
+ opts->rto_ashift, /* -a */
+ ilog2(opts->rto_offset), /* -o */
+ opts->rto_dcols, /* -d */
+ ilog2(opts->rto_dsize), /* -s */
+ opts->rto_sweep ? "yes" : "no", /* -S */
+ verbose); /* -v */
+ }
+}
+
+static void usage(boolean_t requested)
+{
+ const raidz_test_opts_t *o = &rto_opts_defaults;
+
+ FILE *fp = requested ? stdout : stderr;
+
+ (void) fprintf(fp, "Usage:\n"
+ "\t[-a zio ashift (default: %zu)]\n"
+ "\t[-o zio offset, exponent radix 2 (default: %zu)]\n"
+ "\t[-d number of raidz data columns (default: %zu)]\n"
+ "\t[-s zio size, exponent radix 2 (default: %zu)]\n"
+ "\t[-S parameter sweep (default: %s)]\n"
+ "\t[-t timeout for parameter sweep test]\n"
+ "\t[-B benchmark all raidz implementations]\n"
+ "\t[-v increase verbosity (default: %zu)]\n"
+ "\t[-h (print help)]\n"
+ "\t[-T test the test, see if failure would be detected]\n"
+ "\t[-D debug (attach gdb on SIGSEGV)]\n"
+ "",
+ o->rto_ashift, /* -a */
+ ilog2(o->rto_offset), /* -o */
+ o->rto_dcols, /* -d */
+ ilog2(o->rto_dsize), /* -s */
+ rto_opts.rto_sweep ? "yes" : "no", /* -S */
+ o->rto_v); /* -d */
+
+ exit(requested ? 0 : 1);
+}
+
+static void process_options(int argc, char **argv)
+{
+ size_t value;
+ int opt;
+
+ raidz_test_opts_t *o = &rto_opts;
+
+ bcopy(&rto_opts_defaults, o, sizeof (*o));
+
+ while ((opt = getopt(argc, argv, "TDBSvha:o:d:s:t:")) != -1) {
+ value = 0;
+
+ switch (opt) {
+ case 'a':
+ value = strtoull(optarg, NULL, 0);
+ o->rto_ashift = MIN(13, MAX(9, value));
+ break;
+ case 'o':
+ value = strtoull(optarg, NULL, 0);
+ o->rto_offset = ((1ULL << MIN(12, value)) >> 9) << 9;
+ break;
+ case 'd':
+ value = strtoull(optarg, NULL, 0);
+ o->rto_dcols = MIN(255, MAX(1, value));
+ break;
+ case 's':
+ value = strtoull(optarg, NULL, 0);
+ o->rto_dsize = 1ULL << MIN(SPA_MAXBLOCKSHIFT,
+ MAX(SPA_MINBLOCKSHIFT, value));
+ break;
+ case 't':
+ value = strtoull(optarg, NULL, 0);
+ o->rto_sweep_timeout = value;
+ break;
+ case 'v':
+ o->rto_v++;
+ break;
+ case 'S':
+ o->rto_sweep = 1;
+ break;
+ case 'B':
+ o->rto_benchmark = 1;
+ break;
+ case 'D':
+ o->rto_gdb = 1;
+ break;
+ case 'T':
+ o->rto_sanity = 1;
+ break;
+ case 'h':
+ usage(B_TRUE);
+ break;
+ case '?':
+ default:
+ usage(B_FALSE);
+ break;
+ }
+ }
+}
+
+#define DATA_COL(rm, i) ((rm)->rm_col[raidz_parity(rm) + (i)].rc_abd)
+#define DATA_COL_SIZE(rm, i) ((rm)->rm_col[raidz_parity(rm) + (i)].rc_size)
+
+#define CODE_COL(rm, i) ((rm)->rm_col[(i)].rc_abd)
+#define CODE_COL_SIZE(rm, i) ((rm)->rm_col[(i)].rc_size)
+
+static int
+cmp_code(raidz_test_opts_t *opts, const raidz_map_t *rm, const int parity)
+{
+ int i, ret = 0;
+
+ VERIFY(parity >= 1 && parity <= 3);
+
+ for (i = 0; i < parity; i++) {
+ if (abd_cmp(CODE_COL(rm, i), CODE_COL(opts->rm_golden, i),
+ CODE_COL(rm, i)->abd_size) != 0) {
+ ret++;
+ LOG_OPT(D_DEBUG, opts,
+ "\nParity block [%d] different!\n", i);
+ }
+ }
+ return (ret);
+}
+
+static int
+cmp_data(raidz_test_opts_t *opts, raidz_map_t *rm)
+{
+ int i, ret = 0;
+ int dcols = opts->rm_golden->rm_cols - raidz_parity(opts->rm_golden);
+
+ for (i = 0; i < dcols; i++) {
+ if (abd_cmp(DATA_COL(opts->rm_golden, i), DATA_COL(rm, i),
+ DATA_COL(opts->rm_golden, i)->abd_size) != 0) {
+ ret++;
+
+ LOG_OPT(D_DEBUG, opts,
+ "\nData block [%d] different!\n", i);
+ }
+ }
+ return (ret);
+}
+
+static int
+init_rand(void *data, size_t size, void *private)
+{
+ int i;
+ int *dst = (int *)data;
+
+ for (i = 0; i < size / sizeof (int); i++)
+ dst[i] = rand_data[i];
+
+ return (0);
+}
+
+static void
+corrupt_colums(raidz_map_t *rm, const int *tgts, const int cnt)
+{
+ int i;
+ raidz_col_t *col;
+
+ for (i = 0; i < cnt; i++) {
+ col = &rm->rm_col[tgts[i]];
+ (void) abd_iterate_func(col->rc_abd, 0, col->rc_size,
+ init_rand, NULL);
+ }
+}
+
+void
+init_zio_abd(zio_t *zio)
+{
+ (void) abd_iterate_func(zio->io_abd, 0, zio->io_size, init_rand, NULL);
+}
+
+static void
+fini_raidz_map(zio_t **zio, raidz_map_t **rm)
+{
+ vdev_raidz_map_free(*rm);
+ raidz_free((*zio)->io_abd, (*zio)->io_size);
+ umem_free(*zio, sizeof (zio_t));
+
+ *zio = NULL;
+ *rm = NULL;
+}
+
+static int
+init_raidz_golden_map(raidz_test_opts_t *opts, const int parity)
+{
+ int err = 0;
+ zio_t *zio_test;
+ raidz_map_t *rm_test;
+ const size_t total_ncols = opts->rto_dcols + parity;
+
+ if (opts->rm_golden) {
+ fini_raidz_map(&opts->zio_golden, &opts->rm_golden);
+ }
+
+ opts->zio_golden = umem_zalloc(sizeof (zio_t), UMEM_NOFAIL);
+ zio_test = umem_zalloc(sizeof (zio_t), UMEM_NOFAIL);
+
+ opts->zio_golden->io_offset = zio_test->io_offset = opts->rto_offset;
+ opts->zio_golden->io_size = zio_test->io_size = opts->rto_dsize;
+
+ opts->zio_golden->io_abd = raidz_alloc(opts->rto_dsize);
+ zio_test->io_abd = raidz_alloc(opts->rto_dsize);
+
+ init_zio_abd(opts->zio_golden);
+ init_zio_abd(zio_test);
+
+ VERIFY0(vdev_raidz_impl_set("original"));
+
+ opts->rm_golden = vdev_raidz_map_alloc(opts->zio_golden,
+ opts->rto_ashift, total_ncols, parity);
+ rm_test = vdev_raidz_map_alloc(zio_test,
+ opts->rto_ashift, total_ncols, parity);
+
+ VERIFY(opts->zio_golden);
+ VERIFY(opts->rm_golden);
+
+ vdev_raidz_generate_parity(opts->rm_golden);
+ vdev_raidz_generate_parity(rm_test);
+
+ /* sanity check */
+ err |= cmp_data(opts, rm_test);
+ err |= cmp_code(opts, rm_test, parity);
+
+ if (err)
+ ERRMSG("initializing the golden copy ... [FAIL]!\n");
+
+ /* tear down raidz_map of test zio */
+ fini_raidz_map(&zio_test, &rm_test);
+
+ return (err);
+}
+
+static raidz_map_t *
+init_raidz_map(raidz_test_opts_t *opts, zio_t **zio, const int parity)
+{
+ raidz_map_t *rm = NULL;
+ const size_t alloc_dsize = opts->rto_dsize;
+ const size_t total_ncols = opts->rto_dcols + parity;
+ const int ccols[] = { 0, 1, 2 };
+
+ VERIFY(zio);
+ VERIFY(parity <= 3 && parity >= 1);
+
+ *zio = umem_zalloc(sizeof (zio_t), UMEM_NOFAIL);
+
+ (*zio)->io_offset = 0;
+ (*zio)->io_size = alloc_dsize;
+ (*zio)->io_abd = raidz_alloc(alloc_dsize);
+ init_zio_abd(*zio);
+
+ rm = vdev_raidz_map_alloc(*zio, opts->rto_ashift,
+ total_ncols, parity);
+ VERIFY(rm);
+
+ /* Make sure code columns are destroyed */
+ corrupt_colums(rm, ccols, parity);
+
+ return (rm);
+}
+
+static int
+run_gen_check(raidz_test_opts_t *opts)
+{
+ char **impl_name;
+ int fn, err = 0;
+ zio_t *zio_test;
+ raidz_map_t *rm_test;
+
+ err = init_raidz_golden_map(opts, PARITY_PQR);
+ if (0 != err)
+ return (err);
+
+ LOG(D_INFO, DBLSEP);
+ LOG(D_INFO, "Testing parity generation...\n");
+
+ for (impl_name = (char **)raidz_impl_names+1; *impl_name != NULL;
+ impl_name++) {
+
+ LOG(D_INFO, SEP);
+ LOG(D_INFO, "\tTesting [%s] implementation...", *impl_name);
+
+ if (0 != vdev_raidz_impl_set(*impl_name)) {
+ LOG(D_INFO, "[SKIP]\n");
+ continue;
+ } else {
+ LOG(D_INFO, "[SUPPORTED]\n");
+ }
+
+ for (fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
+
+ /* Check if should stop */
+ if (rto_opts.rto_should_stop)
+ return (err);
+
+ /* create suitable raidz_map */
+ rm_test = init_raidz_map(opts, &zio_test, fn+1);
+ VERIFY(rm_test);
+
+ LOG(D_INFO, "\t\tTesting method [%s] ...",
+ raidz_gen_name[fn]);
+
+ if (!opts->rto_sanity)
+ vdev_raidz_generate_parity(rm_test);
+
+ if (cmp_code(opts, rm_test, fn+1) != 0) {
+ LOG(D_INFO, "[FAIL]\n");
+ err++;
+ } else
+ LOG(D_INFO, "[PASS]\n");
+
+ fini_raidz_map(&zio_test, &rm_test);
+ }
+ }
+
+ fini_raidz_map(&opts->zio_golden, &opts->rm_golden);
+
+ return (err);
+}
+
+static int
+run_rec_check_impl(raidz_test_opts_t *opts, raidz_map_t *rm, const int fn)
+{
+ int x0, x1, x2;
+ int tgtidx[3];
+ int err = 0;
+ static const int rec_tgts[7][3] = {
+ {1, 2, 3}, /* rec_p: bad QR & D[0] */
+ {0, 2, 3}, /* rec_q: bad PR & D[0] */
+ {0, 1, 3}, /* rec_r: bad PQ & D[0] */
+ {2, 3, 4}, /* rec_pq: bad R & D[0][1] */
+ {1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
+ {0, 3, 4}, /* rec_qr: bad P & D[0][1] */
+ {3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
+ };
+
+ memcpy(tgtidx, rec_tgts[fn], sizeof (tgtidx));
+
+ if (fn < RAIDZ_REC_PQ) {
+ /* can reconstruct 1 failed data disk */
+ for (x0 = 0; x0 < opts->rto_dcols; x0++) {
+ if (x0 >= rm->rm_cols - raidz_parity(rm))
+ continue;
+
+ /* Check if should stop */
+ if (rto_opts.rto_should_stop)
+ return (err);
+
+ LOG(D_DEBUG, "[%d] ", x0);
+
+ tgtidx[2] = x0 + raidz_parity(rm);
+
+ corrupt_colums(rm, tgtidx+2, 1);
+
+ if (!opts->rto_sanity)
+ (void) vdev_raidz_reconstruct(rm, tgtidx, 3);
+
+ if (cmp_data(opts, rm) != 0) {
+ err++;
+ LOG(D_DEBUG, "\nREC D[%d]... [FAIL]\n", x0);
+ }
+ }
+
+ } else if (fn < RAIDZ_REC_PQR) {
+ /* can reconstruct 2 failed data disk */
+ for (x0 = 0; x0 < opts->rto_dcols; x0++) {
+ if (x0 >= rm->rm_cols - raidz_parity(rm))
+ continue;
+ for (x1 = x0 + 1; x1 < opts->rto_dcols; x1++) {
+ if (x1 >= rm->rm_cols - raidz_parity(rm))
+ continue;
+
+ /* Check if should stop */
+ if (rto_opts.rto_should_stop)
+ return (err);
+
+ LOG(D_DEBUG, "[%d %d] ", x0, x1);
+
+ tgtidx[1] = x0 + raidz_parity(rm);
+ tgtidx[2] = x1 + raidz_parity(rm);
+
+ corrupt_colums(rm, tgtidx+1, 2);
+
+ if (!opts->rto_sanity)
+ (void) vdev_raidz_reconstruct(rm,
+ tgtidx, 3);
+
+ if (cmp_data(opts, rm) != 0) {
+ err++;
+ LOG(D_DEBUG, "\nREC D[%d %d]... "
+ "[FAIL]\n", x0, x1);
+ }
+ }
+ }
+ } else {
+ /* can reconstruct 3 failed data disk */
+ for (x0 = 0; x0 < opts->rto_dcols; x0++) {
+ if (x0 >= rm->rm_cols - raidz_parity(rm))
+ continue;
+ for (x1 = x0 + 1; x1 < opts->rto_dcols; x1++) {
+ if (x1 >= rm->rm_cols - raidz_parity(rm))
+ continue;
+ for (x2 = x1 + 1; x2 < opts->rto_dcols; x2++) {
+ if (x2 >=
+ rm->rm_cols - raidz_parity(rm))
+ continue;
+
+ /* Check if should stop */
+ if (rto_opts.rto_should_stop)
+ return (err);
+
+ LOG(D_DEBUG, "[%d %d %d]", x0, x1, x2);
+
+ tgtidx[0] = x0 + raidz_parity(rm);
+ tgtidx[1] = x1 + raidz_parity(rm);
+ tgtidx[2] = x2 + raidz_parity(rm);
+
+ corrupt_colums(rm, tgtidx, 3);
+
+ if (!opts->rto_sanity)
+ (void) vdev_raidz_reconstruct(
+ rm, tgtidx, 3);
+
+ if (cmp_data(opts, rm) != 0) {
+ err++;
+ LOG(D_DEBUG,
+ "\nREC D[%d %d %d]... "
+ "[FAIL]\n", x0, x1, x2);
+ }
+ }
+ }
+ }
+ }
+ return (err);
+}
+
+static int
+run_rec_check(raidz_test_opts_t *opts)
+{
+ char **impl_name;
+ unsigned fn, err = 0;
+ zio_t *zio_test;
+ raidz_map_t *rm_test;
+
+ err = init_raidz_golden_map(opts, PARITY_PQR);
+ if (0 != err)
+ return (err);
+
+ LOG(D_INFO, DBLSEP);
+ LOG(D_INFO, "Testing data reconstruction...\n");
+
+ for (impl_name = (char **)raidz_impl_names+1; *impl_name != NULL;
+ impl_name++) {
+
+ LOG(D_INFO, SEP);
+ LOG(D_INFO, "\tTesting [%s] implementation...", *impl_name);
+
+ if (vdev_raidz_impl_set(*impl_name) != 0) {
+ LOG(D_INFO, "[SKIP]\n");
+ continue;
+ } else
+ LOG(D_INFO, "[SUPPORTED]\n");
+
+
+ /* create suitable raidz_map */
+ rm_test = init_raidz_map(opts, &zio_test, PARITY_PQR);
+ /* generate parity */
+ vdev_raidz_generate_parity(rm_test);
+
+ for (fn = 0; fn < RAIDZ_REC_NUM; fn++) {
+
+ LOG(D_INFO, "\t\tTesting method [%s] ...",
+ raidz_rec_name[fn]);
+
+ if (run_rec_check_impl(opts, rm_test, fn) != 0) {
+ LOG(D_INFO, "[FAIL]\n");
+ err++;
+
+ } else
+ LOG(D_INFO, "[PASS]\n");
+
+ }
+ /* tear down test raidz_map */
+ fini_raidz_map(&zio_test, &rm_test);
+ }
+
+ fini_raidz_map(&opts->zio_golden, &opts->rm_golden);
+
+ return (err);
+}
+
+static int
+run_test(raidz_test_opts_t *opts)
+{
+ int err = 0;
+
+ if (opts == NULL)
+ opts = &rto_opts;
+
+ print_opts(opts, B_FALSE);
+
+ err |= run_gen_check(opts);
+ err |= run_rec_check(opts);
+
+ return (err);
+}
+
+#define SWEEP_RUNNING 0
+#define SWEEP_FINISHED 1
+#define SWEEP_ERROR 2
+#define SWEEP_TIMEOUT 3
+
+static int sweep_state = 0;
+static raidz_test_opts_t failed_opts;
+
+static kmutex_t sem_mtx;
+static kcondvar_t sem_cv;
+static int max_free_slots;
+static int free_slots;
+
+static void
+sweep_thread(void *arg)
+{
+ int err = 0;
+ raidz_test_opts_t *opts = (raidz_test_opts_t *)arg;
+ VERIFY(opts != NULL);
+
+ err = run_test(opts);
+
+ if (rto_opts.rto_sanity) {
+ /* 25% chance that a sweep test fails */
+ if (rand() < (RAND_MAX/4))
+ err = 1;
+ }
+
+ if (0 != err) {
+ mutex_enter(&sem_mtx);
+ memcpy(&failed_opts, opts, sizeof (raidz_test_opts_t));
+ sweep_state = SWEEP_ERROR;
+ mutex_exit(&sem_mtx);
+ }
+
+ umem_free(opts, sizeof (raidz_test_opts_t));
+
+ /* signal the next thread */
+ mutex_enter(&sem_mtx);
+ free_slots++;
+ cv_signal(&sem_cv);
+ mutex_exit(&sem_mtx);
+
+ thread_exit();
+}
+
+static int
+run_sweep(void)
+{
+ static const size_t dcols_v[] = { 1, 2, 3, 4, 5, 6, 7, 8, 12, 15, 16 };
+ static const size_t ashift_v[] = { 9, 12, 14 };
+ static const size_t size_v[] = { 1 << 9, 21 * (1 << 9), 13 * (1 << 12),
+ 1 << 17, (1 << 20) - (1 << 12), SPA_MAXBLOCKSIZE };
+
+ (void) setvbuf(stdout, NULL, _IONBF, 0);
+
+ ulong_t total_comb = ARRAY_SIZE(size_v) * ARRAY_SIZE(ashift_v) *
+ ARRAY_SIZE(dcols_v);
+ ulong_t tried_comb = 0;
+ hrtime_t time_diff, start_time = gethrtime();
+ raidz_test_opts_t *opts;
+ int a, d, s;
+
+ max_free_slots = free_slots = MAX(2, boot_ncpus);
+
+ mutex_init(&sem_mtx, NULL, MUTEX_DEFAULT, NULL);
+ cv_init(&sem_cv, NULL, CV_DEFAULT, NULL);
+
+ for (s = 0; s < ARRAY_SIZE(size_v); s++)
+ for (a = 0; a < ARRAY_SIZE(ashift_v); a++)
+ for (d = 0; d < ARRAY_SIZE(dcols_v); d++) {
+
+ if (size_v[s] < (1 << ashift_v[a])) {
+ total_comb--;
+ continue;
+ }
+
+ if (++tried_comb % 20 == 0)
+ LOG(D_ALL, "%lu/%lu... ", tried_comb, total_comb);
+
+ /* wait for signal to start new thread */
+ mutex_enter(&sem_mtx);
+ while (cv_timedwait_sig(&sem_cv, &sem_mtx,
+ ddi_get_lbolt() + hz)) {
+
+ /* check if should stop the test (timeout) */
+ time_diff = (gethrtime() - start_time) / NANOSEC;
+ if (rto_opts.rto_sweep_timeout > 0 &&
+ time_diff >= rto_opts.rto_sweep_timeout) {
+ sweep_state = SWEEP_TIMEOUT;
+ rto_opts.rto_should_stop = B_TRUE;
+ mutex_exit(&sem_mtx);
+ goto exit;
+ }
+
+ /* check if should stop the test (error) */
+ if (sweep_state != SWEEP_RUNNING) {
+ mutex_exit(&sem_mtx);
+ goto exit;
+ }
+
+ /* exit loop if a slot is available */
+ if (free_slots > 0) {
+ break;
+ }
+ }
+
+ free_slots--;
+ mutex_exit(&sem_mtx);
+
+ opts = umem_zalloc(sizeof (raidz_test_opts_t), UMEM_NOFAIL);
+ opts->rto_ashift = ashift_v[a];
+ opts->rto_dcols = dcols_v[d];
+ opts->rto_offset = (1 << ashift_v[a]) * rand();
+ opts->rto_dsize = size_v[s];
+ opts->rto_v = 0; /* be quiet */
+
+ VERIFY3P(thread_create(NULL, 0, sweep_thread, (void *) opts,
+ 0, NULL, TS_RUN, maxclsyspri), !=, NULL);
+ }
+
+exit:
+ LOG(D_ALL, "\nWaiting for test threads to finish...\n");
+ mutex_enter(&sem_mtx);
+ VERIFY(free_slots <= max_free_slots);
+ while (free_slots < max_free_slots) {
+ (void) cv_wait(&sem_cv, &sem_mtx);
+ }
+ mutex_exit(&sem_mtx);
+
+ if (sweep_state == SWEEP_ERROR) {
+ ERRMSG("Sweep test failed! Failed option: \n");
+ print_opts(&failed_opts, B_TRUE);
+ } else {
+ if (sweep_state == SWEEP_TIMEOUT)
+ LOG(D_ALL, "Test timeout (%lus). Stopping...\n",
+ (ulong_t)rto_opts.rto_sweep_timeout);
+
+ LOG(D_ALL, "Sweep test succeeded on %lu raidz maps!\n",
+ (ulong_t)tried_comb);
+ }
+
+ mutex_destroy(&sem_mtx);
+
+ return (sweep_state == SWEEP_ERROR ? SWEEP_ERROR : 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ size_t i;
+ int err = 0;
+
+ /* init gdb string early */
+ (void) sprintf(gdb, gdb_tmpl, getpid());
+
+ (void) setvbuf(stdout, NULL, _IOLBF, 0);
+
+ dprintf_setup(&argc, argv);
+
+ process_options(argc, argv);
+
+ kernel_init(FREAD);
+
+ /* setup random data because rand() is not reentrant */
+ rand_data = (int *)umem_alloc(SPA_MAXBLOCKSIZE, UMEM_NOFAIL);
+ srand((unsigned)time(NULL) * getpid());
+ for (i = 0; i < SPA_MAXBLOCKSIZE / sizeof (int); i++)
+ rand_data[i] = rand();
+
+ mprotect((void *)rand_data, SPA_MAXBLOCKSIZE, PROT_READ);
+
+ if (rto_opts.rto_benchmark) {
+ run_raidz_benchmark();
+ } else if (rto_opts.rto_sweep) {
+ err = run_sweep();
+ } else {
+ err = run_test(NULL);
+ }
+
+ umem_free(rand_data, SPA_MAXBLOCKSIZE);
+ kernel_fini();
+
+ return (err);
+}
diff --git a/usr/src/cmd/raidz_test/raidz_test.h b/usr/src/cmd/raidz_test/raidz_test.h
new file mode 100644
index 0000000000..c91e521436
--- /dev/null
+++ b/usr/src/cmd/raidz_test/raidz_test.h
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
+ */
+
+#ifndef RAIDZ_TEST_H
+#define RAIDZ_TEST_H
+
+#include <sys/spa.h>
+
+static const char *raidz_impl_names[] = {
+ "original",
+ "scalar",
+ "sse2",
+ "ssse3",
+ "avx2",
+ "avx512f",
+ "avx512bw",
+ "aarch64_neon",
+ "aarch64_neonx2",
+ "powerpc_altivec",
+ NULL
+};
+
+typedef struct raidz_test_opts {
+ size_t rto_ashift;
+ size_t rto_offset;
+ size_t rto_dcols;
+ size_t rto_dsize;
+ size_t rto_v;
+ size_t rto_sweep;
+ size_t rto_sweep_timeout;
+ size_t rto_benchmark;
+ size_t rto_sanity;
+ size_t rto_gdb;
+
+ /* non-user options */
+ boolean_t rto_should_stop;
+
+ zio_t *zio_golden;
+ raidz_map_t *rm_golden;
+} raidz_test_opts_t;
+
+static const raidz_test_opts_t rto_opts_defaults = {
+ .rto_ashift = 9,
+ .rto_offset = 1ULL << 0,
+ .rto_dcols = 8,
+ .rto_dsize = 1<<19,
+ .rto_v = 0,
+ .rto_sweep = 0,
+ .rto_benchmark = 0,
+ .rto_sanity = 0,
+ .rto_gdb = 0,
+ .rto_should_stop = B_FALSE
+};
+
+extern raidz_test_opts_t rto_opts;
+
+static inline size_t ilog2(size_t a)
+{
+ return (a > 1 ? 1 + ilog2(a >> 1) : 0);
+}
+
+
+#define D_ALL 0
+#define D_INFO 1
+#define D_DEBUG 2
+
+#define LOG(lvl, a...) \
+{ \
+ if (rto_opts.rto_v >= lvl) \
+ (void) fprintf(stdout, a); \
+} \
+
+#define LOG_OPT(lvl, opt, a...) \
+{ \
+ if (opt->rto_v >= lvl) \
+ (void) fprintf(stdout, a); \
+} \
+
+#define ERRMSG(a...) (void) fprintf(stderr, a)
+
+
+#define DBLSEP "================\n"
+#define SEP "----------------\n"
+
+
+#define raidz_alloc(size) abd_alloc(size, B_FALSE)
+#define raidz_free(p, size) abd_free(p)
+
+
+void init_zio_abd(zio_t *zio);
+
+void run_raidz_benchmark(void);
+
+#endif /* RAIDZ_TEST_H */
diff --git a/usr/src/compat/bhyve/README b/usr/src/compat/bhyve/README
new file mode 100644
index 0000000000..87ceb83695
--- /dev/null
+++ b/usr/src/compat/bhyve/README
@@ -0,0 +1,9 @@
+These are the compatibility headers for building bhyve on illumos. They are
+comprised of the shims and glue needed to use native functionality as the
+backing for FreeBSD interfaces. It often means heavy use of #include_next,
+#define renames, and forward definitions to some glue functions.
+
+For headers which would otherwise be copied verbatim from FreeBSD, the
+usr/src/contrib/bhyve area is the appropriate home. This allows us to carry
+only the bare minimum in the 'compat' headers while making updates for the
+'contrib' headers easy (simply copy over the new version).
diff --git a/usr/src/compat/freebsd/amd64/machine/asmacros.h b/usr/src/compat/bhyve/amd64/machine/asmacros.h
index 1f6955130b..1f6955130b 100644
--- a/usr/src/compat/freebsd/amd64/machine/asmacros.h
+++ b/usr/src/compat/bhyve/amd64/machine/asmacros.h
diff --git a/usr/src/compat/freebsd/amd64/machine/atomic.h b/usr/src/compat/bhyve/amd64/machine/atomic.h
index 1da9724b7d..1da9724b7d 100644
--- a/usr/src/compat/freebsd/amd64/machine/atomic.h
+++ b/usr/src/compat/bhyve/amd64/machine/atomic.h
diff --git a/usr/src/compat/freebsd/amd64/machine/clock.h b/usr/src/compat/bhyve/amd64/machine/clock.h
index f50b42a126..f50b42a126 100644
--- a/usr/src/compat/freebsd/amd64/machine/clock.h
+++ b/usr/src/compat/bhyve/amd64/machine/clock.h
diff --git a/usr/src/compat/freebsd/amd64/machine/cpu.h b/usr/src/compat/bhyve/amd64/machine/cpu.h
index 40253af108..40253af108 100644
--- a/usr/src/compat/freebsd/amd64/machine/cpu.h
+++ b/usr/src/compat/bhyve/amd64/machine/cpu.h
diff --git a/usr/src/compat/freebsd/amd64/machine/cpufunc.h b/usr/src/compat/bhyve/amd64/machine/cpufunc.h
index 0b7bcdaa59..0b7bcdaa59 100644
--- a/usr/src/compat/freebsd/amd64/machine/cpufunc.h
+++ b/usr/src/compat/bhyve/amd64/machine/cpufunc.h
diff --git a/usr/src/compat/freebsd/amd64/machine/fpu.h b/usr/src/compat/bhyve/amd64/machine/fpu.h
index 6bc651d996..6bc651d996 100644
--- a/usr/src/compat/freebsd/amd64/machine/fpu.h
+++ b/usr/src/compat/bhyve/amd64/machine/fpu.h
diff --git a/usr/src/compat/freebsd/amd64/machine/iodev.h b/usr/src/compat/bhyve/amd64/machine/iodev.h
index c7cdddc817..c7cdddc817 100644
--- a/usr/src/compat/freebsd/amd64/machine/iodev.h
+++ b/usr/src/compat/bhyve/amd64/machine/iodev.h
diff --git a/usr/src/compat/freebsd/amd64/machine/md_var.h b/usr/src/compat/bhyve/amd64/machine/md_var.h
index ed57a8bebc..ed57a8bebc 100644
--- a/usr/src/compat/freebsd/amd64/machine/md_var.h
+++ b/usr/src/compat/bhyve/amd64/machine/md_var.h
diff --git a/usr/src/compat/freebsd/amd64/machine/param.h b/usr/src/compat/bhyve/amd64/machine/param.h
index b152f4d526..b152f4d526 100644
--- a/usr/src/compat/freebsd/amd64/machine/param.h
+++ b/usr/src/compat/bhyve/amd64/machine/param.h
diff --git a/usr/src/compat/freebsd/amd64/machine/pcb.h b/usr/src/compat/bhyve/amd64/machine/pcb.h
index 75b5de640c..75b5de640c 100644
--- a/usr/src/compat/freebsd/amd64/machine/pcb.h
+++ b/usr/src/compat/bhyve/amd64/machine/pcb.h
diff --git a/usr/src/compat/freebsd/amd64/machine/pmap.h b/usr/src/compat/bhyve/amd64/machine/pmap.h
index ce3185629b..ce3185629b 100644
--- a/usr/src/compat/freebsd/amd64/machine/pmap.h
+++ b/usr/src/compat/bhyve/amd64/machine/pmap.h
diff --git a/usr/src/compat/freebsd/amd64/machine/reg.h b/usr/src/compat/bhyve/amd64/machine/reg.h
index 4a73463603..4a73463603 100644
--- a/usr/src/compat/freebsd/amd64/machine/reg.h
+++ b/usr/src/compat/bhyve/amd64/machine/reg.h
diff --git a/usr/src/compat/freebsd/amd64/machine/segments.h b/usr/src/compat/bhyve/amd64/machine/segments.h
index d0655f4a0e..d0655f4a0e 100644
--- a/usr/src/compat/freebsd/amd64/machine/segments.h
+++ b/usr/src/compat/bhyve/amd64/machine/segments.h
diff --git a/usr/src/compat/freebsd/amd64/machine/smp.h b/usr/src/compat/bhyve/amd64/machine/smp.h
index 9c4f2d111b..9c4f2d111b 100644
--- a/usr/src/compat/freebsd/amd64/machine/smp.h
+++ b/usr/src/compat/bhyve/amd64/machine/smp.h
diff --git a/usr/src/compat/freebsd/amd64/machine/specialreg.h b/usr/src/compat/bhyve/amd64/machine/specialreg.h
index ead63aaaab..ead63aaaab 100644
--- a/usr/src/compat/freebsd/amd64/machine/specialreg.h
+++ b/usr/src/compat/bhyve/amd64/machine/specialreg.h
diff --git a/usr/src/compat/freebsd/amd64/machine/vmm.h b/usr/src/compat/bhyve/amd64/machine/vmm.h
index 1c54c0830d..1c54c0830d 100644
--- a/usr/src/compat/freebsd/amd64/machine/vmm.h
+++ b/usr/src/compat/bhyve/amd64/machine/vmm.h
diff --git a/usr/src/compat/freebsd/amd64/machine/vmm_dev.h b/usr/src/compat/bhyve/amd64/machine/vmm_dev.h
index fe9cb6c705..fe9cb6c705 100644
--- a/usr/src/compat/freebsd/amd64/machine/vmm_dev.h
+++ b/usr/src/compat/bhyve/amd64/machine/vmm_dev.h
diff --git a/usr/src/compat/freebsd/amd64/machine/vmm_instruction_emul.h b/usr/src/compat/bhyve/amd64/machine/vmm_instruction_emul.h
index 02c3f391c7..02c3f391c7 100644
--- a/usr/src/compat/freebsd/amd64/machine/vmm_instruction_emul.h
+++ b/usr/src/compat/bhyve/amd64/machine/vmm_instruction_emul.h
diff --git a/usr/src/compat/freebsd/amd64/machine/vmparam.h b/usr/src/compat/bhyve/amd64/machine/vmparam.h
index c76a3259f3..c76a3259f3 100644
--- a/usr/src/compat/freebsd/amd64/machine/vmparam.h
+++ b/usr/src/compat/bhyve/amd64/machine/vmparam.h
diff --git a/usr/src/compat/freebsd/contrib/dev/acpica/include/acpi.h b/usr/src/compat/bhyve/contrib/dev/acpica/include/acpi.h
index 2668f98ab3..2668f98ab3 100644
--- a/usr/src/compat/freebsd/contrib/dev/acpica/include/acpi.h
+++ b/usr/src/compat/bhyve/contrib/dev/acpica/include/acpi.h
diff --git a/usr/src/compat/freebsd/dev/pci/pcivar.h b/usr/src/compat/bhyve/dev/pci/pcivar.h
index 064d983117..064d983117 100644
--- a/usr/src/compat/freebsd/dev/pci/pcivar.h
+++ b/usr/src/compat/bhyve/dev/pci/pcivar.h
diff --git a/usr/src/compat/freebsd/err.h b/usr/src/compat/bhyve/err.h
index 40d144e025..40d144e025 100644
--- a/usr/src/compat/freebsd/err.h
+++ b/usr/src/compat/bhyve/err.h
diff --git a/usr/src/compat/freebsd/libutil.h b/usr/src/compat/bhyve/libutil.h
index f899d4425e..f899d4425e 100644
--- a/usr/src/compat/freebsd/libutil.h
+++ b/usr/src/compat/bhyve/libutil.h
diff --git a/usr/src/compat/freebsd/net/ethernet.h b/usr/src/compat/bhyve/net/ethernet.h
index dcd3a58925..dcd3a58925 100644
--- a/usr/src/compat/freebsd/net/ethernet.h
+++ b/usr/src/compat/bhyve/net/ethernet.h
diff --git a/usr/src/compat/freebsd/net/ieee_oui.h b/usr/src/compat/bhyve/net/ieee_oui.h
index 068328d833..068328d833 100644
--- a/usr/src/compat/freebsd/net/ieee_oui.h
+++ b/usr/src/compat/bhyve/net/ieee_oui.h
diff --git a/usr/src/compat/freebsd/paths.h b/usr/src/compat/bhyve/paths.h
index e43c963f93..e43c963f93 100644
--- a/usr/src/compat/freebsd/paths.h
+++ b/usr/src/compat/bhyve/paths.h
diff --git a/usr/src/compat/freebsd/pthread_np.h b/usr/src/compat/bhyve/pthread_np.h
index c4f76b259c..c4f76b259c 100644
--- a/usr/src/compat/freebsd/pthread_np.h
+++ b/usr/src/compat/bhyve/pthread_np.h
diff --git a/usr/src/compat/freebsd/string.h b/usr/src/compat/bhyve/string.h
index 7e0f5c7ddc..7e0f5c7ddc 100644
--- a/usr/src/compat/freebsd/string.h
+++ b/usr/src/compat/bhyve/string.h
diff --git a/usr/src/compat/freebsd/strings.h b/usr/src/compat/bhyve/strings.h
index fa3539fb96..fa3539fb96 100644
--- a/usr/src/compat/freebsd/strings.h
+++ b/usr/src/compat/bhyve/strings.h
diff --git a/usr/src/compat/freebsd/sys/_cpuset.h b/usr/src/compat/bhyve/sys/_cpuset.h
index 286d26fc00..286d26fc00 100644
--- a/usr/src/compat/freebsd/sys/_cpuset.h
+++ b/usr/src/compat/bhyve/sys/_cpuset.h
diff --git a/usr/src/compat/freebsd/sys/_iovec.h b/usr/src/compat/bhyve/sys/_iovec.h
index b755ae7e21..b755ae7e21 100644
--- a/usr/src/compat/freebsd/sys/_iovec.h
+++ b/usr/src/compat/bhyve/sys/_iovec.h
diff --git a/usr/src/compat/freebsd/sys/_pthreadtypes.h b/usr/src/compat/bhyve/sys/_pthreadtypes.h
index d746da3712..d746da3712 100644
--- a/usr/src/compat/freebsd/sys/_pthreadtypes.h
+++ b/usr/src/compat/bhyve/sys/_pthreadtypes.h
diff --git a/usr/src/compat/freebsd/sys/_types.h b/usr/src/compat/bhyve/sys/_types.h
index 62c327d216..62c327d216 100644
--- a/usr/src/compat/freebsd/sys/_types.h
+++ b/usr/src/compat/bhyve/sys/_types.h
diff --git a/usr/src/compat/freebsd/sys/bus.h b/usr/src/compat/bhyve/sys/bus.h
index e3b5e0e69d..e3b5e0e69d 100644
--- a/usr/src/compat/freebsd/sys/bus.h
+++ b/usr/src/compat/bhyve/sys/bus.h
diff --git a/usr/src/compat/freebsd/sys/callout.h b/usr/src/compat/bhyve/sys/callout.h
index 11823e6321..11823e6321 100644
--- a/usr/src/compat/freebsd/sys/callout.h
+++ b/usr/src/compat/bhyve/sys/callout.h
diff --git a/usr/src/compat/freebsd/sys/cdefs.h b/usr/src/compat/bhyve/sys/cdefs.h
index 0b857437e3..0b857437e3 100644
--- a/usr/src/compat/freebsd/sys/cdefs.h
+++ b/usr/src/compat/bhyve/sys/cdefs.h
diff --git a/usr/src/compat/freebsd/sys/clock.h b/usr/src/compat/bhyve/sys/clock.h
index ebf7f171a3..ebf7f171a3 100644
--- a/usr/src/compat/freebsd/sys/clock.h
+++ b/usr/src/compat/bhyve/sys/clock.h
diff --git a/usr/src/compat/freebsd/sys/cpuset.h b/usr/src/compat/bhyve/sys/cpuset.h
index 626b323d7d..626b323d7d 100644
--- a/usr/src/compat/freebsd/sys/cpuset.h
+++ b/usr/src/compat/bhyve/sys/cpuset.h
diff --git a/usr/src/compat/freebsd/sys/disk.h b/usr/src/compat/bhyve/sys/disk.h
index c9bdc6a2d8..c9bdc6a2d8 100644
--- a/usr/src/compat/freebsd/sys/disk.h
+++ b/usr/src/compat/bhyve/sys/disk.h
diff --git a/usr/src/compat/freebsd/sys/endian.h b/usr/src/compat/bhyve/sys/endian.h
index 24ea02d251..24ea02d251 100644
--- a/usr/src/compat/freebsd/sys/endian.h
+++ b/usr/src/compat/bhyve/sys/endian.h
diff --git a/usr/src/compat/freebsd/sys/errno.h b/usr/src/compat/bhyve/sys/errno.h
index bd37f43065..bd37f43065 100644
--- a/usr/src/compat/freebsd/sys/errno.h
+++ b/usr/src/compat/bhyve/sys/errno.h
diff --git a/usr/src/compat/freebsd/sys/eventhandler.h b/usr/src/compat/bhyve/sys/eventhandler.h
index 133aa664f0..133aa664f0 100644
--- a/usr/src/compat/freebsd/sys/eventhandler.h
+++ b/usr/src/compat/bhyve/sys/eventhandler.h
diff --git a/usr/src/compat/freebsd/sys/fcntl.h b/usr/src/compat/bhyve/sys/fcntl.h
index 062a3b84ac..062a3b84ac 100644
--- a/usr/src/compat/freebsd/sys/fcntl.h
+++ b/usr/src/compat/bhyve/sys/fcntl.h
diff --git a/usr/src/compat/freebsd/sys/ioctl.h b/usr/src/compat/bhyve/sys/ioctl.h
index 72a46b8085..72a46b8085 100644
--- a/usr/src/compat/freebsd/sys/ioctl.h
+++ b/usr/src/compat/bhyve/sys/ioctl.h
diff --git a/usr/src/compat/freebsd/sys/kernel.h b/usr/src/compat/bhyve/sys/kernel.h
index adf96f40fc..adf96f40fc 100644
--- a/usr/src/compat/freebsd/sys/kernel.h
+++ b/usr/src/compat/bhyve/sys/kernel.h
diff --git a/usr/src/compat/freebsd/sys/ktr.h b/usr/src/compat/bhyve/sys/ktr.h
index 96c499ef18..96c499ef18 100644
--- a/usr/src/compat/freebsd/sys/ktr.h
+++ b/usr/src/compat/bhyve/sys/ktr.h
diff --git a/usr/src/compat/freebsd/sys/libkern.h b/usr/src/compat/bhyve/sys/libkern.h
index 94675a0d66..94675a0d66 100644
--- a/usr/src/compat/freebsd/sys/libkern.h
+++ b/usr/src/compat/bhyve/sys/libkern.h
diff --git a/usr/src/compat/freebsd/sys/limits.h b/usr/src/compat/bhyve/sys/limits.h
index 0e66319791..0e66319791 100644
--- a/usr/src/compat/freebsd/sys/limits.h
+++ b/usr/src/compat/bhyve/sys/limits.h
diff --git a/usr/src/compat/freebsd/sys/lock.h b/usr/src/compat/bhyve/sys/lock.h
index fd6021a87e..fd6021a87e 100644
--- a/usr/src/compat/freebsd/sys/lock.h
+++ b/usr/src/compat/bhyve/sys/lock.h
diff --git a/usr/src/compat/freebsd/sys/malloc.h b/usr/src/compat/bhyve/sys/malloc.h
index 341d57b807..341d57b807 100644
--- a/usr/src/compat/freebsd/sys/malloc.h
+++ b/usr/src/compat/bhyve/sys/malloc.h
diff --git a/usr/src/compat/freebsd/sys/module.h b/usr/src/compat/bhyve/sys/module.h
index 87b73e3fa3..87b73e3fa3 100644
--- a/usr/src/compat/freebsd/sys/module.h
+++ b/usr/src/compat/bhyve/sys/module.h
diff --git a/usr/src/compat/freebsd/sys/mutex.h b/usr/src/compat/bhyve/sys/mutex.h
index 9e588cb98a..9e588cb98a 100644
--- a/usr/src/compat/freebsd/sys/mutex.h
+++ b/usr/src/compat/bhyve/sys/mutex.h
diff --git a/usr/src/compat/freebsd/sys/param.h b/usr/src/compat/bhyve/sys/param.h
index 5ba21a2809..5ba21a2809 100644
--- a/usr/src/compat/freebsd/sys/param.h
+++ b/usr/src/compat/bhyve/sys/param.h
diff --git a/usr/src/compat/freebsd/sys/pcpu.h b/usr/src/compat/bhyve/sys/pcpu.h
index 1bad53c159..1bad53c159 100644
--- a/usr/src/compat/freebsd/sys/pcpu.h
+++ b/usr/src/compat/bhyve/sys/pcpu.h
diff --git a/usr/src/compat/freebsd/sys/sched.h b/usr/src/compat/bhyve/sys/sched.h
index b426ee757e..b426ee757e 100644
--- a/usr/src/compat/freebsd/sys/sched.h
+++ b/usr/src/compat/bhyve/sys/sched.h
diff --git a/usr/src/compat/freebsd/sys/sdt.h b/usr/src/compat/bhyve/sys/sdt.h
index 32d887c0d8..32d887c0d8 100644
--- a/usr/src/compat/freebsd/sys/sdt.h
+++ b/usr/src/compat/bhyve/sys/sdt.h
diff --git a/usr/src/compat/freebsd/sys/select.h b/usr/src/compat/bhyve/sys/select.h
index fcb40c23b1..fcb40c23b1 100644
--- a/usr/src/compat/freebsd/sys/select.h
+++ b/usr/src/compat/bhyve/sys/select.h
diff --git a/usr/src/compat/freebsd/sys/sglist.h b/usr/src/compat/bhyve/sys/sglist.h
index 519c67915f..519c67915f 100644
--- a/usr/src/compat/freebsd/sys/sglist.h
+++ b/usr/src/compat/bhyve/sys/sglist.h
diff --git a/usr/src/compat/freebsd/sys/smp.h b/usr/src/compat/bhyve/sys/smp.h
index 3d6413ce16..3d6413ce16 100644
--- a/usr/src/compat/freebsd/sys/smp.h
+++ b/usr/src/compat/bhyve/sys/smp.h
diff --git a/usr/src/compat/freebsd/sys/socket.h b/usr/src/compat/bhyve/sys/socket.h
index 3bf7a8f440..3bf7a8f440 100644
--- a/usr/src/compat/freebsd/sys/socket.h
+++ b/usr/src/compat/bhyve/sys/socket.h
diff --git a/usr/src/compat/freebsd/sys/sysctl.h b/usr/src/compat/bhyve/sys/sysctl.h
index 9f6a695e34..9f6a695e34 100644
--- a/usr/src/compat/freebsd/sys/sysctl.h
+++ b/usr/src/compat/bhyve/sys/sysctl.h
diff --git a/usr/src/compat/freebsd/sys/systm.h b/usr/src/compat/bhyve/sys/systm.h
index 43fa16d450..43fa16d450 100644
--- a/usr/src/compat/freebsd/sys/systm.h
+++ b/usr/src/compat/bhyve/sys/systm.h
diff --git a/usr/src/compat/freebsd/sys/time.h b/usr/src/compat/bhyve/sys/time.h
index 4e0fbfc02c..4e0fbfc02c 100644
--- a/usr/src/compat/freebsd/sys/time.h
+++ b/usr/src/compat/bhyve/sys/time.h
diff --git a/usr/src/compat/freebsd/sys/types.h b/usr/src/compat/bhyve/sys/types.h
index 63731da42e..63731da42e 100644
--- a/usr/src/compat/freebsd/sys/types.h
+++ b/usr/src/compat/bhyve/sys/types.h
diff --git a/usr/src/compat/freebsd/sys/uio.h b/usr/src/compat/bhyve/sys/uio.h
index 05c6f2a028..05c6f2a028 100644
--- a/usr/src/compat/freebsd/sys/uio.h
+++ b/usr/src/compat/bhyve/sys/uio.h
diff --git a/usr/src/compat/freebsd/termios.h b/usr/src/compat/bhyve/termios.h
index feaa705358..feaa705358 100644
--- a/usr/src/compat/freebsd/termios.h
+++ b/usr/src/compat/bhyve/termios.h
diff --git a/usr/src/compat/freebsd/unistd.h b/usr/src/compat/bhyve/unistd.h
index b4357e1da5..b4357e1da5 100644
--- a/usr/src/compat/freebsd/unistd.h
+++ b/usr/src/compat/bhyve/unistd.h
diff --git a/usr/src/compat/freebsd/uuid.h b/usr/src/compat/bhyve/uuid.h
index 72ef2c7787..72ef2c7787 100644
--- a/usr/src/compat/freebsd/uuid.h
+++ b/usr/src/compat/bhyve/uuid.h
diff --git a/usr/src/compat/freebsd/vm/vm.h b/usr/src/compat/bhyve/vm/vm.h
index f5bb7b6eb8..f5bb7b6eb8 100644
--- a/usr/src/compat/freebsd/vm/vm.h
+++ b/usr/src/compat/bhyve/vm/vm.h
diff --git a/usr/src/compat/freebsd/vm/vm_param.h b/usr/src/compat/bhyve/vm/vm_param.h
index fd76b62a37..fd76b62a37 100644
--- a/usr/src/compat/freebsd/vm/vm_param.h
+++ b/usr/src/compat/bhyve/vm/vm_param.h
diff --git a/usr/src/compat/freebsd/x86/_types.h b/usr/src/compat/bhyve/x86/_types.h
index 8bbae549d8..8bbae549d8 100644
--- a/usr/src/compat/freebsd/x86/_types.h
+++ b/usr/src/compat/bhyve/x86/_types.h
diff --git a/usr/src/compat/freebsd/x86/segments.h b/usr/src/compat/bhyve/x86/segments.h
index 11edc582b5..11edc582b5 100644
--- a/usr/src/compat/freebsd/x86/segments.h
+++ b/usr/src/compat/bhyve/x86/segments.h
diff --git a/usr/src/contrib/bhyve/README b/usr/src/contrib/bhyve/README
new file mode 100644
index 0000000000..415048d584
--- /dev/null
+++ b/usr/src/contrib/bhyve/README
@@ -0,0 +1,12 @@
+These are headers (and sources) contributed directly from FreeBSD which are
+required to build bhyve. Updates are made to our copies here when corresponding
+updates to bhyve require them.
+
+With few exceptions (noted below) they are verbatim copies taken from the
+FreeBSD source tree. Files requiring extensive modification are likely a
+candidate to exist as a shim in usr/src/compat/bhyve. Conversely, if only a
+tiny modification is needed to make a file suitable for contrib, that trade-off
+is probably worthwhile (if done with a '#ifdef _FreeBSD_' guard for clarity).
+
+Files modified for compatibility:
+- isa/rtc.h
diff --git a/usr/contrib/freebsd/amd64/machine/_types.h b/usr/src/contrib/bhyve/amd64/machine/_types.h
index 59994352b5..59994352b5 100644
--- a/usr/contrib/freebsd/amd64/machine/_types.h
+++ b/usr/src/contrib/bhyve/amd64/machine/_types.h
diff --git a/usr/contrib/freebsd/amd64/machine/pmap.h b/usr/src/contrib/bhyve/amd64/machine/pmap.h
index a0b8ee37f2..a0b8ee37f2 100644
--- a/usr/contrib/freebsd/amd64/machine/pmap.h
+++ b/usr/src/contrib/bhyve/amd64/machine/pmap.h
diff --git a/usr/contrib/freebsd/amd64/machine/psl.h b/usr/src/contrib/bhyve/amd64/machine/psl.h
index c660bfbab0..c660bfbab0 100644
--- a/usr/contrib/freebsd/amd64/machine/psl.h
+++ b/usr/src/contrib/bhyve/amd64/machine/psl.h
diff --git a/usr/contrib/freebsd/amd64/machine/timerreg.h b/usr/src/contrib/bhyve/amd64/machine/timerreg.h
index bca7b4dd19..bca7b4dd19 100644
--- a/usr/contrib/freebsd/amd64/machine/timerreg.h
+++ b/usr/src/contrib/bhyve/amd64/machine/timerreg.h
diff --git a/usr/contrib/freebsd/amd64/machine/vm.h b/usr/src/contrib/bhyve/amd64/machine/vm.h
index 885c1607ea..885c1607ea 100644
--- a/usr/contrib/freebsd/amd64/machine/vm.h
+++ b/usr/src/contrib/bhyve/amd64/machine/vm.h
diff --git a/usr/contrib/freebsd/dev/acpica/acpi_hpet.h b/usr/src/contrib/bhyve/dev/acpica/acpi_hpet.h
index df817b7a2b..df817b7a2b 100644
--- a/usr/contrib/freebsd/dev/acpica/acpi_hpet.h
+++ b/usr/src/contrib/bhyve/dev/acpica/acpi_hpet.h
diff --git a/usr/contrib/freebsd/dev/ic/i8253reg.h b/usr/src/contrib/bhyve/dev/ic/i8253reg.h
index 47568b3436..47568b3436 100644
--- a/usr/contrib/freebsd/dev/ic/i8253reg.h
+++ b/usr/src/contrib/bhyve/dev/ic/i8253reg.h
diff --git a/usr/contrib/freebsd/dev/ic/i8259.h b/usr/src/contrib/bhyve/dev/ic/i8259.h
index be523c1df4..be523c1df4 100644
--- a/usr/contrib/freebsd/dev/ic/i8259.h
+++ b/usr/src/contrib/bhyve/dev/ic/i8259.h
diff --git a/usr/contrib/freebsd/dev/ic/ns16550.h b/usr/src/contrib/bhyve/dev/ic/ns16550.h
index 5e8f30e3e8..5e8f30e3e8 100644
--- a/usr/contrib/freebsd/dev/ic/ns16550.h
+++ b/usr/src/contrib/bhyve/dev/ic/ns16550.h
diff --git a/usr/contrib/freebsd/dev/io/iodev.h b/usr/src/contrib/bhyve/dev/io/iodev.h
index d040fcccf4..d040fcccf4 100644
--- a/usr/contrib/freebsd/dev/io/iodev.h
+++ b/usr/src/contrib/bhyve/dev/io/iodev.h
diff --git a/usr/contrib/freebsd/dev/mii/mii.h b/usr/src/contrib/bhyve/dev/mii/mii.h
index fa1ec84eaa..fa1ec84eaa 100644
--- a/usr/contrib/freebsd/dev/mii/mii.h
+++ b/usr/src/contrib/bhyve/dev/mii/mii.h
diff --git a/usr/contrib/freebsd/dev/nvme/nvme.h b/usr/src/contrib/bhyve/dev/nvme/nvme.h
index c7f6496426..c7f6496426 100644
--- a/usr/contrib/freebsd/dev/nvme/nvme.h
+++ b/usr/src/contrib/bhyve/dev/nvme/nvme.h
diff --git a/usr/contrib/freebsd/dev/pci/pcireg.h b/usr/src/contrib/bhyve/dev/pci/pcireg.h
index 32a569dbd4..32a569dbd4 100644
--- a/usr/contrib/freebsd/dev/pci/pcireg.h
+++ b/usr/src/contrib/bhyve/dev/pci/pcireg.h
diff --git a/usr/contrib/freebsd/dev/usb/controller/xhcireg.h b/usr/src/contrib/bhyve/dev/usb/controller/xhcireg.h
index 0e588ecba3..0e588ecba3 100644
--- a/usr/contrib/freebsd/dev/usb/controller/xhcireg.h
+++ b/usr/src/contrib/bhyve/dev/usb/controller/xhcireg.h
diff --git a/usr/contrib/freebsd/dev/usb/usb.h b/usr/src/contrib/bhyve/dev/usb/usb.h
index bcea2ac8bd..bcea2ac8bd 100644
--- a/usr/contrib/freebsd/dev/usb/usb.h
+++ b/usr/src/contrib/bhyve/dev/usb/usb.h
diff --git a/usr/contrib/freebsd/dev/usb/usb_endian.h b/usr/src/contrib/bhyve/dev/usb/usb_endian.h
index 0bbcb9bf82..0bbcb9bf82 100644
--- a/usr/contrib/freebsd/dev/usb/usb_endian.h
+++ b/usr/src/contrib/bhyve/dev/usb/usb_endian.h
diff --git a/usr/contrib/freebsd/dev/usb/usb_freebsd.h b/usr/src/contrib/bhyve/dev/usb/usb_freebsd.h
index 3bc9d2c1eb..3bc9d2c1eb 100644
--- a/usr/contrib/freebsd/dev/usb/usb_freebsd.h
+++ b/usr/src/contrib/bhyve/dev/usb/usb_freebsd.h
diff --git a/usr/contrib/freebsd/dev/usb/usbdi.h b/usr/src/contrib/bhyve/dev/usb/usbdi.h
index 202ad89fa7..202ad89fa7 100644
--- a/usr/contrib/freebsd/dev/usb/usbdi.h
+++ b/usr/src/contrib/bhyve/dev/usb/usbdi.h
diff --git a/usr/contrib/freebsd/isa/isareg.h b/usr/src/contrib/bhyve/isa/isareg.h
index e83e34674f..e83e34674f 100644
--- a/usr/contrib/freebsd/isa/isareg.h
+++ b/usr/src/contrib/bhyve/isa/isareg.h
diff --git a/usr/contrib/freebsd/isa/rtc.h b/usr/src/contrib/bhyve/isa/rtc.h
index bb964ddf6a..bb964ddf6a 100644
--- a/usr/contrib/freebsd/isa/rtc.h
+++ b/usr/src/contrib/bhyve/isa/rtc.h
diff --git a/usr/contrib/freebsd/lib/libutil/expand_number.c b/usr/src/contrib/bhyve/lib/libutil/expand_number.c
index f3b4da89f9..f3b4da89f9 100644
--- a/usr/contrib/freebsd/lib/libutil/expand_number.c
+++ b/usr/src/contrib/bhyve/lib/libutil/expand_number.c
diff --git a/usr/contrib/freebsd/lib/libutil/humanize_number.c b/usr/src/contrib/bhyve/lib/libutil/humanize_number.c
index 675a969aaa..675a969aaa 100644
--- a/usr/contrib/freebsd/lib/libutil/humanize_number.c
+++ b/usr/src/contrib/bhyve/lib/libutil/humanize_number.c
diff --git a/usr/contrib/freebsd/sys/ata.h b/usr/src/contrib/bhyve/sys/ata.h
index 223bd7b3eb..223bd7b3eb 100644
--- a/usr/contrib/freebsd/sys/ata.h
+++ b/usr/src/contrib/bhyve/sys/ata.h
diff --git a/usr/contrib/freebsd/sys/pciio.h b/usr/src/contrib/bhyve/sys/pciio.h
index d70bfbcf6f..d70bfbcf6f 100644
--- a/usr/contrib/freebsd/sys/pciio.h
+++ b/usr/src/contrib/bhyve/sys/pciio.h
diff --git a/usr/contrib/freebsd/sys/queue.h b/usr/src/contrib/bhyve/sys/queue.h
index f26c492af1..f26c492af1 100644
--- a/usr/contrib/freebsd/sys/queue.h
+++ b/usr/src/contrib/bhyve/sys/queue.h
diff --git a/usr/contrib/freebsd/sys/tree.h b/usr/src/contrib/bhyve/sys/tree.h
index 6b47e247bb..6b47e247bb 100644
--- a/usr/contrib/freebsd/sys/tree.h
+++ b/usr/src/contrib/bhyve/sys/tree.h
diff --git a/usr/contrib/freebsd/x86/apicreg.h b/usr/src/contrib/bhyve/x86/apicreg.h
index 24006e2733..24006e2733 100644
--- a/usr/contrib/freebsd/x86/apicreg.h
+++ b/usr/src/contrib/bhyve/x86/apicreg.h
diff --git a/usr/contrib/freebsd/x86/mptable.h b/usr/src/contrib/bhyve/x86/mptable.h
index 8f3c62a295..8f3c62a295 100644
--- a/usr/contrib/freebsd/x86/mptable.h
+++ b/usr/src/contrib/bhyve/x86/mptable.h
diff --git a/usr/contrib/freebsd/x86/psl.h b/usr/src/contrib/bhyve/x86/psl.h
index 6934b4feb7..6934b4feb7 100644
--- a/usr/contrib/freebsd/x86/psl.h
+++ b/usr/src/contrib/bhyve/x86/psl.h
diff --git a/usr/contrib/freebsd/x86/segments.h b/usr/src/contrib/bhyve/x86/segments.h
index 1b8c4a3c1c..1b8c4a3c1c 100644
--- a/usr/contrib/freebsd/x86/segments.h
+++ b/usr/src/contrib/bhyve/x86/segments.h
diff --git a/usr/contrib/freebsd/x86/specialreg.h b/usr/src/contrib/bhyve/x86/specialreg.h
index f528bad55c..f528bad55c 100644
--- a/usr/contrib/freebsd/x86/specialreg.h
+++ b/usr/src/contrib/bhyve/x86/specialreg.h
diff --git a/usr/src/lib/libvmm/Makefile.com b/usr/src/lib/libvmm/Makefile.com
index bef555aed3..ab0e7bd2b8 100644
--- a/usr/src/lib/libvmm/Makefile.com
+++ b/usr/src/lib/libvmm/Makefile.com
@@ -27,8 +27,8 @@ LIBS = $(DYNLIB)
# The FreeBSD compat and contrib headers need to be first in the search
# path, hence we can't just append them to CPPFLAGS. So we assign CPPFLAGS
# directly and pull in CPPFLAGS.master at the appropriate place.
-CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \
- -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64 \
+CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \
+ -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64 \
$(CPPFLAGS.master) -I$(SRC)/uts/i86pc
LDLIBS += -lc -lvmmapi
diff --git a/usr/src/lib/libvmmapi/Makefile.com b/usr/src/lib/libvmmapi/Makefile.com
index 1653e8619c..4c1c74d5a0 100644
--- a/usr/src/lib/libvmmapi/Makefile.com
+++ b/usr/src/lib/libvmmapi/Makefile.com
@@ -29,7 +29,7 @@ SRCDIR = ../common
LIBS = $(DYNLIB)
-CPPFLAGS = -I$(COMPAT)/freebsd -I$(CONTRIB)/freebsd \
+CPPFLAGS = -I$(COMPAT)/bhyve -I$(CONTRIB)/bhyve \
$(CPPFLAGS.master) -I$(SRC)/uts/i86pc
# not linted
@@ -41,7 +41,7 @@ LDLIBS += -lc
all: $(LIBS)
-pics/%.o: $(CONTRIB)/freebsd/lib/libutil/%.c
+pics/%.o: $(CONTRIB)/bhyve/lib/libutil/%.c
$(COMPILE.c) -o $@ $<
$(POST_PROCESS_O)
diff --git a/usr/src/lib/libvmmapi/amd64/Makefile b/usr/src/lib/libvmmapi/amd64/Makefile
index b5cac1ffce..d777b9d456 100644
--- a/usr/src/lib/libvmmapi/amd64/Makefile
+++ b/usr/src/lib/libvmmapi/amd64/Makefile
@@ -16,6 +16,6 @@
include ../Makefile.com
include ../../Makefile.lib.64
-CPPFLAGS += -I$(COMPAT)/freebsd/amd64 -I$(CONTRIB)/freebsd/amd64
+CPPFLAGS += -I$(COMPAT)/bhyve/amd64 -I$(CONTRIB)/bhyve/amd64
install: all $(ROOTLIBS64) $(ROOTLINKS64) $(ROOTLINT64)
diff --git a/usr/src/pkg/manifests/system-file-system-zfs-tests.mf b/usr/src/pkg/manifests/system-file-system-zfs-tests.mf
index 4e2b5f1add..d39248a2e4 100644
--- a/usr/src/pkg/manifests/system-file-system-zfs-tests.mf
+++ b/usr/src/pkg/manifests/system-file-system-zfs-tests.mf
@@ -22,6 +22,7 @@
#
# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+# Copyright 2020 Joyent, Inc.
#
set name=pkg.fmri value=pkg:/system/file-system/zfs/tests@$(PKGVERS)
@@ -53,6 +54,7 @@ $(i386_ONLY)file path=usr/bin/$(ARCH32)/zlook mode=0555
$(i386_ONLY)file path=usr/bin/$(ARCH32)/ztest mode=0555
file path=usr/bin/$(ARCH64)/zlook mode=0555
file path=usr/bin/$(ARCH64)/ztest mode=0555
+file path=usr/bin/raidz_test mode=0555
file path=usr/bin/zloop mode=0555
file path=usr/include/sys/fs/zut.h
file path=usr/lib/devfsadm/linkmod/SUNW_zut_link.so group=sys
diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf
index 3b4bcc373e..0f05230a9b 100644
--- a/usr/src/pkg/manifests/system-test-zfstest.mf
+++ b/usr/src/pkg/manifests/system-test-zfstest.mf
@@ -143,6 +143,7 @@ dir path=opt/zfs-tests/tests/functional/poolversion
dir path=opt/zfs-tests/tests/functional/privilege
dir path=opt/zfs-tests/tests/functional/projectquota
dir path=opt/zfs-tests/tests/functional/quota
+dir path=opt/zfs-tests/tests/functional/raidz
dir path=opt/zfs-tests/tests/functional/redundancy
dir path=opt/zfs-tests/tests/functional/refquota
dir path=opt/zfs-tests/tests/functional/refreserv
@@ -2800,6 +2801,10 @@ file path=opt/zfs-tests/tests/functional/quota/quota_004_pos mode=0555
file path=opt/zfs-tests/tests/functional/quota/quota_005_pos mode=0555
file path=opt/zfs-tests/tests/functional/quota/quota_006_neg mode=0555
file path=opt/zfs-tests/tests/functional/quota/setup mode=0555
+file path=opt/zfs-tests/tests/functional/raidz/cleanup mode=0555
+file path=opt/zfs-tests/tests/functional/raidz/raidz_001_neg mode=0555
+file path=opt/zfs-tests/tests/functional/raidz/raidz_002_pos mode=0555
+file path=opt/zfs-tests/tests/functional/raidz/setup mode=0555
file path=opt/zfs-tests/tests/functional/redundancy/cleanup mode=0555
file path=opt/zfs-tests/tests/functional/redundancy/redundancy.cfg mode=0444
file path=opt/zfs-tests/tests/functional/redundancy/redundancy.kshlib \
diff --git a/usr/src/req.flg b/usr/src/req.flg
index aaf37ddd97..f1e17bbd52 100644
--- a/usr/src/req.flg
+++ b/usr/src/req.flg
@@ -34,5 +34,3 @@ echo_file usr/src/Makefile.master.64
echo_file usr/src/Makefile.msg.targ
echo_file usr/src/Makefile.psm
echo_file usr/src/Makefile.psm.targ
-
-find_files "s.*" usr/contrib/freebsd
diff --git a/usr/src/test/zfs-tests/include/commands.cfg b/usr/src/test/zfs-tests/include/commands.cfg
index 050d6caba7..f9b0bdf7ac 100644
--- a/usr/src/test/zfs-tests/include/commands.cfg
+++ b/usr/src/test/zfs-tests/include/commands.cfg
@@ -11,7 +11,7 @@
#
# Copyright (c) 2016, 2018 by Delphix. All rights reserved.
-# Copyright 2019 Joyent, Inc.
+# Copyright 2020 Joyent, Inc.
#
#
@@ -89,6 +89,7 @@ export USR_BIN_FILES='awk
ps
pwd
python
+ raidz_test
readlink
rm
rmdir
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index f7dc35928e..656e274985 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -582,6 +582,9 @@ tests = ['projectid_001_pos', 'projectid_002_pos', 'projectid_003_pos',
tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', 'quota_004_pos',
'quota_005_pos', 'quota_006_neg']
+[/opt/zfs-tests/tests/functional/raidz]
+tests = ['raidz_001_neg', 'raidz_002_pos']
+
[/opt/zfs-tests/tests/functional/redundancy]
tests = ['redundancy_001_pos', 'redundancy_002_pos', 'redundancy_003_pos',
'redundancy_004_neg']
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index 4dbfde3fb0..54848ba403 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -582,6 +582,9 @@ tests = ['projectid_001_pos', 'projectid_002_pos', 'projectid_003_pos',
tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', 'quota_004_pos',
'quota_005_pos', 'quota_006_neg']
+[/opt/zfs-tests/tests/functional/raidz]
+tests = ['raidz_001_neg', 'raidz_002_pos']
+
[/opt/zfs-tests/tests/functional/redundancy]
tests = ['redundancy_001_pos', 'redundancy_002_pos', 'redundancy_003_pos',
'redundancy_004_neg']
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index 21473782c2..6ae3857a0a 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -582,6 +582,9 @@ tests = ['projectid_001_pos', 'projectid_002_pos', 'projectid_003_pos',
tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', 'quota_004_pos',
'quota_005_pos', 'quota_006_neg']
+[/opt/zfs-tests/tests/functional/raidz]
+tests = ['raidz_001_neg', 'raidz_002_pos']
+
[/opt/zfs-tests/tests/functional/redundancy]
tests = ['redundancy_001_pos', 'redundancy_002_pos', 'redundancy_003_pos',
'redundancy_004_neg']
diff --git a/usr/src/test/zfs-tests/runfiles/smartos.run b/usr/src/test/zfs-tests/runfiles/smartos.run
index c8d6dc4783..47059b0b52 100644
--- a/usr/src/test/zfs-tests/runfiles/smartos.run
+++ b/usr/src/test/zfs-tests/runfiles/smartos.run
@@ -510,6 +510,9 @@ tests = ['projectid_001_pos', 'projectid_002_pos', 'projectid_003_pos',
tests = ['quota_001_pos', 'quota_002_pos', 'quota_003_pos', 'quota_004_pos',
'quota_005_pos', 'quota_006_neg']
+[/opt/zfs-tests/tests/functional/raidz]
+tests = ['raidz_001_neg', 'raidz_002_pos']
+
[/opt/zfs-tests/tests/functional/refquota]
tests = ['refquota_001_pos', 'refquota_002_pos', 'refquota_003_pos',
'refquota_004_pos', 'refquota_005_pos', 'refquota_006_neg']
diff --git a/usr/src/test/zfs-tests/tests/functional/raidz/Makefile b/usr/src/test/zfs-tests/tests/functional/raidz/Makefile
new file mode 100644
index 0000000000..5d0bf4506a
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/raidz/Makefile
@@ -0,0 +1,21 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2020 Joyent, Inc.
+#
+
+include $(SRC)/Makefile.master
+
+ROOTOPTPKG = $(ROOT)/opt/zfs-tests
+TARGETDIR = $(ROOTOPTPKG)/tests/functional/raidz
+
+include $(SRC)/test/zfs-tests/Makefile.com
diff --git a/usr/src/test/zfs-tests/tests/functional/raidz/cleanup.ksh b/usr/src/test/zfs-tests/tests/functional/raidz/cleanup.ksh
new file mode 100755
index 0000000000..c92c54c270
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/raidz/cleanup.ksh
@@ -0,0 +1,30 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016 by Gvozden Neskovic. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+# default_cleanup
diff --git a/usr/src/test/zfs-tests/tests/functional/raidz/raidz_001_neg.ksh b/usr/src/test/zfs-tests/tests/functional/raidz/raidz_001_neg.ksh
new file mode 100755
index 0000000000..4c105b9411
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/raidz/raidz_001_neg.ksh
@@ -0,0 +1,38 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016 by Gvozden Neskovic. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Call the raidz_test tool with -T options to test the infrastructure.
+# This option should make raidz_test to return non 0.
+#
+
+log_mustnot raidz_test -T
+
+log_pass "raidz_test detects errors as espected."
diff --git a/usr/src/test/zfs-tests/tests/functional/raidz/raidz_002_pos.ksh b/usr/src/test/zfs-tests/tests/functional/raidz/raidz_002_pos.ksh
new file mode 100755
index 0000000000..e238a881b0
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/raidz/raidz_002_pos.ksh
@@ -0,0 +1,41 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016 by Gvozden Neskovic. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+#
+# DESCRIPTION:
+# Call the raidz_test tool with -S to test all supported raidz
+# implementations. This options will test several raidz block geometries
+# and several zio parameters that affect raidz block layout. Data
+# reconstruction performs all combinations of failed disks. Wall time
+# is set to 5min, but actual runtime might be longer.
+#
+
+log_must raidz_test -S -t 300
+
+log_pass "raidz_test parameter sweep test succeeded."
diff --git a/usr/src/test/zfs-tests/tests/functional/raidz/setup.ksh b/usr/src/test/zfs-tests/tests/functional/raidz/setup.ksh
new file mode 100755
index 0000000000..4e155d24d5
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/raidz/setup.ksh
@@ -0,0 +1,32 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2016 by Gvozden Neskovic. All rights reserved.
+# Use is subject to license terms.
+#
+
+. $STF_SUITE/include/libtest.shlib
+
+verify_runnable "global"
+
+log_pass
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 720701371d..ff108e47e5 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -1434,6 +1434,8 @@ ZFS_COMMON_OBJS += \
vdev_missing.o \
vdev_queue.o \
vdev_raidz.o \
+ vdev_raidz_math.o \
+ vdev_raidz_math_scalar.o \
vdev_removal.o \
vdev_root.o \
vdev_trim.o \
diff --git a/usr/src/uts/common/fs/zfs/abd.c b/usr/src/uts/common/fs/zfs/abd.c
index 66a7a49d73..e980c82eee 100644
--- a/usr/src/uts/common/fs/zfs/abd.c
+++ b/usr/src/uts/common/fs/zfs/abd.c
@@ -12,6 +12,7 @@
/*
* Copyright (c) 2014 by Chunwei Chen. All rights reserved.
* Copyright (c) 2019 by Delphix. All rights reserved.
+ * Copyright 2020 Joyent, Inc.
*/
/*
@@ -764,7 +765,8 @@ abd_iter_map(struct abd_iter *aiter)
} else {
size_t index = abd_iter_scatter_chunk_index(aiter);
offset = abd_iter_scatter_chunk_offset(aiter);
- aiter->iter_mapsize = zfs_abd_chunk_size - offset;
+ aiter->iter_mapsize = MIN(zfs_abd_chunk_size - offset,
+ aiter->iter_abd->abd_size - aiter->iter_pos);
paddr = aiter->iter_abd->abd_u.abd_scatter.abd_chunks[index];
}
aiter->iter_mapaddr = (char *)paddr + offset;
@@ -993,3 +995,180 @@ abd_cmp(abd_t *dabd, abd_t *sabd, size_t size)
{
return (abd_iterate_func2(dabd, sabd, 0, 0, size, abd_cmp_cb, NULL));
}
+
+/*
+ * Iterate over code ABDs and a data ABD and call @func_raidz_gen.
+ *
+ * @cabds parity ABDs, must have equal size
+ * @dabd data ABD. Can be NULL (in this case @dsize = 0)
+ * @func_raidz_gen should be implemented so that its behaviour
+ * is the same when taking linear and when taking scatter
+ */
+void
+abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
+ ssize_t csize, ssize_t dsize, const unsigned parity,
+ void (*func_raidz_gen)(void **, const void *, size_t, size_t))
+{
+ int i;
+ ssize_t len, dlen;
+ struct abd_iter caiters[3];
+ struct abd_iter daiter = {0};
+ void *caddrs[3];
+
+ ASSERT3U(parity, <=, 3);
+
+ for (i = 0; i < parity; i++)
+ abd_iter_init(&caiters[i], cabds[i]);
+
+ if (dabd)
+ abd_iter_init(&daiter, dabd);
+
+ ASSERT3S(dsize, >=, 0);
+
+#ifdef _KERNEL
+ kpreempt_disable();
+#endif
+ while (csize > 0) {
+ len = csize;
+
+ if (dabd && dsize > 0)
+ abd_iter_map(&daiter);
+
+ for (i = 0; i < parity; i++) {
+ abd_iter_map(&caiters[i]);
+ caddrs[i] = caiters[i].iter_mapaddr;
+ }
+
+ switch (parity) {
+ case 3:
+ len = MIN(caiters[2].iter_mapsize, len);
+ /* falls through */
+ case 2:
+ len = MIN(caiters[1].iter_mapsize, len);
+ /* falls through */
+ case 1:
+ len = MIN(caiters[0].iter_mapsize, len);
+ }
+
+ /* must be progressive */
+ ASSERT3S(len, >, 0);
+
+ if (dabd && dsize > 0) {
+ /* this needs precise iter.length */
+ len = MIN(daiter.iter_mapsize, len);
+ len = MIN(dsize, len);
+ dlen = len;
+ } else
+ dlen = 0;
+
+ /* must be progressive */
+ ASSERT3S(len, >, 0);
+ /*
+ * The iterated function likely will not do well if each
+ * segment except the last one is not multiple of 512 (raidz).
+ */
+ ASSERT3U(((uint64_t)len & 511ULL), ==, 0);
+
+ func_raidz_gen(caddrs, daiter.iter_mapaddr, len, dlen);
+
+ for (i = parity-1; i >= 0; i--) {
+ abd_iter_unmap(&caiters[i]);
+ abd_iter_advance(&caiters[i], len);
+ }
+
+ if (dabd && dsize > 0) {
+ abd_iter_unmap(&daiter);
+ abd_iter_advance(&daiter, dlen);
+ dsize -= dlen;
+ }
+
+ csize -= len;
+
+ ASSERT3S(dsize, >=, 0);
+ ASSERT3S(csize, >=, 0);
+ }
+#ifdef _KERNEL
+ kpreempt_enable();
+#endif
+}
+
+/*
+ * Iterate over code ABDs and data reconstruction target ABDs and call
+ * @func_raidz_rec. Function maps at most 6 pages atomically.
+ *
+ * @cabds parity ABDs, must have equal size
+ * @tabds rec target ABDs, at most 3
+ * @tsize size of data target columns
+ * @func_raidz_rec expects syndrome data in target columns. Function
+ * reconstructs data and overwrites target columns.
+ */
+void
+abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
+ ssize_t tsize, const unsigned parity,
+ void (*func_raidz_rec)(void **t, const size_t tsize, void **c,
+ const unsigned *mul),
+ const unsigned *mul)
+{
+ int i;
+ ssize_t len;
+ struct abd_iter citers[3];
+ struct abd_iter xiters[3];
+ void *caddrs[3], *xaddrs[3];
+
+ ASSERT3U(parity, <=, 3);
+
+ for (i = 0; i < parity; i++) {
+ abd_iter_init(&citers[i], cabds[i]);
+ abd_iter_init(&xiters[i], tabds[i]);
+ }
+
+#ifdef _KERNEL
+ kpreempt_disable();
+#endif
+ while (tsize > 0) {
+
+ for (i = 0; i < parity; i++) {
+ abd_iter_map(&citers[i]);
+ abd_iter_map(&xiters[i]);
+ caddrs[i] = citers[i].iter_mapaddr;
+ xaddrs[i] = xiters[i].iter_mapaddr;
+ }
+
+ len = tsize;
+ switch (parity) {
+ case 3:
+ len = MIN(xiters[2].iter_mapsize, len);
+ len = MIN(citers[2].iter_mapsize, len);
+ /* falls through */
+ case 2:
+ len = MIN(xiters[1].iter_mapsize, len);
+ len = MIN(citers[1].iter_mapsize, len);
+ /* falls through */
+ case 1:
+ len = MIN(xiters[0].iter_mapsize, len);
+ len = MIN(citers[0].iter_mapsize, len);
+ }
+ /* must be progressive */
+ ASSERT3S(len, >, 0);
+ /*
+ * The iterated function likely will not do well if each
+ * segment except the last one is not multiple of 512 (raidz).
+ */
+ ASSERT3U(((uint64_t)len & 511ULL), ==, 0);
+
+ func_raidz_rec(xaddrs, len, caddrs, mul);
+
+ for (i = parity-1; i >= 0; i--) {
+ abd_iter_unmap(&xiters[i]);
+ abd_iter_unmap(&citers[i]);
+ abd_iter_advance(&xiters[i], len);
+ abd_iter_advance(&citers[i], len);
+ }
+
+ tsize -= len;
+ ASSERT3S(tsize, >=, 0);
+ }
+#ifdef _KERNEL
+ kpreempt_enable();
+#endif
+}
diff --git a/usr/src/uts/common/fs/zfs/spa_misc.c b/usr/src/uts/common/fs/zfs/spa_misc.c
index 9dac4e2ddc..c9ceeb6873 100644
--- a/usr/src/uts/common/fs/zfs/spa_misc.c
+++ b/usr/src/uts/common/fs/zfs/spa_misc.c
@@ -44,6 +44,7 @@
#include <sys/vdev_impl.h>
#include <sys/vdev_initialize.h>
#include <sys/vdev_trim.h>
+#include <sys/vdev_raidz.h>
#include <sys/metaslab.h>
#include <sys/uberblock_impl.h>
#include <sys/txg.h>
@@ -2253,6 +2254,7 @@ spa_init(int mode)
zil_init();
vdev_cache_stat_init();
vdev_mirror_stat_init();
+ vdev_raidz_math_init();
zfs_prop_init();
zpool_prop_init();
zpool_feature_init();
@@ -2271,6 +2273,7 @@ spa_fini(void)
vdev_cache_stat_fini();
vdev_mirror_stat_fini();
+ vdev_raidz_math_fini();
zil_fini();
dmu_fini();
zio_fini();
diff --git a/usr/src/uts/common/fs/zfs/sys/abd.h b/usr/src/uts/common/fs/zfs/sys/abd.h
index 621635933e..23699c0420 100644
--- a/usr/src/uts/common/fs/zfs/sys/abd.h
+++ b/usr/src/uts/common/fs/zfs/sys/abd.h
@@ -103,6 +103,15 @@ int abd_cmp(abd_t *, abd_t *, size_t);
int abd_cmp_buf_off(abd_t *, const void *, size_t, size_t);
void abd_zero_off(abd_t *, size_t, size_t);
+void abd_raidz_gen_iterate(abd_t **cabds, abd_t *dabd,
+ ssize_t csize, ssize_t dsize, const unsigned parity,
+ void (*func_raidz_gen)(void **, const void *, size_t, size_t));
+void abd_raidz_rec_iterate(abd_t **cabds, abd_t **tabds,
+ ssize_t tsize, const unsigned parity,
+ void (*func_raidz_rec)(void **t, const size_t tsize, void **c,
+ const unsigned *mul),
+ const unsigned *mul);
+
/*
* Wrappers for calls with offsets of 0
*/
diff --git a/usr/src/uts/common/fs/zfs/sys/simd.h b/usr/src/uts/common/fs/zfs/sys/simd.h
new file mode 100644
index 0000000000..4494c7d02a
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/sys/simd.h
@@ -0,0 +1,40 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2020 Joyent, Inc.
+ */
+
+#ifndef _SIMD_H
+#define _SIMD_H
+
+#if defined(__amd64__) || defined(__i386__)
+
+/* Temporararily disabled until subsequent work to turn this on. */
+#define kfpu_allowed() 0
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+#define kfpu_init() (0)
+#define kfpu_fini() do {} while (0)
+
+#else
+
+/* Non-x86 CPUs currently always disallow kernel FPU support */
+#define kfpu_allowed() 0
+#define kfpu_initialize(tsk) do {} while (0)
+#define kfpu_begin() do {} while (0)
+#define kfpu_end() do {} while (0)
+#define kfpu_init() (0)
+#define kfpu_fini() do {} while (0)
+#endif
+
+#endif /* _SIMD_H */
diff --git a/usr/src/uts/common/fs/zfs/sys/vdev_raidz.h b/usr/src/uts/common/fs/zfs/sys/vdev_raidz.h
new file mode 100644
index 0000000000..bf5c840139
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/sys/vdev_raidz.h
@@ -0,0 +1,65 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2016 Gvozden Neskovic <neskovic@compeng.uni-frankfurt.de>.
+ * Copyright 2020 Joyent, Inc.
+ */
+
+#ifndef _SYS_VDEV_RAIDZ_H
+#define _SYS_VDEV_RAIDZ_H
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct zio;
+struct raidz_map;
+#if !defined(_KERNEL)
+struct kernel_param {};
+#endif
+
+/*
+ * vdev_raidz interface
+ */
+struct raidz_map * vdev_raidz_map_alloc(struct zio *, uint64_t,
+ uint64_t, uint64_t);
+void vdev_raidz_map_free(struct raidz_map *);
+void vdev_raidz_generate_parity(struct raidz_map *);
+int vdev_raidz_reconstruct(struct raidz_map *, const int *, int);
+
+/*
+ * vdev_raidz_math interface
+ */
+void vdev_raidz_math_init(void);
+void vdev_raidz_math_fini(void);
+const struct raidz_impl_ops *vdev_raidz_math_get_ops(void);
+int vdev_raidz_math_generate(struct raidz_map *);
+int vdev_raidz_math_reconstruct(struct raidz_map *, const int *,
+ const int *, const int);
+int vdev_raidz_impl_set(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SYS_VDEV_RAIDZ_H */
diff --git a/usr/src/uts/common/fs/zfs/sys/vdev_raidz_impl.h b/usr/src/uts/common/fs/zfs/sys/vdev_raidz_impl.h
new file mode 100644
index 0000000000..d8defc04ea
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/sys/vdev_raidz_impl.h
@@ -0,0 +1,351 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ */
+
+#ifndef _VDEV_RAIDZ_H
+#define _VDEV_RAIDZ_H
+
+#include <sys/types.h>
+#include <sys/debug.h>
+#include <sys/kstat.h>
+#include <sys/abd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CODE_P (0U)
+#define CODE_Q (1U)
+#define CODE_R (2U)
+
+#define PARITY_P (1U)
+#define PARITY_PQ (2U)
+#define PARITY_PQR (3U)
+
+#define TARGET_X (0U)
+#define TARGET_Y (1U)
+#define TARGET_Z (2U)
+
+/*
+ * Parity generation methods indexes
+ */
+enum raidz_math_gen_op {
+ RAIDZ_GEN_P = 0,
+ RAIDZ_GEN_PQ,
+ RAIDZ_GEN_PQR,
+ RAIDZ_GEN_NUM = 3
+};
+/*
+ * Data reconstruction methods indexes
+ */
+enum raidz_rec_op {
+ RAIDZ_REC_P = 0,
+ RAIDZ_REC_Q,
+ RAIDZ_REC_R,
+ RAIDZ_REC_PQ,
+ RAIDZ_REC_PR,
+ RAIDZ_REC_QR,
+ RAIDZ_REC_PQR,
+ RAIDZ_REC_NUM = 7
+};
+
+extern const char *raidz_gen_name[RAIDZ_GEN_NUM];
+extern const char *raidz_rec_name[RAIDZ_REC_NUM];
+
+/*
+ * Methods used to define raidz implementation
+ *
+ * @raidz_gen_f Parity generation function
+ * @par1 pointer to raidz_map
+ * @raidz_rec_f Data reconstruction function
+ * @par1 pointer to raidz_map
+ * @par2 array of reconstruction targets
+ * @will_work_f Function returns TRUE if impl. is supported on the system
+ * @init_impl_f Function is called once on init
+ * @fini_impl_f Function is called once on fini
+ */
+typedef void (*raidz_gen_f)(void *);
+typedef int (*raidz_rec_f)(void *, const int *);
+typedef boolean_t (*will_work_f)(void);
+typedef void (*init_impl_f)(void);
+typedef void (*fini_impl_f)(void);
+
+#define RAIDZ_IMPL_NAME_MAX (20)
+
+typedef struct raidz_impl_ops {
+ init_impl_f init;
+ fini_impl_f fini;
+ raidz_gen_f gen[RAIDZ_GEN_NUM]; /* Parity generate functions */
+ raidz_rec_f rec[RAIDZ_REC_NUM]; /* Data reconstruction functions */
+ will_work_f is_supported; /* Support check function */
+ char name[RAIDZ_IMPL_NAME_MAX]; /* Name of the implementation */
+} raidz_impl_ops_t;
+
+typedef struct raidz_col {
+ size_t rc_devidx; /* child device index for I/O */
+ size_t rc_offset; /* device offset */
+ size_t rc_size; /* I/O size */
+ abd_t *rc_abd; /* I/O data */
+ void *rc_gdata; /* used to store the "good" version */
+ int rc_error; /* I/O error for this device */
+ unsigned int rc_tried; /* Did we attempt this I/O column? */
+ unsigned int rc_skipped; /* Did we skip this I/O column? */
+} raidz_col_t;
+
+typedef struct raidz_map {
+ size_t rm_cols; /* Regular column count */
+ size_t rm_scols; /* Count including skipped columns */
+ size_t rm_bigcols; /* Number of oversized columns */
+ size_t rm_asize; /* Actual total I/O size */
+ size_t rm_missingdata; /* Count of missing data devices */
+ size_t rm_missingparity; /* Count of missing parity devices */
+ size_t rm_firstdatacol; /* First data column/parity count */
+ size_t rm_nskip; /* Skipped sectors for padding */
+ size_t rm_skipstart; /* Column index of padding start */
+ void *rm_abd_copy; /* rm_asize-buffer of copied data */
+ size_t rm_reports; /* # of referencing checksum reports */
+ unsigned int rm_freed; /* map no longer has referencing ZIO */
+ unsigned int rm_ecksuminjected; /* checksum error was injected */
+ const raidz_impl_ops_t *rm_ops; /* RAIDZ math operations */
+ raidz_col_t rm_col[1]; /* Flexible array of I/O columns */
+} raidz_map_t;
+
+#define RAIDZ_ORIGINAL_IMPL (INT_MAX)
+
+extern const raidz_impl_ops_t vdev_raidz_scalar_impl;
+
+/*
+ * Commonly used raidz_map helpers
+ *
+ * raidz_parity Returns parity of the RAIDZ block
+ * raidz_ncols Returns number of columns the block spans
+ * raidz_nbigcols Returns number of big columns columns
+ * raidz_col_p Returns pointer to a column
+ * raidz_col_size Returns size of a column
+ * raidz_big_size Returns size of big columns
+ * raidz_short_size Returns size of short columns
+ */
+#define raidz_parity(rm) ((rm)->rm_firstdatacol)
+#define raidz_ncols(rm) ((rm)->rm_cols)
+#define raidz_nbigcols(rm) ((rm)->rm_bigcols)
+#define raidz_col_p(rm, c) ((rm)->rm_col + (c))
+#define raidz_col_size(rm, c) ((rm)->rm_col[c].rc_size)
+#define raidz_big_size(rm) (raidz_col_size(rm, CODE_P))
+#define raidz_short_size(rm) (raidz_col_size(rm, raidz_ncols(rm)-1))
+
+/*
+ * Macro defines an RAIDZ parity generation method
+ *
+ * @code parity the function produce
+ * @impl name of the implementation
+ */
+#define _RAIDZ_GEN_WRAP(code, impl) \
+static void \
+impl ## _gen_ ## code(void *rmp) \
+{ \
+ raidz_map_t *rm = (raidz_map_t *) rmp; \
+ raidz_generate_## code ## _impl(rm); \
+}
+
+/*
+ * Macro defines an RAIDZ data reconstruction method
+ *
+ * @code parity the function produce
+ * @impl name of the implementation
+ */
+#define _RAIDZ_REC_WRAP(code, impl) \
+static int \
+impl ## _rec_ ## code(void *rmp, const int *tgtidx) \
+{ \
+ raidz_map_t *rm = (raidz_map_t *) rmp; \
+ return (raidz_reconstruct_## code ## _impl(rm, tgtidx)); \
+}
+
+/*
+ * Define all gen methods for an implementation
+ *
+ * @impl name of the implementation
+ */
+#define DEFINE_GEN_METHODS(impl) \
+ _RAIDZ_GEN_WRAP(p, impl); \
+ _RAIDZ_GEN_WRAP(pq, impl); \
+ _RAIDZ_GEN_WRAP(pqr, impl)
+
+/*
+ * Define all rec functions for an implementation
+ *
+ * @impl name of the implementation
+ */
+#define DEFINE_REC_METHODS(impl) \
+ _RAIDZ_REC_WRAP(p, impl); \
+ _RAIDZ_REC_WRAP(q, impl); \
+ _RAIDZ_REC_WRAP(r, impl); \
+ _RAIDZ_REC_WRAP(pq, impl); \
+ _RAIDZ_REC_WRAP(pr, impl); \
+ _RAIDZ_REC_WRAP(qr, impl); \
+ _RAIDZ_REC_WRAP(pqr, impl)
+
+#define RAIDZ_GEN_METHODS(impl) \
+{ \
+ [RAIDZ_GEN_P] = & impl ## _gen_p, \
+ [RAIDZ_GEN_PQ] = & impl ## _gen_pq, \
+ [RAIDZ_GEN_PQR] = & impl ## _gen_pqr \
+}
+
+#define RAIDZ_REC_METHODS(impl) \
+{ \
+ [RAIDZ_REC_P] = & impl ## _rec_p, \
+ [RAIDZ_REC_Q] = & impl ## _rec_q, \
+ [RAIDZ_REC_R] = & impl ## _rec_r, \
+ [RAIDZ_REC_PQ] = & impl ## _rec_pq, \
+ [RAIDZ_REC_PR] = & impl ## _rec_pr, \
+ [RAIDZ_REC_QR] = & impl ## _rec_qr, \
+ [RAIDZ_REC_PQR] = & impl ## _rec_pqr \
+}
+
+
+typedef struct raidz_impl_kstat {
+ uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed kiB/s */
+ uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed kiB/s */
+} raidz_impl_kstat_t;
+
+/*
+ * Enumerate various multiplication constants
+ * used in reconstruction methods
+ */
+typedef enum raidz_mul_info {
+ /* Reconstruct Q */
+ MUL_Q_X = 0,
+ /* Reconstruct R */
+ MUL_R_X = 0,
+ /* Reconstruct PQ */
+ MUL_PQ_X = 0,
+ MUL_PQ_Y = 1,
+ /* Reconstruct PR */
+ MUL_PR_X = 0,
+ MUL_PR_Y = 1,
+ /* Reconstruct QR */
+ MUL_QR_XQ = 0,
+ MUL_QR_X = 1,
+ MUL_QR_YQ = 2,
+ MUL_QR_Y = 3,
+ /* Reconstruct PQR */
+ MUL_PQR_XP = 0,
+ MUL_PQR_XQ = 1,
+ MUL_PQR_XR = 2,
+ MUL_PQR_YU = 3,
+ MUL_PQR_YP = 4,
+ MUL_PQR_YQ = 5,
+
+ MUL_CNT = 6
+} raidz_mul_info_t;
+
+/*
+ * Powers of 2 in the Galois field.
+ */
+extern const uint8_t vdev_raidz_pow2[256] __attribute__((aligned(256)));
+/* Logs of 2 in the Galois field defined above. */
+extern const uint8_t vdev_raidz_log2[256] __attribute__((aligned(256)));
+
+/*
+ * Multiply a given number by 2 raised to the given power.
+ */
+static inline uint8_t
+vdev_raidz_exp2(const uint8_t a, const unsigned exp)
+{
+ if (a == 0)
+ return (0);
+
+ return (vdev_raidz_pow2[(exp + (unsigned) vdev_raidz_log2[a]) % 255]);
+}
+
+/*
+ * Galois Field operations.
+ *
+ * gf_exp2 - computes 2 raised to the given power
+ * gf_exp2 - computes 4 raised to the given power
+ * gf_mul - multiplication
+ * gf_div - division
+ * gf_inv - multiplicative inverse
+ */
+typedef unsigned gf_t;
+typedef unsigned gf_log_t;
+
+static inline gf_t
+gf_mul(const gf_t a, const gf_t b)
+{
+ gf_log_t logsum;
+
+ if (a == 0 || b == 0)
+ return (0);
+
+ logsum = (gf_log_t) vdev_raidz_log2[a] + (gf_log_t) vdev_raidz_log2[b];
+
+ return ((gf_t) vdev_raidz_pow2[logsum % 255]);
+}
+
+static inline gf_t
+gf_div(const gf_t a, const gf_t b)
+{
+ gf_log_t logsum;
+
+ ASSERT3U(b, >, 0);
+ if (a == 0)
+ return (0);
+
+ logsum = (gf_log_t) 255 + (gf_log_t) vdev_raidz_log2[a] -
+ (gf_log_t) vdev_raidz_log2[b];
+
+ return ((gf_t) vdev_raidz_pow2[logsum % 255]);
+}
+
+static inline gf_t
+gf_inv(const gf_t a)
+{
+ gf_log_t logsum;
+
+ ASSERT3U(a, >, 0);
+
+ logsum = (gf_log_t) 255 - (gf_log_t) vdev_raidz_log2[a];
+
+ return ((gf_t) vdev_raidz_pow2[logsum]);
+}
+
+static inline gf_t
+gf_exp2(gf_log_t exp)
+{
+ return (vdev_raidz_pow2[exp % 255]);
+}
+
+static inline gf_t
+gf_exp4(gf_log_t exp)
+{
+ ASSERT3U(exp, <=, 255);
+ return ((gf_t) vdev_raidz_pow2[(2 * exp) % 255]);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VDEV_RAIDZ_H */
diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz.c b/usr/src/uts/common/fs/zfs/vdev_raidz.c
index 10772d5265..e4db03ce89 100644
--- a/usr/src/uts/common/fs/zfs/vdev_raidz.c
+++ b/usr/src/uts/common/fs/zfs/vdev_raidz.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2019 by Delphix. All rights reserved.
+ * Copyright (c) 2016 Gvozden Nešković. All rights reserved.
* Copyright 2019 Joyent, Inc.
* Copyright (c) 2014 Integros [integros.com]
*/
@@ -35,6 +36,8 @@
#include <sys/abd.h>
#include <sys/fs/zfs.h>
#include <sys/fm/fs/zfs.h>
+#include <sys/vdev_raidz.h>
+#include <sys/vdev_raidz_impl.h>
#ifdef ZFS_DEBUG
#include <sys/vdev.h> /* For vdev_xlate() in vdev_raidz_io_verify() */
@@ -98,7 +101,7 @@
* R = 4^n-1 * D_0 + 4^n-2 * D_1 + ... + 4^1 * D_n-2 + 4^0 * D_n-1
* = ((...((D_0) * 4 + D_1) * 4 + ...) * 4 + D_n-2) * 4 + D_n-1
*
- * We chose 1, 2, and 4 as our generators because 1 corresponds to the trival
+ * We chose 1, 2, and 4 as our generators because 1 corresponds to the trivial
* XOR operation, and 2 and 4 can be computed quickly and generate linearly-
* independent coefficients. (There are no additional coefficients that have
* this property which is why the uncorrected Plank method breaks down.)
@@ -107,34 +110,6 @@
* or in concert to recover missing data columns.
*/
-typedef struct raidz_col {
- uint64_t rc_devidx; /* child device index for I/O */
- uint64_t rc_offset; /* device offset */
- uint64_t rc_size; /* I/O size */
- abd_t *rc_abd; /* I/O data */
- void *rc_gdata; /* used to store the "good" version */
- int rc_error; /* I/O error for this device */
- uint8_t rc_tried; /* Did we attempt this I/O column? */
- uint8_t rc_skipped; /* Did we skip this I/O column? */
-} raidz_col_t;
-
-typedef struct raidz_map {
- uint64_t rm_cols; /* Regular column count */
- uint64_t rm_scols; /* Count including skipped columns */
- uint64_t rm_bigcols; /* Number of oversized columns */
- uint64_t rm_asize; /* Actual total I/O size */
- uint64_t rm_missingdata; /* Count of missing data devices */
- uint64_t rm_missingparity; /* Count of missing parity devices */
- uint64_t rm_firstdatacol; /* First data column/parity count */
- uint64_t rm_nskip; /* Skipped sectors for padding */
- uint64_t rm_skipstart; /* Column index of padding start */
- abd_t *rm_abd_copy; /* rm_asize-buffer of copied data */
- uintptr_t rm_reports; /* # of referencing checksum reports */
- uint8_t rm_freed; /* map no longer has referencing ZIO */
- uint8_t rm_ecksuminjected; /* checksum error was injected */
- raidz_col_t rm_col[1]; /* Flexible array of I/O columns */
-} raidz_map_t;
-
#define VDEV_RAIDZ_P 0
#define VDEV_RAIDZ_Q 1
#define VDEV_RAIDZ_R 2
@@ -153,7 +128,7 @@ typedef struct raidz_map {
(mask) = (x) & 0x8080808080808080ULL; \
(mask) = ((mask) << 1) - ((mask) >> 7); \
(x) = (((x) << 1) & 0xfefefefefefefefeULL) ^ \
- ((mask) & 0x1d1d1d1d1d1d1d1d); \
+ ((mask) & 0x1d1d1d1d1d1d1d1dULL); \
}
#define VDEV_RAIDZ_64MUL_4(x, mask) \
@@ -164,104 +139,7 @@ typedef struct raidz_map {
#define VDEV_LABEL_OFFSET(x) (x + VDEV_LABEL_START_SIZE)
-/*
- * Force reconstruction to use the general purpose method.
- */
-int vdev_raidz_default_to_general;
-
-/* Powers of 2 in the Galois field defined above. */
-static const uint8_t vdev_raidz_pow2[256] = {
- 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
- 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
- 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
- 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
- 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
- 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
- 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
- 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
- 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
- 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
- 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
- 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
- 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
- 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
- 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
- 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
- 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
- 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
- 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
- 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
- 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
- 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
- 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
- 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
- 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
- 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
- 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
- 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
- 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
- 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
- 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
- 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
-};
-/* Logs of 2 in the Galois field defined above. */
-static const uint8_t vdev_raidz_log2[256] = {
- 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
- 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
- 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
- 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
- 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
- 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
- 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
- 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
- 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
- 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
- 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
- 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
- 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
- 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
- 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
- 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
- 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
- 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
- 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
- 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
- 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
- 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
- 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
- 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
- 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
- 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
- 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
- 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
- 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
- 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
- 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
- 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
-};
-
-static void vdev_raidz_generate_parity(raidz_map_t *rm);
-
-/*
- * Multiply a given number by 2 raised to the given power.
- */
-static uint8_t
-vdev_raidz_exp2(uint_t a, int exp)
-{
- if (a == 0)
- return (0);
-
- ASSERT(exp >= 0);
- ASSERT(vdev_raidz_log2[a] > 0 || a == 1);
-
- exp += vdev_raidz_log2[a];
- if (exp > 255)
- exp -= 255;
-
- return (vdev_raidz_pow2[exp]);
-}
-
-static void
+void
vdev_raidz_map_free(raidz_map_t *rm)
{
int c;
@@ -271,7 +149,6 @@ vdev_raidz_map_free(raidz_map_t *rm)
if (rm->rm_col[c].rc_gdata != NULL)
abd_free(rm->rm_col[c].rc_gdata);
-
}
for (c = rm->rm_firstdatacol; c < rm->rm_cols; c++)
@@ -311,7 +188,7 @@ static void
vdev_raidz_cksum_finish(zio_cksum_report_t *zcr, const abd_t *good_data)
{
raidz_map_t *rm = zcr->zcr_cbdata;
- size_t c = zcr->zcr_cbinfo;
+ const size_t c = zcr->zcr_cbinfo;
size_t x, offset;
const abd_t *good = NULL;
@@ -459,19 +336,19 @@ static const zio_vsd_ops_t vdev_raidz_vsd_ops = {
* Divides the IO evenly across all child vdevs; usually, dcols is
* the number of children in the target vdev.
*/
-static raidz_map_t *
-vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
- uint64_t unit_shift, uint64_t dcols, uint64_t nparity)
+raidz_map_t *
+vdev_raidz_map_alloc(zio_t *zio, uint64_t ashift, uint64_t dcols,
+ uint64_t nparity)
{
raidz_map_t *rm;
/* The starting RAIDZ (parent) vdev sector of the block. */
- uint64_t b = offset >> unit_shift;
+ uint64_t b = zio->io_offset >> ashift;
/* The zio's size in units of the vdev's minimum sector size. */
- uint64_t s = size >> unit_shift;
+ uint64_t s = zio->io_size >> ashift;
/* The first column for this stripe. */
uint64_t f = b % dcols;
/* The starting byte offset on each child vdev. */
- uint64_t o = (b / dcols) << unit_shift;
+ uint64_t o = (b / dcols) << ashift;
uint64_t q, r, c, bc, col, acols, scols, coff, devidx, asize, tot;
uint64_t off = 0;
@@ -530,7 +407,7 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
coff = o;
if (col >= dcols) {
col -= dcols;
- coff += 1ULL << unit_shift;
+ coff += 1ULL << ashift;
}
rm->rm_col[c].rc_devidx = col;
rm->rm_col[c].rc_offset = coff;
@@ -543,29 +420,29 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
if (c >= acols)
rm->rm_col[c].rc_size = 0;
else if (c < bc)
- rm->rm_col[c].rc_size = (q + 1) << unit_shift;
+ rm->rm_col[c].rc_size = (q + 1) << ashift;
else
- rm->rm_col[c].rc_size = q << unit_shift;
+ rm->rm_col[c].rc_size = q << ashift;
asize += rm->rm_col[c].rc_size;
}
- ASSERT3U(asize, ==, tot << unit_shift);
- rm->rm_asize = roundup(asize, (nparity + 1) << unit_shift);
+ ASSERT3U(asize, ==, tot << ashift);
+ rm->rm_asize = roundup(asize, (nparity + 1) << ashift);
rm->rm_nskip = roundup(tot, nparity + 1) - tot;
- ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << unit_shift);
+ ASSERT3U(rm->rm_asize - asize, ==, rm->rm_nskip << ashift);
ASSERT3U(rm->rm_nskip, <=, nparity);
for (c = 0; c < rm->rm_firstdatacol; c++)
rm->rm_col[c].rc_abd =
abd_alloc_linear(rm->rm_col[c].rc_size, B_FALSE);
- rm->rm_col[c].rc_abd = abd_get_offset_size(abd, 0,
+ rm->rm_col[c].rc_abd = abd_get_offset_size(zio->io_abd, 0,
rm->rm_col[c].rc_size);
off = rm->rm_col[c].rc_size;
for (c = c + 1; c < acols; c++) {
- rm->rm_col[c].rc_abd = abd_get_offset_size(abd, off,
+ rm->rm_col[c].rc_abd = abd_get_offset_size(zio->io_abd, off,
rm->rm_col[c].rc_size);
off += rm->rm_col[c].rc_size;
}
@@ -573,7 +450,7 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
/*
* If all data stored spans all columns, there's a danger that parity
* will always be on the same device and, since parity isn't read
- * during normal operation, that that device's I/O bandwidth won't be
+ * during normal operation, that device's I/O bandwidth won't be
* used effectively. We therefore switch the parity every 1MB.
*
* ... at least that was, ostensibly, the theory. As a practical
@@ -593,7 +470,7 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
ASSERT(rm->rm_cols >= 2);
ASSERT(rm->rm_col[0].rc_size == rm->rm_col[1].rc_size);
- if (rm->rm_firstdatacol == 1 && (offset & (1ULL << 20))) {
+ if (rm->rm_firstdatacol == 1 && (zio->io_offset & (1ULL << 20))) {
devidx = rm->rm_col[0].rc_devidx;
o = rm->rm_col[0].rc_offset;
rm->rm_col[0].rc_devidx = rm->rm_col[1].rc_devidx;
@@ -605,6 +482,9 @@ vdev_raidz_map_alloc(abd_t *abd, uint64_t size, uint64_t offset,
rm->rm_skipstart = 1;
}
+ /* init RAIDZ parity ops */
+ rm->rm_ops = vdev_raidz_math_get_ops();
+
return (rm);
}
@@ -681,7 +561,6 @@ vdev_raidz_generate_parity_p(raidz_map_t *rm)
p = abd_to_buf(rm->rm_col[VDEV_RAIDZ_P].rc_abd);
if (c == rm->rm_firstdatacol) {
- ASSERT3U(src->abd_size, >=, rm->rm_col[c].rc_size);
abd_copy_to_buf_off(p, src, 0, rm->rm_col[c].rc_size);
} else {
struct pqr_struct pqr = { p, NULL, NULL };
@@ -793,9 +672,13 @@ vdev_raidz_generate_parity_pqr(raidz_map_t *rm)
* Generate RAID parity in the first virtual columns according to the number of
* parity columns available.
*/
-static void
+void
vdev_raidz_generate_parity(raidz_map_t *rm)
{
+ /* Generate using the new math implementation */
+ if (vdev_raidz_math_generate(rm) != RAIDZ_ORIGINAL_IMPL)
+ return;
+
switch (rm->rm_firstdatacol) {
case 1:
vdev_raidz_generate_parity_p(rm);
@@ -873,8 +756,8 @@ vdev_raidz_reconst_q_post_func(void *buf, size_t size, void *private)
int cnt = size / sizeof (dst[0]);
for (int i = 0; i < cnt; i++, dst++, rq->q++) {
- *dst ^= *rq->q;
+ *dst ^= *rq->q;
int j;
uint8_t *b;
for (j = 0, b = (uint8_t *)dst; j < 8; j++, b++) {
@@ -1159,9 +1042,12 @@ vdev_raidz_reconstruct_pq(raidz_map_t *rm, int *tgts, int ntgts)
* ~~ ~~
* __ __
* | 1 1 1 1 1 1 1 1 |
+ * | 128 64 32 16 8 4 2 1 |
* | 19 205 116 29 64 16 4 1 |
* | 1 0 0 0 0 0 0 0 |
- * (V|I)' = | 0 0 0 1 0 0 0 0 |
+ * | 0 1 0 0 0 0 0 0 |
+ * (V|I)' = | 0 0 1 0 0 0 0 0 |
+ * | 0 0 0 1 0 0 0 0 |
* | 0 0 0 0 1 0 0 0 |
* | 0 0 0 0 0 1 0 0 |
* | 0 0 0 0 0 0 1 0 |
@@ -1385,8 +1271,8 @@ vdev_raidz_matrix_reconstruct(raidz_map_t *rm, int n, int nmissing,
int i, j, x, cc, c;
uint8_t *src;
uint64_t ccount;
- uint8_t *dst[VDEV_RAIDZ_MAXPARITY];
- uint64_t dcount[VDEV_RAIDZ_MAXPARITY];
+ uint8_t *dst[VDEV_RAIDZ_MAXPARITY] = { NULL };
+ uint64_t dcount[VDEV_RAIDZ_MAXPARITY] = { 0 };
uint8_t log = 0;
uint8_t val;
int ll;
@@ -1595,12 +1481,12 @@ vdev_raidz_reconstruct_general(raidz_map_t *rm, int *tgts, int ntgts)
return (code);
}
-static int
-vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt)
+int
+vdev_raidz_reconstruct(raidz_map_t *rm, const int *t, int nt)
{
int tgts[VDEV_RAIDZ_MAXPARITY], *dt;
int ntgts;
- int i, c;
+ int i, c, ret;
int code;
int nbadparity, nbaddata;
int parity_valid[VDEV_RAIDZ_MAXPARITY];
@@ -1638,34 +1524,37 @@ vdev_raidz_reconstruct(raidz_map_t *rm, int *t, int nt)
dt = &tgts[nbadparity];
+ /* Reconstruct using the new math implementation */
+ ret = vdev_raidz_math_reconstruct(rm, parity_valid, dt, nbaddata);
+ if (ret != RAIDZ_ORIGINAL_IMPL)
+ return (ret);
+
/*
* See if we can use any of our optimized reconstruction routines.
*/
- if (!vdev_raidz_default_to_general) {
- switch (nbaddata) {
- case 1:
- if (parity_valid[VDEV_RAIDZ_P])
- return (vdev_raidz_reconstruct_p(rm, dt, 1));
+ switch (nbaddata) {
+ case 1:
+ if (parity_valid[VDEV_RAIDZ_P])
+ return (vdev_raidz_reconstruct_p(rm, dt, 1));
- ASSERT(rm->rm_firstdatacol > 1);
+ ASSERT(rm->rm_firstdatacol > 1);
- if (parity_valid[VDEV_RAIDZ_Q])
- return (vdev_raidz_reconstruct_q(rm, dt, 1));
+ if (parity_valid[VDEV_RAIDZ_Q])
+ return (vdev_raidz_reconstruct_q(rm, dt, 1));
- ASSERT(rm->rm_firstdatacol > 2);
- break;
+ ASSERT(rm->rm_firstdatacol > 2);
+ break;
- case 2:
- ASSERT(rm->rm_firstdatacol > 1);
+ case 2:
+ ASSERT(rm->rm_firstdatacol > 1);
- if (parity_valid[VDEV_RAIDZ_P] &&
- parity_valid[VDEV_RAIDZ_Q])
- return (vdev_raidz_reconstruct_pq(rm, dt, 2));
+ if (parity_valid[VDEV_RAIDZ_P] &&
+ parity_valid[VDEV_RAIDZ_Q])
+ return (vdev_raidz_reconstruct_pq(rm, dt, 2));
- ASSERT(rm->rm_firstdatacol > 2);
+ ASSERT(rm->rm_firstdatacol > 2);
- break;
- }
+ break;
}
code = vdev_raidz_reconstruct_general(rm, tgts, ntgts);
@@ -1821,11 +1710,16 @@ vdev_raidz_dumpio(vdev_t *vd, caddr_t data, size_t size,
* treat the on-disk format as if the only blocks are the complete 128
* KB size.
*/
- abd_t *abd = abd_get_from_buf(data - (offset - origoffset),
+
+ /* First, fake a zio for vdev_raidz_map_alloc. */
+ zio_t *zio = kmem_zalloc(sizeof (zio_t), KM_SLEEP);
+ zio->io_offset = origoffset;
+ zio->io_size = SPA_OLD_MAXBLOCKSIZE;
+ zio->io_abd = abd_get_from_buf(data - (offset - origoffset),
SPA_OLD_MAXBLOCKSIZE);
- rm = vdev_raidz_map_alloc(abd,
- SPA_OLD_MAXBLOCKSIZE, origoffset, tvd->vdev_ashift,
- vd->vdev_children, vd->vdev_nparity);
+
+ rm = vdev_raidz_map_alloc(zio, tvd->vdev_ashift, vd->vdev_children,
+ vd->vdev_nparity);
coloffset = origoffset;
@@ -1874,7 +1768,9 @@ vdev_raidz_dumpio(vdev_t *vd, caddr_t data, size_t size,
}
vdev_raidz_map_free(rm);
- abd_put(abd);
+ abd_put(zio->io_abd);
+ kmem_free(zio, sizeof (zio_t));
+
#endif /* KERNEL */
return (err);
@@ -1965,8 +1861,7 @@ vdev_raidz_io_start(zio_t *zio)
raidz_col_t *rc;
int c, i;
- rm = vdev_raidz_map_alloc(zio->io_abd, zio->io_size, zio->io_offset,
- tvd->vdev_ashift, vd->vdev_children,
+ rm = vdev_raidz_map_alloc(zio, tvd->vdev_ashift, vd->vdev_children,
vd->vdev_nparity);
zio->io_vsd = rm;
@@ -2141,11 +2036,6 @@ raidz_parity_verify(zio_t *zio, raidz_map_t *rm)
return (ret);
}
-/*
- * Keep statistics on all the ways that we used parity to correct data.
- */
-static uint64_t raidz_corrected[1 << VDEV_RAIDZ_MAXPARITY];
-
static int
vdev_raidz_worst_error(raidz_map_t *rm)
{
@@ -2251,7 +2141,6 @@ vdev_raidz_combrec(zio_t *zio, int total_errors, int data_errors)
*/
code = vdev_raidz_reconstruct(rm, tgts, n);
if (raidz_checksum_verify(zio) == 0) {
- atomic_inc_64(&raidz_corrected[code]);
for (i = 0; i < n; i++) {
c = tgts[i];
@@ -2466,8 +2355,6 @@ vdev_raidz_io_done(zio_t *zio)
code = vdev_raidz_reconstruct(rm, tgts, n);
if (raidz_checksum_verify(zio) == 0) {
- atomic_inc_64(&raidz_corrected[code]);
-
/*
* If we read more parity disks than were used
* for reconstruction, confirm that the other
@@ -2620,7 +2507,7 @@ vdev_raidz_state_change(vdev_t *vd, int faulted, int degraded)
/*
* Determine if any portion of the provided block resides on a child vdev
* with a dirty DTL and therefore needs to be resilvered. The function
- * assumes that at least one DTL is dirty which imples that full stripe
+ * assumes that at least one DTL is dirty which implies that full stripe
* width blocks must be resilvered.
*/
static boolean_t
diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz_math.c b/usr/src/uts/common/fs/zfs/vdev_raidz_math.c
new file mode 100644
index 0000000000..2a1dac33c5
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/vdev_raidz_math.c
@@ -0,0 +1,571 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ */
+
+#include <sys/zfs_context.h>
+#include <sys/types.h>
+#include <sys/zio.h>
+#include <sys/debug.h>
+#include <sys/zfs_debug.h>
+#include <sys/vdev_raidz.h>
+#include <sys/vdev_raidz_impl.h>
+#include <sys/simd.h>
+
+#ifndef isspace
+#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \
+ (c) == '\r' || (c) == '\f' || (c) == '\013')
+#endif
+
+extern boolean_t raidz_will_scalar_work(void);
+
+/* Opaque implementation with NULL methods to represent original methods */
+static const raidz_impl_ops_t vdev_raidz_original_impl = {
+ .name = "original",
+ .is_supported = raidz_will_scalar_work,
+};
+
+/* RAIDZ parity op that contain the fastest methods */
+static raidz_impl_ops_t vdev_raidz_fastest_impl = {
+ .name = "fastest"
+};
+
+/* All compiled in implementations */
+const raidz_impl_ops_t *raidz_all_maths[] = {
+ &vdev_raidz_original_impl,
+ &vdev_raidz_scalar_impl,
+};
+
+/* Indicate that benchmark has been completed */
+static boolean_t raidz_math_initialized = B_FALSE;
+
+/* Select raidz implementation */
+#define IMPL_FASTEST (UINT32_MAX)
+#define IMPL_CYCLE (UINT32_MAX - 1)
+#define IMPL_ORIGINAL (0)
+#define IMPL_SCALAR (1)
+
+#define RAIDZ_IMPL_READ(i) (*(volatile uint32_t *) &(i))
+
+static uint32_t zfs_vdev_raidz_impl = IMPL_SCALAR;
+static uint32_t user_sel_impl = IMPL_FASTEST;
+
+/* Hold all supported implementations */
+static size_t raidz_supp_impl_cnt = 0;
+static raidz_impl_ops_t *raidz_supp_impl[ARRAY_SIZE(raidz_all_maths)];
+
+#if defined(_KERNEL)
+/*
+ * kstats values for supported implementations
+ * Values represent per disk throughput of 8 disk+parity raidz vdev [B/s]
+ *
+ * PORTING NOTE:
+ * On illumos this is not a kstat. OpenZFS uses their home-grown kstat code
+ * which implements a free-form kstat using additional functionality that does
+ * not exist in illumos. Because there are no software consumers of this
+ * information, we omit a kstat API. If an administrator needs to see this
+ * data for some reason, they can use mdb.
+ *
+ * The format of the kstat data on OpenZFS would be a "header" that looks like
+ * this (a column for each entry in the "raidz_gen_name" and "raidz_rec_name"
+ * arrays, starting with the parity function "implementation" name):
+ * impl gen_p gen_pq gen_pqr rec_p rec_q rec_r rec_pq rec_pr rec_qr rec_pqr
+ * This is followed by a row for each parity function implementation, showing
+ * the "speed" values calculated for that implementation for each of the
+ * parity generation and reconstruction functions in the "raidz_all_maths"
+ * array.
+ */
+static raidz_impl_kstat_t raidz_impl_kstats[ARRAY_SIZE(raidz_all_maths) + 1];
+
+#endif
+
+/*
+ * Returns the RAIDZ operations for raidz_map() parity calculations. When
+ * a SIMD implementation is not allowed in the current context, then fallback
+ * to the fastest generic implementation.
+ */
+const raidz_impl_ops_t *
+vdev_raidz_math_get_ops(void)
+{
+ /*
+ * illumos porting note:
+ * The following check from OpenZFS is disabled since we don't have
+ * this compiled in yet and we need to be able to change the
+ * implementation for the user-level test suite.
+ *
+ * if (!kfpu_allowed())
+ * return (&vdev_raidz_scalar_impl);
+ */
+
+ raidz_impl_ops_t *ops = NULL;
+ const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl);
+
+ switch (impl) {
+ case IMPL_FASTEST:
+ ASSERT(raidz_math_initialized);
+ ops = &vdev_raidz_fastest_impl;
+ break;
+ case IMPL_CYCLE:
+ /* Cycle through all supported implementations */
+ ASSERT(raidz_math_initialized);
+ ASSERT3U(raidz_supp_impl_cnt, >, 0);
+ static size_t cycle_impl_idx = 0;
+ size_t idx = (++cycle_impl_idx) % raidz_supp_impl_cnt;
+ ops = raidz_supp_impl[idx];
+ break;
+ case IMPL_ORIGINAL:
+ ops = (raidz_impl_ops_t *)&vdev_raidz_original_impl;
+ break;
+ case IMPL_SCALAR:
+ ops = (raidz_impl_ops_t *)&vdev_raidz_scalar_impl;
+ break;
+ default:
+ ASSERT3U(impl, <, raidz_supp_impl_cnt);
+ ASSERT3U(raidz_supp_impl_cnt, >, 0);
+ if (impl < ARRAY_SIZE(raidz_all_maths))
+ ops = raidz_supp_impl[impl];
+ break;
+ }
+
+ ASSERT3P(ops, !=, NULL);
+
+ return (ops);
+}
+
+/*
+ * Select parity generation method for raidz_map
+ */
+int
+vdev_raidz_math_generate(raidz_map_t *rm)
+{
+ raidz_gen_f gen_parity = NULL;
+
+ switch (raidz_parity(rm)) {
+ case 1:
+ gen_parity = rm->rm_ops->gen[RAIDZ_GEN_P];
+ break;
+ case 2:
+ gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQ];
+ break;
+ case 3:
+ gen_parity = rm->rm_ops->gen[RAIDZ_GEN_PQR];
+ break;
+ default:
+ gen_parity = NULL;
+ cmn_err(CE_PANIC, "invalid RAID-Z configuration %u",
+ (uint_t)raidz_parity(rm));
+ break;
+ }
+
+ /* if method is NULL execute the original implementation */
+ if (gen_parity == NULL)
+ return (RAIDZ_ORIGINAL_IMPL);
+
+ gen_parity(rm);
+
+ return (0);
+}
+
+static raidz_rec_f
+reconstruct_fun_p_sel(raidz_map_t *rm, const int *parity_valid,
+ const int nbaddata)
+{
+ if (nbaddata == 1 && parity_valid[CODE_P]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_P]);
+ }
+ return ((raidz_rec_f) NULL);
+}
+
+static raidz_rec_f
+reconstruct_fun_pq_sel(raidz_map_t *rm, const int *parity_valid,
+ const int nbaddata)
+{
+ if (nbaddata == 1) {
+ if (parity_valid[CODE_P]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_P]);
+ } else if (parity_valid[CODE_Q]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_Q]);
+ }
+ } else if (nbaddata == 2 &&
+ parity_valid[CODE_P] && parity_valid[CODE_Q]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_PQ]);
+ }
+ return ((raidz_rec_f) NULL);
+}
+
+static raidz_rec_f
+reconstruct_fun_pqr_sel(raidz_map_t *rm, const int *parity_valid,
+ const int nbaddata)
+{
+ if (nbaddata == 1) {
+ if (parity_valid[CODE_P]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_P]);
+ } else if (parity_valid[CODE_Q]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_Q]);
+ } else if (parity_valid[CODE_R]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_R]);
+ }
+ } else if (nbaddata == 2) {
+ if (parity_valid[CODE_P] && parity_valid[CODE_Q]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_PQ]);
+ } else if (parity_valid[CODE_P] && parity_valid[CODE_R]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_PR]);
+ } else if (parity_valid[CODE_Q] && parity_valid[CODE_R]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_QR]);
+ }
+ } else if (nbaddata == 3 &&
+ parity_valid[CODE_P] && parity_valid[CODE_Q] &&
+ parity_valid[CODE_R]) {
+ return (rm->rm_ops->rec[RAIDZ_REC_PQR]);
+ }
+ return ((raidz_rec_f) NULL);
+}
+
+/*
+ * Select data reconstruction method for raidz_map
+ * @parity_valid - Parity validity flag
+ * @dt - Failed data index array
+ * @nbaddata - Number of failed data columns
+ */
+int
+vdev_raidz_math_reconstruct(raidz_map_t *rm, const int *parity_valid,
+ const int *dt, const int nbaddata)
+{
+ raidz_rec_f rec_fn = NULL;
+
+ switch (raidz_parity(rm)) {
+ case PARITY_P:
+ rec_fn = reconstruct_fun_p_sel(rm, parity_valid, nbaddata);
+ break;
+ case PARITY_PQ:
+ rec_fn = reconstruct_fun_pq_sel(rm, parity_valid, nbaddata);
+ break;
+ case PARITY_PQR:
+ rec_fn = reconstruct_fun_pqr_sel(rm, parity_valid, nbaddata);
+ break;
+ default:
+ cmn_err(CE_PANIC, "invalid RAID-Z configuration %u",
+ (uint_t)raidz_parity(rm));
+ break;
+ }
+
+ if (rec_fn == NULL)
+ return (RAIDZ_ORIGINAL_IMPL);
+ else
+ return (rec_fn(rm, dt));
+}
+
+const char *raidz_gen_name[] = {
+ "gen_p", "gen_pq", "gen_pqr"
+};
+const char *raidz_rec_name[] = {
+ "rec_p", "rec_q", "rec_r",
+ "rec_pq", "rec_pr", "rec_qr", "rec_pqr"
+};
+
+#if defined(_KERNEL)
+
+#define BENCH_D_COLS (8ULL)
+#define BENCH_COLS (BENCH_D_COLS + PARITY_PQR)
+#define BENCH_ZIO_SIZE (1ULL << SPA_OLD_MAXBLOCKSHIFT) /* 128 kiB */
+#define BENCH_NS MSEC2NSEC(25) /* 25ms */
+
+typedef void (*benchmark_fn)(raidz_map_t *rm, const int fn);
+
+static void
+benchmark_gen_impl(raidz_map_t *rm, const int fn)
+{
+ (void) fn;
+ vdev_raidz_generate_parity(rm);
+}
+
+static void
+benchmark_rec_impl(raidz_map_t *rm, const int fn)
+{
+ static const int rec_tgt[7][3] = {
+ {1, 2, 3}, /* rec_p: bad QR & D[0] */
+ {0, 2, 3}, /* rec_q: bad PR & D[0] */
+ {0, 1, 3}, /* rec_r: bad PQ & D[0] */
+ {2, 3, 4}, /* rec_pq: bad R & D[0][1] */
+ {1, 3, 4}, /* rec_pr: bad Q & D[0][1] */
+ {0, 3, 4}, /* rec_qr: bad P & D[0][1] */
+ {3, 4, 5} /* rec_pqr: bad & D[0][1][2] */
+ };
+
+ vdev_raidz_reconstruct(rm, rec_tgt[fn], 3);
+}
+
+/*
+ * Benchmarking of all supported implementations (raidz_supp_impl_cnt)
+ * is performed by setting the rm_ops pointer and calling the top level
+ * generate/reconstruct methods of bench_rm.
+ */
+static void
+benchmark_raidz_impl(raidz_map_t *bench_rm, const int fn, benchmark_fn bench_fn)
+{
+ uint64_t run_cnt, speed, best_speed = 0;
+ hrtime_t t_start, t_diff;
+ raidz_impl_ops_t *curr_impl;
+ raidz_impl_kstat_t *fstat = &raidz_impl_kstats[raidz_supp_impl_cnt];
+ int impl, i;
+
+ for (impl = 0; impl < raidz_supp_impl_cnt; impl++) {
+ /* set an implementation to benchmark */
+ curr_impl = raidz_supp_impl[impl];
+ bench_rm->rm_ops = curr_impl;
+
+ run_cnt = 0;
+ t_start = gethrtime();
+
+ do {
+ for (i = 0; i < 25; i++, run_cnt++)
+ bench_fn(bench_rm, fn);
+
+ t_diff = gethrtime() - t_start;
+ } while (t_diff < BENCH_NS);
+
+ speed = run_cnt * BENCH_ZIO_SIZE * NANOSEC;
+ speed /= (t_diff * BENCH_COLS);
+
+ if (bench_fn == benchmark_gen_impl)
+ raidz_impl_kstats[impl].gen[fn] = speed;
+ else
+ raidz_impl_kstats[impl].rec[fn] = speed;
+
+ /* Update fastest implementation method */
+ if (speed > best_speed) {
+ best_speed = speed;
+
+ if (bench_fn == benchmark_gen_impl) {
+ fstat->gen[fn] = impl;
+ vdev_raidz_fastest_impl.gen[fn] =
+ curr_impl->gen[fn];
+ } else {
+ fstat->rec[fn] = impl;
+ vdev_raidz_fastest_impl.rec[fn] =
+ curr_impl->rec[fn];
+ }
+ }
+ }
+}
+#endif
+
+/*
+ * Initialize and benchmark all supported implementations.
+ */
+static void
+benchmark_raidz(void)
+{
+ raidz_impl_ops_t *curr_impl;
+ int i, c;
+
+ /* Move supported impl into raidz_supp_impl */
+ for (i = 0, c = 0; i < ARRAY_SIZE(raidz_all_maths); i++) {
+ curr_impl = (raidz_impl_ops_t *)raidz_all_maths[i];
+
+ if (curr_impl->init)
+ curr_impl->init();
+
+ if (curr_impl->is_supported())
+ raidz_supp_impl[c++] = (raidz_impl_ops_t *)curr_impl;
+ }
+ membar_producer(); /* complete raidz_supp_impl[] init */
+ raidz_supp_impl_cnt = c; /* number of supported impl */
+
+#if defined(_KERNEL)
+ zio_t *bench_zio = NULL;
+ raidz_map_t *bench_rm = NULL;
+ uint64_t bench_parity;
+
+ /* Fake a zio and run the benchmark on a warmed up buffer */
+ bench_zio = kmem_zalloc(sizeof (zio_t), KM_SLEEP);
+ bench_zio->io_offset = 0;
+ bench_zio->io_size = BENCH_ZIO_SIZE; /* only data columns */
+ bench_zio->io_abd = abd_alloc_linear(BENCH_ZIO_SIZE, B_TRUE);
+ memset(abd_to_buf(bench_zio->io_abd), 0xAA, BENCH_ZIO_SIZE);
+
+ /* Benchmark parity generation methods */
+ for (int fn = 0; fn < RAIDZ_GEN_NUM; fn++) {
+ bench_parity = fn + 1;
+ /* New raidz_map is needed for each generate_p/q/r */
+ bench_rm = vdev_raidz_map_alloc(bench_zio, SPA_MINBLOCKSHIFT,
+ BENCH_D_COLS + bench_parity, bench_parity);
+
+ benchmark_raidz_impl(bench_rm, fn, benchmark_gen_impl);
+
+ vdev_raidz_map_free(bench_rm);
+ }
+
+ /* Benchmark data reconstruction methods */
+ bench_rm = vdev_raidz_map_alloc(bench_zio, SPA_MINBLOCKSHIFT,
+ BENCH_COLS, PARITY_PQR);
+
+ for (int fn = 0; fn < RAIDZ_REC_NUM; fn++)
+ benchmark_raidz_impl(bench_rm, fn, benchmark_rec_impl);
+
+ vdev_raidz_map_free(bench_rm);
+
+ /* cleanup the bench zio */
+ abd_free(bench_zio->io_abd);
+ kmem_free(bench_zio, sizeof (zio_t));
+#else
+ /*
+ * Skip the benchmark in user space to avoid impacting libzpool
+ * consumers (zdb, zhack, zinject, ztest). The last implementation
+ * is assumed to be the fastest and used by default.
+ */
+ memcpy(&vdev_raidz_fastest_impl,
+ raidz_supp_impl[raidz_supp_impl_cnt - 1],
+ sizeof (vdev_raidz_fastest_impl));
+ strcpy(vdev_raidz_fastest_impl.name, "fastest");
+#endif /* _KERNEL */
+}
+
+void
+vdev_raidz_math_init(void)
+{
+ /* Determine the fastest available implementation. */
+ benchmark_raidz();
+
+ /* Finish initialization */
+ atomic_swap_32(&zfs_vdev_raidz_impl, user_sel_impl);
+ raidz_math_initialized = B_TRUE;
+}
+
+void
+vdev_raidz_math_fini(void)
+{
+ raidz_impl_ops_t const *curr_impl;
+
+ for (int i = 0; i < ARRAY_SIZE(raidz_all_maths); i++) {
+ curr_impl = raidz_all_maths[i];
+ if (curr_impl->fini)
+ curr_impl->fini();
+ }
+}
+
+static const struct {
+ char *name;
+ uint32_t sel;
+} math_impl_opts[] = {
+ { "cycle", IMPL_CYCLE },
+ { "fastest", IMPL_FASTEST },
+ { "original", IMPL_ORIGINAL },
+ { "scalar", IMPL_SCALAR }
+};
+
+/*
+ * Function sets desired raidz implementation.
+ *
+ * If we are called before init(), user preference will be saved in
+ * user_sel_impl, and applied in later init() call. This occurs when module
+ * parameter is specified on module load. Otherwise, directly update
+ * zfs_vdev_raidz_impl.
+ *
+ * @val Name of raidz implementation to use
+ * @param Unused.
+ */
+int
+vdev_raidz_impl_set(const char *val)
+{
+ int err = -EINVAL;
+ char req_name[RAIDZ_IMPL_NAME_MAX];
+ uint32_t impl = RAIDZ_IMPL_READ(user_sel_impl);
+ size_t i;
+
+ /* sanitize input */
+ i = strnlen(val, RAIDZ_IMPL_NAME_MAX);
+ if (i == 0 || i == RAIDZ_IMPL_NAME_MAX)
+ return (err);
+
+ strlcpy(req_name, val, RAIDZ_IMPL_NAME_MAX);
+ while (i > 0 && !!isspace(req_name[i-1]))
+ i--;
+ req_name[i] = '\0';
+
+ /* Check mandatory options */
+ for (i = 0; i < ARRAY_SIZE(math_impl_opts); i++) {
+ if (strcmp(req_name, math_impl_opts[i].name) == 0) {
+ impl = math_impl_opts[i].sel;
+ err = 0;
+ break;
+ }
+ }
+
+ /* check all supported impl if init() was already called */
+ if (err != 0 && raidz_math_initialized) {
+ /* check all supported implementations */
+ for (i = 0; i < raidz_supp_impl_cnt; i++) {
+ if (strcmp(req_name, raidz_supp_impl[i]->name) == 0) {
+ impl = i;
+ err = 0;
+ break;
+ }
+ }
+ }
+
+ if (err == 0) {
+ if (raidz_math_initialized)
+ atomic_swap_32(&zfs_vdev_raidz_impl, impl);
+ else
+ atomic_swap_32(&user_sel_impl, impl);
+ }
+
+ return (err);
+}
+
+#if defined(_KERNEL) && defined(__linux__)
+
+static int
+zfs_vdev_raidz_impl_set(const char *val, zfs_kernel_param_t *kp)
+{
+ return (vdev_raidz_impl_set(val));
+}
+
+static int
+zfs_vdev_raidz_impl_get(char *buffer, zfs_kernel_param_t *kp)
+{
+ int i, cnt = 0;
+ char *fmt;
+ const uint32_t impl = RAIDZ_IMPL_READ(zfs_vdev_raidz_impl);
+
+ ASSERT(raidz_math_initialized);
+
+ /* list mandatory options */
+ for (i = 0; i < ARRAY_SIZE(math_impl_opts) - 2; i++) {
+ fmt = (impl == math_impl_opts[i].sel) ? "[%s] " : "%s ";
+ cnt += sprintf(buffer + cnt, fmt, math_impl_opts[i].name);
+ }
+
+ /* list all supported implementations */
+ for (i = 0; i < raidz_supp_impl_cnt; i++) {
+ fmt = (i == impl) ? "[%s] " : "%s ";
+ cnt += sprintf(buffer + cnt, fmt, raidz_supp_impl[i]->name);
+ }
+
+ return (cnt);
+}
+
+module_param_call(zfs_vdev_raidz_impl, zfs_vdev_raidz_impl_set,
+ zfs_vdev_raidz_impl_get, NULL, 0644);
+MODULE_PARM_DESC(zfs_vdev_raidz_impl, "Select raidz implementation.");
+#endif
diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz_math_impl.h b/usr/src/uts/common/fs/zfs/vdev_raidz_math_impl.h
new file mode 100644
index 0000000000..89c2082c4a
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/vdev_raidz_math_impl.h
@@ -0,0 +1,1477 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ */
+
+#ifndef _VDEV_RAIDZ_MATH_IMPL_H
+#define _VDEV_RAIDZ_MATH_IMPL_H
+
+#include <sys/types.h>
+
+#define raidz_inline inline __attribute__((always_inline))
+#ifndef noinline
+#define noinline __attribute__((noinline))
+#endif
+
+/*
+ * Functions calculate multiplication constants for data reconstruction.
+ * Coefficients depend on RAIDZ geometry, indexes of failed child vdevs, and
+ * used parity columns for reconstruction.
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ * @coeff output array of coefficients. Array must be provided by
+ * user and must hold minimum MUL_CNT values.
+ */
+static noinline void
+raidz_rec_q_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+
+ coeff[MUL_Q_X] = gf_exp2(255 - (ncols - x - 1));
+}
+
+static noinline void
+raidz_rec_r_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+
+ coeff[MUL_R_X] = gf_exp4(255 - (ncols - x - 1));
+}
+
+static noinline void
+raidz_rec_pq_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+ const unsigned y = tgtidx[TARGET_Y];
+ gf_t a, b, e;
+
+ a = gf_exp2(x + 255 - y);
+ b = gf_exp2(255 - (ncols - x - 1));
+ e = a ^ 0x01;
+
+ coeff[MUL_PQ_X] = gf_div(a, e);
+ coeff[MUL_PQ_Y] = gf_div(b, e);
+}
+
+static noinline void
+raidz_rec_pr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+ const unsigned y = tgtidx[TARGET_Y];
+
+ gf_t a, b, e;
+
+ a = gf_exp4(x + 255 - y);
+ b = gf_exp4(255 - (ncols - x - 1));
+ e = a ^ 0x01;
+
+ coeff[MUL_PR_X] = gf_div(a, e);
+ coeff[MUL_PR_Y] = gf_div(b, e);
+}
+
+static noinline void
+raidz_rec_qr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+ const unsigned y = tgtidx[TARGET_Y];
+
+ gf_t nx, ny, nxxy, nxyy, d;
+
+ nx = gf_exp2(ncols - x - 1);
+ ny = gf_exp2(ncols - y - 1);
+ nxxy = gf_mul(gf_mul(nx, nx), ny);
+ nxyy = gf_mul(gf_mul(nx, ny), ny);
+ d = nxxy ^ nxyy;
+
+ coeff[MUL_QR_XQ] = ny;
+ coeff[MUL_QR_X] = gf_div(ny, d);
+ coeff[MUL_QR_YQ] = nx;
+ coeff[MUL_QR_Y] = gf_div(nx, d);
+}
+
+static noinline void
+raidz_rec_pqr_coeff(const raidz_map_t *rm, const int *tgtidx, unsigned *coeff)
+{
+ const unsigned ncols = raidz_ncols(rm);
+ const unsigned x = tgtidx[TARGET_X];
+ const unsigned y = tgtidx[TARGET_Y];
+ const unsigned z = tgtidx[TARGET_Z];
+
+ gf_t nx, ny, nz, nxx, nyy, nzz, nyyz, nyzz, xd, yd;
+
+ nx = gf_exp2(ncols - x - 1);
+ ny = gf_exp2(ncols - y - 1);
+ nz = gf_exp2(ncols - z - 1);
+
+ nxx = gf_exp4(ncols - x - 1);
+ nyy = gf_exp4(ncols - y - 1);
+ nzz = gf_exp4(ncols - z - 1);
+
+ nyyz = gf_mul(gf_mul(ny, nz), ny);
+ nyzz = gf_mul(nzz, ny);
+
+ xd = gf_mul(nxx, ny) ^ gf_mul(nx, nyy) ^ nyyz ^
+ gf_mul(nxx, nz) ^ gf_mul(nzz, nx) ^ nyzz;
+
+ yd = gf_inv(ny ^ nz);
+
+ coeff[MUL_PQR_XP] = gf_div(nyyz ^ nyzz, xd);
+ coeff[MUL_PQR_XQ] = gf_div(nyy ^ nzz, xd);
+ coeff[MUL_PQR_XR] = gf_div(ny ^ nz, xd);
+ coeff[MUL_PQR_YU] = nx;
+ coeff[MUL_PQR_YP] = gf_mul(nz, yd);
+ coeff[MUL_PQR_YQ] = yd;
+}
+
+/*
+ * Method for zeroing a buffer (can be implemented using SIMD).
+ * This method is used by multiple for gen/rec functions.
+ *
+ * @dc Destination buffer
+ * @dsize Destination buffer size
+ * @private Unused
+ */
+static int
+raidz_zero_abd_cb(void *dc, size_t dsize, void *private)
+{
+ v_t *dst = (v_t *)dc;
+ size_t i;
+
+ ZERO_DEFINE();
+
+ (void) private; /* unused */
+
+ ZERO(ZERO_D);
+
+ for (i = 0; i < dsize / sizeof (v_t); i += (2 * ZERO_STRIDE)) {
+ STORE(dst + i, ZERO_D);
+ STORE(dst + i + ZERO_STRIDE, ZERO_D);
+ }
+
+ return (0);
+}
+
+#define raidz_zero(dabd, size) \
+{ \
+ abd_iterate_func(dabd, 0, size, raidz_zero_abd_cb, NULL); \
+}
+
+/*
+ * Method for copying two buffers (can be implemented using SIMD).
+ * This method is used by multiple for gen/rec functions.
+ *
+ * @dc Destination buffer
+ * @sc Source buffer
+ * @dsize Destination buffer size
+ * @ssize Source buffer size
+ * @private Unused
+ */
+static int
+raidz_copy_abd_cb(void *dc, void *sc, size_t size, void *private)
+{
+ v_t *dst = (v_t *)dc;
+ const v_t *src = (v_t *)sc;
+ size_t i;
+
+ COPY_DEFINE();
+
+ (void) private; /* unused */
+
+ for (i = 0; i < size / sizeof (v_t); i += (2 * COPY_STRIDE)) {
+ LOAD(src + i, COPY_D);
+ STORE(dst + i, COPY_D);
+
+ LOAD(src + i + COPY_STRIDE, COPY_D);
+ STORE(dst + i + COPY_STRIDE, COPY_D);
+ }
+
+ return (0);
+}
+
+
+#define raidz_copy(dabd, sabd, size) \
+{ \
+ abd_iterate_func2(dabd, sabd, 0, 0, size, raidz_copy_abd_cb, NULL);\
+}
+
+/*
+ * Method for adding (XORing) two buffers.
+ * Source and destination are XORed together and result is stored in
+ * destination buffer. This method is used by multiple for gen/rec functions.
+ *
+ * @dc Destination buffer
+ * @sc Source buffer
+ * @dsize Destination buffer size
+ * @ssize Source buffer size
+ * @private Unused
+ */
+static int
+raidz_add_abd_cb(void *dc, void *sc, size_t size, void *private)
+{
+ v_t *dst = (v_t *)dc;
+ const v_t *src = (v_t *)sc;
+ size_t i;
+
+ ADD_DEFINE();
+
+ (void) private; /* unused */
+
+ for (i = 0; i < size / sizeof (v_t); i += (2 * ADD_STRIDE)) {
+ LOAD(dst + i, ADD_D);
+ XOR_ACC(src + i, ADD_D);
+ STORE(dst + i, ADD_D);
+
+ LOAD(dst + i + ADD_STRIDE, ADD_D);
+ XOR_ACC(src + i + ADD_STRIDE, ADD_D);
+ STORE(dst + i + ADD_STRIDE, ADD_D);
+ }
+
+ return (0);
+}
+
+#define raidz_add(dabd, sabd, size) \
+{ \
+ abd_iterate_func2(dabd, sabd, 0, 0, size, raidz_add_abd_cb, NULL);\
+}
+
+/*
+ * Method for multiplying a buffer with a constant in GF(2^8).
+ * Symbols from buffer are multiplied by a constant and result is stored
+ * back in the same buffer.
+ *
+ * @dc In/Out data buffer.
+ * @size Size of the buffer
+ * @private pointer to the multiplication constant (unsigned)
+ */
+static int
+raidz_mul_abd_cb(void *dc, size_t size, void *private)
+{
+ const unsigned mul = *((unsigned *)private);
+ v_t *d = (v_t *)dc;
+ size_t i;
+
+ MUL_DEFINE();
+
+ for (i = 0; i < size / sizeof (v_t); i += (2 * MUL_STRIDE)) {
+ LOAD(d + i, MUL_D);
+ MUL(mul, MUL_D);
+ STORE(d + i, MUL_D);
+
+ LOAD(d + i + MUL_STRIDE, MUL_D);
+ MUL(mul, MUL_D);
+ STORE(d + i + MUL_STRIDE, MUL_D);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Syndrome generation/update macros
+ *
+ * Require LOAD(), XOR(), STORE(), MUL2(), and MUL4() macros
+ */
+#define P_D_SYNDROME(D, T, t) \
+{ \
+ LOAD((t), T); \
+ XOR(D, T); \
+ STORE((t), T); \
+}
+
+#define Q_D_SYNDROME(D, T, t) \
+{ \
+ LOAD((t), T); \
+ MUL2(T); \
+ XOR(D, T); \
+ STORE((t), T); \
+}
+
+#define Q_SYNDROME(T, t) \
+{ \
+ LOAD((t), T); \
+ MUL2(T); \
+ STORE((t), T); \
+}
+
+#define R_D_SYNDROME(D, T, t) \
+{ \
+ LOAD((t), T); \
+ MUL4(T); \
+ XOR(D, T); \
+ STORE((t), T); \
+}
+
+#define R_SYNDROME(T, t) \
+{ \
+ LOAD((t), T); \
+ MUL4(T); \
+ STORE((t), T); \
+}
+
+
+/*
+ * PARITY CALCULATION
+ *
+ * Macros *_SYNDROME are used for parity/syndrome calculation.
+ * *_D_SYNDROME() macros are used to calculate syndrome between 0 and
+ * length of data column, and *_SYNDROME() macros are only for updating
+ * the parity/syndrome if data column is shorter.
+ *
+ * P parity is calculated using raidz_add_abd().
+ */
+
+/*
+ * Generate P parity (RAIDZ1)
+ *
+ * @rm RAIDZ map
+ */
+static raidz_inline void
+raidz_generate_p_impl(raidz_map_t * const rm)
+{
+ size_t c;
+ const size_t ncols = raidz_ncols(rm);
+ const size_t psize = rm->rm_col[CODE_P].rc_size;
+ abd_t *pabd = rm->rm_col[CODE_P].rc_abd;
+ size_t size;
+ abd_t *dabd;
+
+ raidz_math_begin();
+
+ /* start with first data column */
+ raidz_copy(pabd, rm->rm_col[1].rc_abd, psize);
+
+ for (c = 2; c < ncols; c++) {
+ dabd = rm->rm_col[c].rc_abd;
+ size = rm->rm_col[c].rc_size;
+
+ /* add data column */
+ raidz_add(pabd, dabd, size);
+ }
+
+ raidz_math_end();
+}
+
+
+/*
+ * Generate PQ parity (RAIDZ2)
+ * The function is called per data column.
+ *
+ * @c array of pointers to parity (code) columns
+ * @dc pointer to data column
+ * @csize size of parity columns
+ * @dsize size of data column
+ */
+static void
+raidz_gen_pq_add(void **c, const void *dc, const size_t csize,
+ const size_t dsize)
+{
+ v_t *p = (v_t *)c[0];
+ v_t *q = (v_t *)c[1];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const qend = q + (csize / sizeof (v_t));
+
+ GEN_PQ_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += GEN_PQ_STRIDE, p += GEN_PQ_STRIDE,
+ q += GEN_PQ_STRIDE) {
+ LOAD(d, GEN_PQ_D);
+ P_D_SYNDROME(GEN_PQ_D, GEN_PQ_C, p);
+ Q_D_SYNDROME(GEN_PQ_D, GEN_PQ_C, q);
+ }
+ for (; q < qend; q += GEN_PQ_STRIDE) {
+ Q_SYNDROME(GEN_PQ_C, q);
+ }
+}
+
+
+/*
+ * Generate PQ parity (RAIDZ2)
+ *
+ * @rm RAIDZ map
+ */
+static raidz_inline void
+raidz_generate_pq_impl(raidz_map_t * const rm)
+{
+ size_t c;
+ const size_t ncols = raidz_ncols(rm);
+ const size_t csize = rm->rm_col[CODE_P].rc_size;
+ size_t dsize;
+ abd_t *dabd;
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_P].rc_abd,
+ rm->rm_col[CODE_Q].rc_abd
+ };
+
+ raidz_math_begin();
+
+ raidz_copy(cabds[CODE_P], rm->rm_col[2].rc_abd, csize);
+ raidz_copy(cabds[CODE_Q], rm->rm_col[2].rc_abd, csize);
+
+ for (c = 3; c < ncols; c++) {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+
+ abd_raidz_gen_iterate(cabds, dabd, csize, dsize, 2,
+ raidz_gen_pq_add);
+ }
+
+ raidz_math_end();
+}
+
+
+/*
+ * Generate PQR parity (RAIDZ3)
+ * The function is called per data column.
+ *
+ * @c array of pointers to parity (code) columns
+ * @dc pointer to data column
+ * @csize size of parity columns
+ * @dsize size of data column
+ */
+static void
+raidz_gen_pqr_add(void **c, const void *dc, const size_t csize,
+ const size_t dsize)
+{
+ v_t *p = (v_t *)c[0];
+ v_t *q = (v_t *)c[1];
+ v_t *r = (v_t *)c[CODE_R];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const qend = q + (csize / sizeof (v_t));
+
+ GEN_PQR_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += GEN_PQR_STRIDE, p += GEN_PQR_STRIDE,
+ q += GEN_PQR_STRIDE, r += GEN_PQR_STRIDE) {
+ LOAD(d, GEN_PQR_D);
+ P_D_SYNDROME(GEN_PQR_D, GEN_PQR_C, p);
+ Q_D_SYNDROME(GEN_PQR_D, GEN_PQR_C, q);
+ R_D_SYNDROME(GEN_PQR_D, GEN_PQR_C, r);
+ }
+ for (; q < qend; q += GEN_PQR_STRIDE, r += GEN_PQR_STRIDE) {
+ Q_SYNDROME(GEN_PQR_C, q);
+ R_SYNDROME(GEN_PQR_C, r);
+ }
+}
+
+
+/*
+ * Generate PQR parity (RAIDZ2)
+ *
+ * @rm RAIDZ map
+ */
+static raidz_inline void
+raidz_generate_pqr_impl(raidz_map_t * const rm)
+{
+ size_t c;
+ const size_t ncols = raidz_ncols(rm);
+ const size_t csize = rm->rm_col[CODE_P].rc_size;
+ size_t dsize;
+ abd_t *dabd;
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_P].rc_abd,
+ rm->rm_col[CODE_Q].rc_abd,
+ rm->rm_col[CODE_R].rc_abd
+ };
+
+ raidz_math_begin();
+
+ raidz_copy(cabds[CODE_P], rm->rm_col[3].rc_abd, csize);
+ raidz_copy(cabds[CODE_Q], rm->rm_col[3].rc_abd, csize);
+ raidz_copy(cabds[CODE_R], rm->rm_col[3].rc_abd, csize);
+
+ for (c = 4; c < ncols; c++) {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+
+ abd_raidz_gen_iterate(cabds, dabd, csize, dsize, 3,
+ raidz_gen_pqr_add);
+ }
+
+ raidz_math_end();
+}
+
+
+/*
+ * DATA RECONSTRUCTION
+ *
+ * Data reconstruction process consists of two phases:
+ * - Syndrome calculation
+ * - Data reconstruction
+ *
+ * Syndrome is calculated by generating parity using available data columns
+ * and zeros in places of erasure. Existing parity is added to corresponding
+ * syndrome value to obtain the [P|Q|R]syn values from equation:
+ * P = Psyn + Dx + Dy + Dz
+ * Q = Qsyn + 2^x * Dx + 2^y * Dy + 2^z * Dz
+ * R = Rsyn + 4^x * Dx + 4^y * Dy + 4^z * Dz
+ *
+ * For data reconstruction phase, the corresponding equations are solved
+ * for missing data (Dx, Dy, Dz). This generally involves multiplying known
+ * symbols by an coefficient and adding them together. The multiplication
+ * constant coefficients are calculated ahead of the operation in
+ * raidz_rec_[q|r|pq|pq|qr|pqr]_coeff() functions.
+ *
+ * IMPLEMENTATION NOTE: RAID-Z block can have complex geometry, with "big"
+ * and "short" columns.
+ * For this reason, reconstruction is performed in minimum of
+ * two steps. First, from offset 0 to short_size, then from short_size to
+ * short_size. Calculation functions REC_[*]_BLOCK() are implemented to work
+ * over both ranges. The split also enables removal of conditional expressions
+ * from loop bodies, improving throughput of SIMD implementations.
+ * For the best performance, all functions marked with raidz_inline attribute
+ * must be inlined by compiler.
+ *
+ * parity data
+ * columns columns
+ * <----------> <------------------>
+ * x y <----+ missing columns (x, y)
+ * | |
+ * +---+---+---+---+-v-+---+-v-+---+ ^ 0
+ * | | | | | | | | | |
+ * | | | | | | | | | |
+ * | P | Q | R | D | D | D | D | D | |
+ * | | | | 0 | 1 | 2 | 3 | 4 | |
+ * | | | | | | | | | v
+ * | | | | | +---+---+---+ ^ short_size
+ * | | | | | | |
+ * +---+---+---+---+---+ v big_size
+ * <------------------> <---------->
+ * big columns short columns
+ *
+ */
+
+
+
+
+/*
+ * Reconstruct single data column using P parity
+ *
+ * @syn_method raidz_add_abd()
+ * @rec_method not applicable
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_p_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ size_t size;
+ abd_t *dabd;
+
+ raidz_math_begin();
+
+ /* copy P into target */
+ raidz_copy(xabd, rm->rm_col[CODE_P].rc_abd, xsize);
+
+ /* generate p_syndrome */
+ for (c = firstdc; c < ncols; c++) {
+ if (c == x)
+ continue;
+
+ dabd = rm->rm_col[c].rc_abd;
+ size = MIN(rm->rm_col[c].rc_size, xsize);
+
+ raidz_add(xabd, dabd, size);
+ }
+
+ raidz_math_end();
+
+ return (1 << CODE_P);
+}
+
+
+/*
+ * Generate Q syndrome (Qsyn)
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @xsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_q_abd(void **xc, const void *dc, const size_t xsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)xc[TARGET_X];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const xend = x + (xsize / sizeof (v_t));
+
+ SYN_Q_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE) {
+ LOAD(d, SYN_Q_D);
+ Q_D_SYNDROME(SYN_Q_D, SYN_Q_X, x);
+ }
+ for (; x < xend; x += SYN_STRIDE) {
+ Q_SYNDROME(SYN_Q_X, x);
+ }
+}
+
+
+/*
+ * Reconstruct single data column using Q parity
+ *
+ * @syn_method raidz_add_abd()
+ * @rec_method raidz_mul_abd_cb()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_q_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ const size_t xsize = rm->rm_col[x].rc_size;
+ abd_t *tabds[] = { xabd };
+
+ unsigned coeff[MUL_CNT];
+ raidz_rec_q_coeff(rm, tgtidx, coeff);
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ }
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 1,
+ raidz_syn_q_abd);
+ }
+
+ /* add Q to the syndrome */
+ raidz_add(xabd, rm->rm_col[CODE_Q].rc_abd, xsize);
+
+ /* transform the syndrome */
+ abd_iterate_func(xabd, 0, xsize, raidz_mul_abd_cb, (void*) coeff);
+
+ raidz_math_end();
+
+ return (1 << CODE_Q);
+}
+
+
+/*
+ * Generate R syndrome (Rsyn)
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @tsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_r_abd(void **xc, const void *dc, const size_t tsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)xc[TARGET_X];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+
+ SYN_R_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE) {
+ LOAD(d, SYN_R_D);
+ R_D_SYNDROME(SYN_R_D, SYN_R_X, x);
+ }
+ for (; x < xend; x += SYN_STRIDE) {
+ R_SYNDROME(SYN_R_X, x);
+ }
+}
+
+
+/*
+ * Reconstruct single data column using R parity
+ *
+ * @syn_method raidz_add_abd()
+ * @rec_method raidz_mul_abd_cb()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_r_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ abd_t *tabds[] = { xabd };
+
+ unsigned coeff[MUL_CNT];
+ raidz_rec_r_coeff(rm, tgtidx, coeff);
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ }
+
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 1,
+ raidz_syn_r_abd);
+ }
+
+ /* add R to the syndrome */
+ raidz_add(xabd, rm->rm_col[CODE_R].rc_abd, xsize);
+
+ /* transform the syndrome */
+ abd_iterate_func(xabd, 0, xsize, raidz_mul_abd_cb, (void *)coeff);
+
+ raidz_math_end();
+
+ return (1 << CODE_R);
+}
+
+
+/*
+ * Generate P and Q syndromes
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @tsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_pq_abd(void **tc, const void *dc, const size_t tsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)tc[TARGET_X];
+ v_t *y = (v_t *)tc[TARGET_Y];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const yend = y + (tsize / sizeof (v_t));
+
+ SYN_PQ_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE, y += SYN_STRIDE) {
+ LOAD(d, SYN_PQ_D);
+ P_D_SYNDROME(SYN_PQ_D, SYN_PQ_X, x);
+ Q_D_SYNDROME(SYN_PQ_D, SYN_PQ_X, y);
+ }
+ for (; y < yend; y += SYN_STRIDE) {
+ Q_SYNDROME(SYN_PQ_X, y);
+ }
+}
+
+/*
+ * Reconstruct data using PQ parity and PQ syndromes
+ *
+ * @tc syndrome/result columns
+ * @tsize size of syndrome/result columns
+ * @c parity columns
+ * @mul array of multiplication constants
+ */
+static void
+raidz_rec_pq_abd(void **tc, const size_t tsize, void **c,
+ const unsigned *mul)
+{
+ v_t *x = (v_t *)tc[TARGET_X];
+ v_t *y = (v_t *)tc[TARGET_Y];
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+ const v_t *p = (v_t *)c[CODE_P];
+ const v_t *q = (v_t *)c[CODE_Q];
+
+ REC_PQ_DEFINE();
+
+ for (; x < xend; x += REC_PQ_STRIDE, y += REC_PQ_STRIDE,
+ p += REC_PQ_STRIDE, q += REC_PQ_STRIDE) {
+ LOAD(x, REC_PQ_X);
+ LOAD(y, REC_PQ_Y);
+
+ XOR_ACC(p, REC_PQ_X);
+ XOR_ACC(q, REC_PQ_Y);
+
+ /* Save Pxy */
+ COPY(REC_PQ_X, REC_PQ_T);
+
+ /* Calc X */
+ MUL(mul[MUL_PQ_X], REC_PQ_X);
+ MUL(mul[MUL_PQ_Y], REC_PQ_Y);
+ XOR(REC_PQ_Y, REC_PQ_X);
+ STORE(x, REC_PQ_X);
+
+ /* Calc Y */
+ XOR(REC_PQ_T, REC_PQ_X);
+ STORE(y, REC_PQ_X);
+ }
+}
+
+
+/*
+ * Reconstruct two data columns using PQ parity
+ *
+ * @syn_method raidz_syn_pq_abd()
+ * @rec_method raidz_rec_pq_abd()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_pq_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ const size_t y = tgtidx[TARGET_Y];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ const size_t ysize = rm->rm_col[y].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ abd_t *yabd = rm->rm_col[y].rc_abd;
+ abd_t *tabds[2] = { xabd, yabd };
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_P].rc_abd,
+ rm->rm_col[CODE_Q].rc_abd
+ };
+
+ unsigned coeff[MUL_CNT];
+ raidz_rec_pq_coeff(rm, tgtidx, coeff);
+
+ /*
+ * Check if some of targets is shorter then others
+ * In this case, shorter target needs to be replaced with
+ * new buffer so that syndrome can be calculated.
+ */
+ if (ysize < xsize) {
+ yabd = abd_alloc(xsize, B_FALSE);
+ tabds[1] = yabd;
+ }
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ raidz_zero(yabd, xsize);
+ }
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x || c == y) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
+ raidz_syn_pq_abd);
+ }
+
+ abd_raidz_rec_iterate(cabds, tabds, xsize, 2, raidz_rec_pq_abd, coeff);
+
+ /* Copy shorter targets back to the original abd buffer */
+ if (ysize < xsize)
+ raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
+
+ raidz_math_end();
+
+ if (ysize < xsize)
+ abd_free(yabd);
+
+ return ((1 << CODE_P) | (1 << CODE_Q));
+}
+
+
+/*
+ * Generate P and R syndromes
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @tsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_pr_abd(void **c, const void *dc, const size_t tsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)c[TARGET_X];
+ v_t *y = (v_t *)c[TARGET_Y];
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+ const v_t * const yend = y + (tsize / sizeof (v_t));
+
+ SYN_PR_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE, y += SYN_STRIDE) {
+ LOAD(d, SYN_PR_D);
+ P_D_SYNDROME(SYN_PR_D, SYN_PR_X, x);
+ R_D_SYNDROME(SYN_PR_D, SYN_PR_X, y);
+ }
+ for (; y < yend; y += SYN_STRIDE) {
+ R_SYNDROME(SYN_PR_X, y);
+ }
+}
+
+/*
+ * Reconstruct data using PR parity and PR syndromes
+ *
+ * @tc syndrome/result columns
+ * @tsize size of syndrome/result columns
+ * @c parity columns
+ * @mul array of multiplication constants
+ */
+static void
+raidz_rec_pr_abd(void **t, const size_t tsize, void **c,
+ const unsigned *mul)
+{
+ v_t *x = (v_t *)t[TARGET_X];
+ v_t *y = (v_t *)t[TARGET_Y];
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+ const v_t *p = (v_t *)c[CODE_P];
+ const v_t *q = (v_t *)c[CODE_Q];
+
+ REC_PR_DEFINE();
+
+ for (; x < xend; x += REC_PR_STRIDE, y += REC_PR_STRIDE,
+ p += REC_PR_STRIDE, q += REC_PR_STRIDE) {
+ LOAD(x, REC_PR_X);
+ LOAD(y, REC_PR_Y);
+ XOR_ACC(p, REC_PR_X);
+ XOR_ACC(q, REC_PR_Y);
+
+ /* Save Pxy */
+ COPY(REC_PR_X, REC_PR_T);
+
+ /* Calc X */
+ MUL(mul[MUL_PR_X], REC_PR_X);
+ MUL(mul[MUL_PR_Y], REC_PR_Y);
+ XOR(REC_PR_Y, REC_PR_X);
+ STORE(x, REC_PR_X);
+
+ /* Calc Y */
+ XOR(REC_PR_T, REC_PR_X);
+ STORE(y, REC_PR_X);
+ }
+}
+
+
+/*
+ * Reconstruct two data columns using PR parity
+ *
+ * @syn_method raidz_syn_pr_abd()
+ * @rec_method raidz_rec_pr_abd()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_pr_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[0];
+ const size_t y = tgtidx[1];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ const size_t ysize = rm->rm_col[y].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ abd_t *yabd = rm->rm_col[y].rc_abd;
+ abd_t *tabds[2] = { xabd, yabd };
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_P].rc_abd,
+ rm->rm_col[CODE_R].rc_abd
+ };
+ unsigned coeff[MUL_CNT];
+ raidz_rec_pr_coeff(rm, tgtidx, coeff);
+
+ /*
+ * Check if some of targets are shorter then others.
+ * They need to be replaced with a new buffer so that syndrome can
+ * be calculated on full length.
+ */
+ if (ysize < xsize) {
+ yabd = abd_alloc(xsize, B_FALSE);
+ tabds[1] = yabd;
+ }
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ raidz_zero(yabd, xsize);
+ }
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x || c == y) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
+ raidz_syn_pr_abd);
+ }
+
+ abd_raidz_rec_iterate(cabds, tabds, xsize, 2, raidz_rec_pr_abd, coeff);
+
+ /*
+ * Copy shorter targets back to the original abd buffer
+ */
+ if (ysize < xsize)
+ raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
+
+ raidz_math_end();
+
+ if (ysize < xsize)
+ abd_free(yabd);
+
+ return ((1 << CODE_P) | (1 << CODE_Q));
+}
+
+
+/*
+ * Generate Q and R syndromes
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @tsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_qr_abd(void **c, const void *dc, const size_t tsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)c[TARGET_X];
+ v_t *y = (v_t *)c[TARGET_Y];
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+
+ SYN_QR_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE, y += SYN_STRIDE) {
+ LOAD(d, SYN_PQ_D);
+ Q_D_SYNDROME(SYN_QR_D, SYN_QR_X, x);
+ R_D_SYNDROME(SYN_QR_D, SYN_QR_X, y);
+ }
+ for (; x < xend; x += SYN_STRIDE, y += SYN_STRIDE) {
+ Q_SYNDROME(SYN_QR_X, x);
+ R_SYNDROME(SYN_QR_X, y);
+ }
+}
+
+
+/*
+ * Reconstruct data using QR parity and QR syndromes
+ *
+ * @tc syndrome/result columns
+ * @tsize size of syndrome/result columns
+ * @c parity columns
+ * @mul array of multiplication constants
+ */
+static void
+raidz_rec_qr_abd(void **t, const size_t tsize, void **c,
+ const unsigned *mul)
+{
+ v_t *x = (v_t *)t[TARGET_X];
+ v_t *y = (v_t *)t[TARGET_Y];
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+ const v_t *p = (v_t *)c[CODE_P];
+ const v_t *q = (v_t *)c[CODE_Q];
+
+ REC_QR_DEFINE();
+
+ for (; x < xend; x += REC_QR_STRIDE, y += REC_QR_STRIDE,
+ p += REC_QR_STRIDE, q += REC_QR_STRIDE) {
+ LOAD(x, REC_QR_X);
+ LOAD(y, REC_QR_Y);
+
+ XOR_ACC(p, REC_QR_X);
+ XOR_ACC(q, REC_QR_Y);
+
+ /* Save Pxy */
+ COPY(REC_QR_X, REC_QR_T);
+
+ /* Calc X */
+ MUL(mul[MUL_QR_XQ], REC_QR_X); /* X = Q * xqm */
+ XOR(REC_QR_Y, REC_QR_X); /* X = R ^ X */
+ MUL(mul[MUL_QR_X], REC_QR_X); /* X = X * xm */
+ STORE(x, REC_QR_X);
+
+ /* Calc Y */
+ MUL(mul[MUL_QR_YQ], REC_QR_T); /* X = Q * xqm */
+ XOR(REC_QR_Y, REC_QR_T); /* X = R ^ X */
+ MUL(mul[MUL_QR_Y], REC_QR_T); /* X = X * xm */
+ STORE(y, REC_QR_T);
+ }
+}
+
+
+/*
+ * Reconstruct two data columns using QR parity
+ *
+ * @syn_method raidz_syn_qr_abd()
+ * @rec_method raidz_rec_qr_abd()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_qr_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ const size_t y = tgtidx[TARGET_Y];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ const size_t ysize = rm->rm_col[y].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ abd_t *yabd = rm->rm_col[y].rc_abd;
+ abd_t *tabds[2] = { xabd, yabd };
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_Q].rc_abd,
+ rm->rm_col[CODE_R].rc_abd
+ };
+ unsigned coeff[MUL_CNT];
+ raidz_rec_qr_coeff(rm, tgtidx, coeff);
+
+ /*
+ * Check if some of targets is shorter then others
+ * In this case, shorter target needs to be replaced with
+ * new buffer so that syndrome can be calculated.
+ */
+ if (ysize < xsize) {
+ yabd = abd_alloc(xsize, B_FALSE);
+ tabds[1] = yabd;
+ }
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ raidz_zero(yabd, xsize);
+ }
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x || c == y) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 2,
+ raidz_syn_qr_abd);
+ }
+
+ abd_raidz_rec_iterate(cabds, tabds, xsize, 2, raidz_rec_qr_abd, coeff);
+
+ /*
+ * Copy shorter targets back to the original abd buffer
+ */
+ if (ysize < xsize)
+ raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
+
+ raidz_math_end();
+
+ if (ysize < xsize)
+ abd_free(yabd);
+
+
+ return ((1 << CODE_Q) | (1 << CODE_R));
+}
+
+
+/*
+ * Generate P, Q, and R syndromes
+ *
+ * @xc array of pointers to syndrome columns
+ * @dc data column (NULL if missing)
+ * @tsize size of syndrome columns
+ * @dsize size of data column (0 if missing)
+ */
+static void
+raidz_syn_pqr_abd(void **c, const void *dc, const size_t tsize,
+ const size_t dsize)
+{
+ v_t *x = (v_t *)c[TARGET_X];
+ v_t *y = (v_t *)c[TARGET_Y];
+ v_t *z = (v_t *)c[TARGET_Z];
+ const v_t * const yend = y + (tsize / sizeof (v_t));
+ const v_t *d = (const v_t *)dc;
+ const v_t * const dend = d + (dsize / sizeof (v_t));
+
+ SYN_PQR_DEFINE();
+
+ MUL2_SETUP();
+
+ for (; d < dend; d += SYN_STRIDE, x += SYN_STRIDE, y += SYN_STRIDE,
+ z += SYN_STRIDE) {
+ LOAD(d, SYN_PQR_D);
+ P_D_SYNDROME(SYN_PQR_D, SYN_PQR_X, x)
+ Q_D_SYNDROME(SYN_PQR_D, SYN_PQR_X, y);
+ R_D_SYNDROME(SYN_PQR_D, SYN_PQR_X, z);
+ }
+ for (; y < yend; y += SYN_STRIDE, z += SYN_STRIDE) {
+ Q_SYNDROME(SYN_PQR_X, y);
+ R_SYNDROME(SYN_PQR_X, z);
+ }
+}
+
+
+/*
+ * Reconstruct data using PRQ parity and PQR syndromes
+ *
+ * @tc syndrome/result columns
+ * @tsize size of syndrome/result columns
+ * @c parity columns
+ * @mul array of multiplication constants
+ */
+static void
+raidz_rec_pqr_abd(void **t, const size_t tsize, void **c,
+ const unsigned * const mul)
+{
+ v_t *x = (v_t *)t[TARGET_X];
+ v_t *y = (v_t *)t[TARGET_Y];
+ v_t *z = (v_t *)t[TARGET_Z];
+ const v_t * const xend = x + (tsize / sizeof (v_t));
+ const v_t *p = (v_t *)c[CODE_P];
+ const v_t *q = (v_t *)c[CODE_Q];
+ const v_t *r = (v_t *)c[CODE_R];
+
+ REC_PQR_DEFINE();
+
+ for (; x < xend; x += REC_PQR_STRIDE, y += REC_PQR_STRIDE,
+ z += REC_PQR_STRIDE, p += REC_PQR_STRIDE, q += REC_PQR_STRIDE,
+ r += REC_PQR_STRIDE) {
+ LOAD(x, REC_PQR_X);
+ LOAD(y, REC_PQR_Y);
+ LOAD(z, REC_PQR_Z);
+
+ XOR_ACC(p, REC_PQR_X);
+ XOR_ACC(q, REC_PQR_Y);
+ XOR_ACC(r, REC_PQR_Z);
+
+ /* Save Pxyz and Qxyz */
+ COPY(REC_PQR_X, REC_PQR_XS);
+ COPY(REC_PQR_Y, REC_PQR_YS);
+
+ /* Calc X */
+ MUL(mul[MUL_PQR_XP], REC_PQR_X); /* Xp = Pxyz * xp */
+ MUL(mul[MUL_PQR_XQ], REC_PQR_Y); /* Xq = Qxyz * xq */
+ XOR(REC_PQR_Y, REC_PQR_X);
+ MUL(mul[MUL_PQR_XR], REC_PQR_Z); /* Xr = Rxyz * xr */
+ XOR(REC_PQR_Z, REC_PQR_X); /* X = Xp + Xq + Xr */
+ STORE(x, REC_PQR_X);
+
+ /* Calc Y */
+ XOR(REC_PQR_X, REC_PQR_XS); /* Pyz = Pxyz + X */
+ MUL(mul[MUL_PQR_YU], REC_PQR_X); /* Xq = X * upd_q */
+ XOR(REC_PQR_X, REC_PQR_YS); /* Qyz = Qxyz + Xq */
+ COPY(REC_PQR_XS, REC_PQR_X); /* restore Pyz */
+ MUL(mul[MUL_PQR_YP], REC_PQR_X); /* Yp = Pyz * yp */
+ MUL(mul[MUL_PQR_YQ], REC_PQR_YS); /* Yq = Qyz * yq */
+ XOR(REC_PQR_X, REC_PQR_YS); /* Y = Yp + Yq */
+ STORE(y, REC_PQR_YS);
+
+ /* Calc Z */
+ XOR(REC_PQR_XS, REC_PQR_YS); /* Z = Pz = Pyz + Y */
+ STORE(z, REC_PQR_YS);
+ }
+}
+
+
+/*
+ * Reconstruct three data columns using PQR parity
+ *
+ * @syn_method raidz_syn_pqr_abd()
+ * @rec_method raidz_rec_pqr_abd()
+ *
+ * @rm RAIDZ map
+ * @tgtidx array of missing data indexes
+ */
+static raidz_inline int
+raidz_reconstruct_pqr_impl(raidz_map_t *rm, const int *tgtidx)
+{
+ size_t c;
+ size_t dsize;
+ abd_t *dabd;
+ const size_t firstdc = raidz_parity(rm);
+ const size_t ncols = raidz_ncols(rm);
+ const size_t x = tgtidx[TARGET_X];
+ const size_t y = tgtidx[TARGET_Y];
+ const size_t z = tgtidx[TARGET_Z];
+ const size_t xsize = rm->rm_col[x].rc_size;
+ const size_t ysize = rm->rm_col[y].rc_size;
+ const size_t zsize = rm->rm_col[z].rc_size;
+ abd_t *xabd = rm->rm_col[x].rc_abd;
+ abd_t *yabd = rm->rm_col[y].rc_abd;
+ abd_t *zabd = rm->rm_col[z].rc_abd;
+ abd_t *tabds[] = { xabd, yabd, zabd };
+ abd_t *cabds[] = {
+ rm->rm_col[CODE_P].rc_abd,
+ rm->rm_col[CODE_Q].rc_abd,
+ rm->rm_col[CODE_R].rc_abd
+ };
+ unsigned coeff[MUL_CNT];
+ raidz_rec_pqr_coeff(rm, tgtidx, coeff);
+
+ /*
+ * Check if some of targets is shorter then others
+ * In this case, shorter target needs to be replaced with
+ * new buffer so that syndrome can be calculated.
+ */
+ if (ysize < xsize) {
+ yabd = abd_alloc(xsize, B_FALSE);
+ tabds[1] = yabd;
+ }
+ if (zsize < xsize) {
+ zabd = abd_alloc(xsize, B_FALSE);
+ tabds[2] = zabd;
+ }
+
+ raidz_math_begin();
+
+ /* Start with first data column if present */
+ if (firstdc != x) {
+ raidz_copy(xabd, rm->rm_col[firstdc].rc_abd, xsize);
+ raidz_copy(yabd, rm->rm_col[firstdc].rc_abd, xsize);
+ raidz_copy(zabd, rm->rm_col[firstdc].rc_abd, xsize);
+ } else {
+ raidz_zero(xabd, xsize);
+ raidz_zero(yabd, xsize);
+ raidz_zero(zabd, xsize);
+ }
+
+ /* generate q_syndrome */
+ for (c = firstdc+1; c < ncols; c++) {
+ if (c == x || c == y || c == z) {
+ dabd = NULL;
+ dsize = 0;
+ } else {
+ dabd = rm->rm_col[c].rc_abd;
+ dsize = rm->rm_col[c].rc_size;
+ }
+
+ abd_raidz_gen_iterate(tabds, dabd, xsize, dsize, 3,
+ raidz_syn_pqr_abd);
+ }
+
+ abd_raidz_rec_iterate(cabds, tabds, xsize, 3, raidz_rec_pqr_abd, coeff);
+
+ /*
+ * Copy shorter targets back to the original abd buffer
+ */
+ if (ysize < xsize)
+ raidz_copy(rm->rm_col[y].rc_abd, yabd, ysize);
+ if (zsize < xsize)
+ raidz_copy(rm->rm_col[z].rc_abd, zabd, zsize);
+
+ raidz_math_end();
+
+ if (ysize < xsize)
+ abd_free(yabd);
+ if (zsize < xsize)
+ abd_free(zabd);
+
+ return ((1 << CODE_P) | (1 << CODE_Q) | (1 << CODE_R));
+}
+
+#endif /* _VDEV_RAIDZ_MATH_IMPL_H */
diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz_math_scalar.c b/usr/src/uts/common/fs/zfs/vdev_raidz_math_scalar.c
new file mode 100644
index 0000000000..cd742e146c
--- /dev/null
+++ b/usr/src/uts/common/fs/zfs/vdev_raidz_math_scalar.c
@@ -0,0 +1,337 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
+ */
+
+#include <sys/vdev_raidz_impl.h>
+
+/*
+ * Provide native CPU scalar routines.
+ * Support 32bit and 64bit CPUs.
+ */
+#if ((~(0x0ULL)) >> 24) == 0xffULL
+#define ELEM_SIZE 4
+typedef uint32_t iv_t;
+#elif ((~(0x0ULL)) >> 56) == 0xffULL
+#define ELEM_SIZE 8
+typedef uint64_t iv_t;
+#endif
+
+/*
+ * Vector type used in scalar implementation
+ *
+ * The union is expected to be of native CPU register size. Since addition
+ * uses XOR operation, it can be performed an all byte elements at once.
+ * Multiplication requires per byte access.
+ */
+typedef union {
+ iv_t e;
+ uint8_t b[ELEM_SIZE];
+} v_t;
+
+/*
+ * Precomputed lookup tables for multiplication by a constant
+ *
+ * Reconstruction path requires multiplication by a constant factors. Instead of
+ * performing two step lookup (log & exp tables), a direct lookup can be used
+ * instead. Multiplication of element 'a' by a constant 'c' is obtained as:
+ *
+ * r = vdev_raidz_mul_lt[c_log][a];
+ *
+ * where c_log = vdev_raidz_log2[c]. Log of coefficient factors is used because
+ * they are faster to obtain while solving the syndrome equations.
+ *
+ * PERFORMANCE NOTE:
+ * Even though the complete lookup table uses 64kiB, only relatively small
+ * portion of it is used at the same time. Following shows number of accessed
+ * bytes for different cases:
+ * - 1 failed disk: 256B (1 mul. coefficient)
+ * - 2 failed disks: 512B (2 mul. coefficients)
+ * - 3 failed disks: 1536B (6 mul. coefficients)
+ *
+ * Size of actually accessed lookup table regions is only larger for
+ * reconstruction of 3 failed disks, when compared to traditional log/exp
+ * method. But since the result is obtained in one lookup step performance is
+ * doubled.
+ */
+static uint8_t vdev_raidz_mul_lt[256][256] __attribute__((aligned(256)));
+
+static void
+raidz_init_scalar(void)
+{
+ int c, i;
+ for (c = 0; c < 256; c++)
+ for (i = 0; i < 256; i++)
+ vdev_raidz_mul_lt[c][i] = gf_mul(c, i);
+
+}
+
+#define PREFETCHNTA(ptr, offset) {}
+#define PREFETCH(ptr, offset) {}
+
+#define XOR_ACC(src, acc) acc.e ^= ((v_t *)src)[0].e
+#define XOR(src, acc) acc.e ^= src.e
+#define ZERO(acc) acc.e = 0
+#define COPY(src, dst) dst = src
+#define LOAD(src, val) val = ((v_t *)src)[0]
+#define STORE(dst, val) ((v_t *)dst)[0] = val
+
+/*
+ * Constants used for optimized multiplication by 2.
+ */
+static const struct {
+ iv_t mod;
+ iv_t mask;
+ iv_t msb;
+} scalar_mul2_consts = {
+#if ELEM_SIZE == 8
+ .mod = 0x1d1d1d1d1d1d1d1dULL,
+ .mask = 0xfefefefefefefefeULL,
+ .msb = 0x8080808080808080ULL,
+#else
+ .mod = 0x1d1d1d1dULL,
+ .mask = 0xfefefefeULL,
+ .msb = 0x80808080ULL,
+#endif
+};
+
+#define MUL2_SETUP() {}
+
+#define MUL2(a) \
+{ \
+ iv_t _mask; \
+ \
+ _mask = (a).e & scalar_mul2_consts.msb; \
+ _mask = (_mask << 1) - (_mask >> 7); \
+ (a).e = ((a).e << 1) & scalar_mul2_consts.mask; \
+ (a).e = (a).e ^ (_mask & scalar_mul2_consts.mod); \
+}
+
+#define MUL4(a) \
+{ \
+ MUL2(a); \
+ MUL2(a); \
+}
+
+#define MUL(c, a) \
+{ \
+ const uint8_t *mul_lt = vdev_raidz_mul_lt[c]; \
+ switch (ELEM_SIZE) { \
+ case 8: \
+ a.b[7] = mul_lt[a.b[7]]; \
+ a.b[6] = mul_lt[a.b[6]]; \
+ a.b[5] = mul_lt[a.b[5]]; \
+ a.b[4] = mul_lt[a.b[4]]; \
+ /* falls through */ \
+ case 4: \
+ a.b[3] = mul_lt[a.b[3]]; \
+ a.b[2] = mul_lt[a.b[2]]; \
+ a.b[1] = mul_lt[a.b[1]]; \
+ a.b[0] = mul_lt[a.b[0]]; \
+ break; \
+ } \
+}
+
+#define raidz_math_begin() {}
+#define raidz_math_end() {}
+
+#define SYN_STRIDE 1
+
+#define ZERO_DEFINE() v_t d0
+#define ZERO_STRIDE 1
+#define ZERO_D d0
+
+#define COPY_DEFINE() v_t d0
+#define COPY_STRIDE 1
+#define COPY_D d0
+
+#define ADD_DEFINE() v_t d0
+#define ADD_STRIDE 1
+#define ADD_D d0
+
+#define MUL_DEFINE() v_t d0
+#define MUL_STRIDE 1
+#define MUL_D d0
+
+#define GEN_P_STRIDE 1
+#define GEN_P_DEFINE() v_t p0
+#define GEN_P_P p0
+
+#define GEN_PQ_STRIDE 1
+#define GEN_PQ_DEFINE() v_t d0, c0
+#define GEN_PQ_D d0
+#define GEN_PQ_C c0
+
+#define GEN_PQR_STRIDE 1
+#define GEN_PQR_DEFINE() v_t d0, c0
+#define GEN_PQR_D d0
+#define GEN_PQR_C c0
+
+#define SYN_Q_DEFINE() v_t d0, x0
+#define SYN_Q_D d0
+#define SYN_Q_X x0
+
+
+#define SYN_R_DEFINE() v_t d0, x0
+#define SYN_R_D d0
+#define SYN_R_X x0
+
+
+#define SYN_PQ_DEFINE() v_t d0, x0
+#define SYN_PQ_D d0
+#define SYN_PQ_X x0
+
+
+#define REC_PQ_STRIDE 1
+#define REC_PQ_DEFINE() v_t x0, y0, t0
+#define REC_PQ_X x0
+#define REC_PQ_Y y0
+#define REC_PQ_T t0
+
+
+#define SYN_PR_DEFINE() v_t d0, x0
+#define SYN_PR_D d0
+#define SYN_PR_X x0
+
+#define REC_PR_STRIDE 1
+#define REC_PR_DEFINE() v_t x0, y0, t0
+#define REC_PR_X x0
+#define REC_PR_Y y0
+#define REC_PR_T t0
+
+
+#define SYN_QR_DEFINE() v_t d0, x0
+#define SYN_QR_D d0
+#define SYN_QR_X x0
+
+
+#define REC_QR_STRIDE 1
+#define REC_QR_DEFINE() v_t x0, y0, t0
+#define REC_QR_X x0
+#define REC_QR_Y y0
+#define REC_QR_T t0
+
+
+#define SYN_PQR_DEFINE() v_t d0, x0
+#define SYN_PQR_D d0
+#define SYN_PQR_X x0
+
+#define REC_PQR_STRIDE 1
+#define REC_PQR_DEFINE() v_t x0, y0, z0, xs0, ys0
+#define REC_PQR_X x0
+#define REC_PQR_Y y0
+#define REC_PQR_Z z0
+#define REC_PQR_XS xs0
+#define REC_PQR_YS ys0
+
+#include "vdev_raidz_math_impl.h"
+
+DEFINE_GEN_METHODS(scalar);
+DEFINE_REC_METHODS(scalar);
+
+boolean_t
+raidz_will_scalar_work(void)
+{
+ return (B_TRUE); /* always */
+}
+
+const raidz_impl_ops_t vdev_raidz_scalar_impl = {
+ .init = raidz_init_scalar,
+ .fini = NULL,
+ .gen = RAIDZ_GEN_METHODS(scalar),
+ .rec = RAIDZ_REC_METHODS(scalar),
+ .is_supported = &raidz_will_scalar_work,
+ .name = "scalar"
+};
+
+/* Powers of 2 in the RAID-Z Galois field. */
+const uint8_t vdev_raidz_pow2[256] __attribute__((aligned(256))) = {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26,
+ 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9,
+ 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0,
+ 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35,
+ 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23,
+ 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0,
+ 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1,
+ 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc,
+ 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0,
+ 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f,
+ 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2,
+ 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88,
+ 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce,
+ 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93,
+ 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc,
+ 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9,
+ 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54,
+ 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa,
+ 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73,
+ 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e,
+ 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff,
+ 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4,
+ 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41,
+ 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e,
+ 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6,
+ 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef,
+ 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09,
+ 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5,
+ 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16,
+ 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83,
+ 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01
+};
+
+/* Logs of 2 in the RAID-Z Galois field. */
+const uint8_t vdev_raidz_log2[256] __attribute__((aligned(256))) = {
+ 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6,
+ 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b,
+ 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81,
+ 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71,
+ 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21,
+ 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45,
+ 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9,
+ 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6,
+ 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd,
+ 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88,
+ 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd,
+ 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40,
+ 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e,
+ 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d,
+ 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b,
+ 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57,
+ 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d,
+ 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18,
+ 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c,
+ 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e,
+ 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd,
+ 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61,
+ 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e,
+ 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2,
+ 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76,
+ 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6,
+ 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa,
+ 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a,
+ 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51,
+ 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7,
+ 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8,
+ 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf,
+};
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index 47c4a190cf..d06cb875cf 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -26,6 +26,7 @@
* Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright 2019 Joyent, Inc.
* Copyright 2020 Joshua M. Clulow <josh@sysmgr.org>
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
/* Portions Copyright 2010 Robert Milkowski */
@@ -2229,18 +2230,34 @@ zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr)
* Our count is maintained in the vfs structure, but the
* number is off by 1 to indicate a hold on the vfs
* structure itself.
- *
- * The '.zfs' directory maintains a reference of its
- * own, and any active references underneath are
- * reflected in the vnode count.
*/
- if (zfsvfs->z_ctldir == NULL) {
- if (vfsp->vfs_count > 1)
- return (SET_ERROR(EBUSY));
- } else {
- if (vfsp->vfs_count > 2 ||
- zfsvfs->z_ctldir->v_count > 1)
- return (SET_ERROR(EBUSY));
+ boolean_t draining;
+ uint_t thresh = 1;
+
+ /*
+ * The '.zfs' directory maintains a reference of its own, and
+ * any active references underneath are reflected in the vnode
+ * count. Allow one additional reference for it.
+ */
+ if (zfsvfs->z_ctldir != NULL)
+ thresh++;
+
+ /*
+ * If it's running, the asynchronous unlinked drain task needs
+ * to be stopped before the number of active vnodes can be
+ * reliably checked.
+ */
+ draining = zfsvfs->z_draining;
+ if (draining)
+ zfs_unlinked_drain_stop_wait(zfsvfs);
+
+ if (vfsp->vfs_count > thresh || (zfsvfs->z_ctldir != NULL &&
+ zfsvfs->z_ctldir->v_count > 1)) {
+ if (draining) {
+ /* If it was draining, restart the task */
+ zfs_unlinked_drain(zfsvfs);
+ }
+ return (SET_ERROR(EBUSY));
}
}
diff --git a/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h b/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h
index a8df3df932..ce0cc20879 100644
--- a/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h
+++ b/usr/src/uts/common/io/ixgbe/ixgbe_osdep.h
@@ -113,7 +113,7 @@ boolean_t ixgbe_removed(struct ixgbe_hw *);
#ifdef _BIG_ENDIAN
#define IXGBE_CPU_TO_LE16 BSWAP_16
#define IXGBE_CPU_TO_LE32 BSWAP_32
-#define IXGBE_LE32_TO_CPUS BSWAP_32
+#define IXGBE_LE32_TO_CPUS(x) *(x) = BSWAP_32(*(x))
#define IXGBE_CPU_TO_BE16(x) (x)
#define IXGBE_CPU_TO_BE32(x) (x)
#define IXGBE_BE32_TO_CPU(x) (x)
diff --git a/usr/src/uts/common/sys/sysevent.h b/usr/src/uts/common/sys/sysevent.h
index 392b426977..c2be00ad27 100644
--- a/usr/src/uts/common/sys/sysevent.h
+++ b/usr/src/uts/common/sys/sysevent.h
@@ -73,7 +73,7 @@ extern "C" {
#define SE_KERN_PUB "kern:"
#define SUNW_KERN_PUB SUNW_VENDOR ":" SE_KERN_PUB
#define SUNW_USR_PUB SUNW_VENDOR ":" SE_USR_PUB
-#define ILLUMOS_KERN_PUB ILLUMOS_VENDOR":"SE_KERN_PUB
+#define ILLUMOS_KERN_PUB ILLUMOS_VENDOR ":" SE_KERN_PUB
/*
* Event header and attribute value limits
diff --git a/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c b/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
index 634575427e..ec338b1cdd 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c
@@ -12,6 +12,7 @@
/*
* Copyright 2015 Pluribus Networks Inc.
* Copyright 2019 Joyent, Inc.
+ * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
*/
#include <sys/types.h>
@@ -65,6 +66,7 @@
static kmutex_t vmmdev_mtx;
static dev_info_t *vmmdev_dip;
static hma_reg_t *vmmdev_hma_reg;
+static uint_t vmmdev_hma_ref;
static sdev_plugin_hdl_t vmmdev_sdev_hdl;
static kmutex_t vmm_mtx;
@@ -1322,6 +1324,56 @@ vmm_lookup(const char *name)
return (sc);
}
+/*
+ * Acquire an HMA registration if not already held.
+ */
+static boolean_t
+vmm_hma_acquire(void)
+{
+ ASSERT(MUTEX_NOT_HELD(&vmm_mtx));
+
+ mutex_enter(&vmmdev_mtx);
+
+ if (vmmdev_hma_reg == NULL) {
+ VERIFY3U(vmmdev_hma_ref, ==, 0);
+ vmmdev_hma_reg = hma_register(vmmdev_hvm_name);
+ if (vmmdev_hma_reg == NULL) {
+ cmn_err(CE_WARN, "%s HMA registration failed.",
+ vmmdev_hvm_name);
+ mutex_exit(&vmmdev_mtx);
+ return (B_FALSE);
+ }
+ }
+
+ vmmdev_hma_ref++;
+
+ mutex_exit(&vmmdev_mtx);
+
+ return (B_TRUE);
+}
+
+/*
+ * Release the HMA registration if held and there are no remaining VMs.
+ */
+static void
+vmm_hma_release(void)
+{
+ ASSERT(MUTEX_NOT_HELD(&vmm_mtx));
+
+ mutex_enter(&vmmdev_mtx);
+
+ VERIFY3U(vmmdev_hma_ref, !=, 0);
+
+ vmmdev_hma_ref--;
+
+ if (vmmdev_hma_ref == 0) {
+ VERIFY(vmmdev_hma_reg != NULL);
+ hma_unregister(vmmdev_hma_reg);
+ vmmdev_hma_reg = NULL;
+ }
+ mutex_exit(&vmmdev_mtx);
+}
+
static int
vmmdev_do_vm_create(char *name, cred_t *cr)
{
@@ -1333,11 +1385,15 @@ vmmdev_do_vm_create(char *name, cred_t *cr)
return (EINVAL);
}
+ if (!vmm_hma_acquire())
+ return (ENXIO);
+
mutex_enter(&vmm_mtx);
- /* Look for duplicates names */
+ /* Look for duplicate names */
if (vmm_lookup(name) != NULL) {
mutex_exit(&vmm_mtx);
+ vmm_hma_release();
return (EEXIST);
}
@@ -1347,6 +1403,7 @@ vmmdev_do_vm_create(char *name, cred_t *cr)
sc = list_next(&vmm_list, sc)) {
if (sc->vmm_zone == curzone) {
mutex_exit(&vmm_mtx);
+ vmm_hma_release();
return (EINVAL);
}
}
@@ -1397,6 +1454,7 @@ fail:
ddi_soft_state_free(vmm_statep, minor);
}
mutex_exit(&vmm_mtx);
+ vmm_hma_release();
return (error);
}
@@ -1685,13 +1743,16 @@ done:
}
static int
-vmm_do_vm_destroy_locked(vmm_softc_t *sc, boolean_t clean_zsd)
+vmm_do_vm_destroy_locked(vmm_softc_t *sc, boolean_t clean_zsd,
+ boolean_t *hma_release)
{
dev_info_t *pdip = ddi_get_parent(vmmdev_dip);
minor_t minor;
ASSERT(MUTEX_HELD(&vmm_mtx));
+ *hma_release = B_FALSE;
+
if (clean_zsd) {
vmm_zsd_rem_vm(sc);
}
@@ -1714,6 +1775,7 @@ vmm_do_vm_destroy_locked(vmm_softc_t *sc, boolean_t clean_zsd)
vm_destroy(sc->vmm_vm);
ddi_soft_state_free(vmm_statep, minor);
id_free(vmm_minors, minor);
+ *hma_release = B_TRUE;
}
(void) devfs_clean(pdip, NULL, DV_CLEAN_FORCE);
@@ -1723,12 +1785,16 @@ vmm_do_vm_destroy_locked(vmm_softc_t *sc, boolean_t clean_zsd)
int
vmm_do_vm_destroy(vmm_softc_t *sc, boolean_t clean_zsd)
{
+ boolean_t hma_release = B_FALSE;
int err;
mutex_enter(&vmm_mtx);
- err = vmm_do_vm_destroy_locked(sc, clean_zsd);
+ err = vmm_do_vm_destroy_locked(sc, clean_zsd, &hma_release);
mutex_exit(&vmm_mtx);
+ if (hma_release)
+ vmm_hma_release();
+
return (err);
}
@@ -1736,6 +1802,7 @@ vmm_do_vm_destroy(vmm_softc_t *sc, boolean_t clean_zsd)
static int
vmmdev_do_vm_destroy(const char *name, cred_t *cr)
{
+ boolean_t hma_release = B_FALSE;
vmm_softc_t *sc;
int err;
@@ -1756,13 +1823,16 @@ vmmdev_do_vm_destroy(const char *name, cred_t *cr)
mutex_exit(&vmm_mtx);
return (EPERM);
}
- err = vmm_do_vm_destroy_locked(sc, B_TRUE);
+ err = vmm_do_vm_destroy_locked(sc, B_TRUE, &hma_release);
+
mutex_exit(&vmm_mtx);
+ if (hma_release)
+ vmm_hma_release();
+
return (err);
}
-
static int
vmm_open(dev_t *devp, int flag, int otyp, cred_t *credp)
{
@@ -1799,6 +1869,7 @@ vmm_close(dev_t dev, int flag, int otyp, cred_t *credp)
{
minor_t minor;
vmm_softc_t *sc;
+ boolean_t hma_release = B_FALSE;
minor = getminor(dev);
if (minor == VMM_CTL_MINOR)
@@ -1814,14 +1885,22 @@ vmm_close(dev_t dev, int flag, int otyp, cred_t *credp)
VERIFY(sc->vmm_is_open);
sc->vmm_is_open = B_FALSE;
+ /*
+ * If this VM was destroyed while the vmm device was open, then
+ * clean it up now that it is closed.
+ */
if (sc->vmm_flags & VMM_DESTROY) {
list_remove(&vmm_destroy_list, sc);
vm_destroy(sc->vmm_vm);
ddi_soft_state_free(vmm_statep, minor);
id_free(vmm_minors, minor);
+ hma_release = B_TRUE;
}
mutex_exit(&vmm_mtx);
+ if (hma_release)
+ vmm_hma_release();
+
return (0);
}
@@ -2076,12 +2155,18 @@ vmm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
vmm_sol_glue_init();
vmm_arena_init();
+ /*
+ * Perform temporary HMA registration to determine if the system
+ * is capable.
+ */
if ((reg = hma_register(vmmdev_hvm_name)) == NULL) {
goto fail;
} else if (vmm_mod_load() != 0) {
goto fail;
}
vmm_loaded = B_TRUE;
+ hma_unregister(reg);
+ reg = NULL;
/* Create control node. Other nodes will be created on demand. */
if (ddi_create_minor_node(dip, "ctl", S_IFCHR,
@@ -2096,7 +2181,6 @@ vmm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
}
ddi_report_dev(dip);
- vmmdev_hma_reg = reg;
vmmdev_sdev_hdl = sph;
vmmdev_dip = dip;
mutex_exit(&vmmdev_mtx);
@@ -2153,8 +2237,7 @@ vmm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
vmmdev_dip = NULL;
VERIFY0(vmm_mod_unload());
- hma_unregister(vmmdev_hma_reg);
- vmmdev_hma_reg = NULL;
+ VERIFY3U(vmmdev_hma_reg, ==, NULL);
vmm_arena_fini();
vmm_sol_glue_cleanup();
diff --git a/usr/src/uts/i86pc/ppt/Makefile b/usr/src/uts/i86pc/ppt/Makefile
index 7c41368efd..7c10482e98 100644
--- a/usr/src/uts/i86pc/ppt/Makefile
+++ b/usr/src/uts/i86pc/ppt/Makefile
@@ -44,8 +44,8 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
#
ALL_BUILDS = $(ALL_BUILDSONLY64)
DEF_BUILDS = $(DEF_BUILDSONLY64)
-PRE_INC_PATH = -I$(COMPAT)/freebsd -I$(COMPAT)/freebsd/amd64 \
- -I$(CONTRIB)/freebsd -I$(CONTRIB)/freebsd/amd64
+PRE_INC_PATH = -I$(COMPAT)/bhyve -I$(COMPAT)/bhyve/amd64 \
+ -I$(CONTRIB)/bhyve -I$(CONTRIB)/bhyve/amd64
INC_PATH += -I$(UTSBASE)/i86pc/io/vmm -I$(UTSBASE)/i86pc/io/vmm/io
AS_INC_PATH += -I$(UTSBASE)/i86pc/io/vmm -I$(OBJS_DIR)
diff --git a/usr/src/uts/i86pc/vmm/Makefile b/usr/src/uts/i86pc/vmm/Makefile
index c55abf6090..e7f07c4c4e 100644
--- a/usr/src/uts/i86pc/vmm/Makefile
+++ b/usr/src/uts/i86pc/vmm/Makefile
@@ -56,8 +56,8 @@ $(OBJS_DIR)/vmx.o := SMOFF += deref_check
ALL_BUILDS = $(ALL_BUILDSONLY64)
DEF_BUILDS = $(DEF_BUILDSONLY64)
-PRE_INC_PATH = -I$(COMPAT)/freebsd -I$(COMPAT)/freebsd/amd64 \
- -I$(CONTRIB)/freebsd -I$(CONTRIB)/freebsd/amd64
+PRE_INC_PATH = -I$(COMPAT)/bhyve -I$(COMPAT)/bhyve/amd64 \
+ -I$(CONTRIB)/bhyve -I$(CONTRIB)/bhyve/amd64
INC_PATH += -I$(UTSBASE)/i86pc/io/vmm -I$(UTSBASE)/i86pc/io/vmm/io
AS_INC_PATH += -I$(UTSBASE)/i86pc/io/vmm -I$(OBJS_DIR)
diff --git a/usr/src/uts/req.flg b/usr/src/uts/req.flg
index 15085a486d..76b8de8999 100644
--- a/usr/src/uts/req.flg
+++ b/usr/src/uts/req.flg
@@ -38,7 +38,6 @@ echo_file usr/src/Makefile
# For full builds (open and closed), we want both etc/certs and
# etc/keys. For an open source build, there's no etc/keys directory.
-find_files "s.*" usr/contrib/freebsd
find_files "s.*" usr/src/cmd/cmd-crypto/etc
find_files "s.*" usr/src/common/acl
find_files "s.*" usr/src/common/atomic
@@ -58,5 +57,6 @@ find_files "s.*" usr/src/common/smbios
find_files "s.*" usr/src/common/tsol
find_files "s.*" usr/src/common/util
find_files "s.*" usr/src/common/zfs
-find_files "s.*" usr/src/compat/freebsd
+find_files "s.*" usr/src/compat/bhyve
+find_files "s.*" usr/src/contrib/bhyve
find_files "s.*" usr/src/psm/promif
diff --git a/usr/src/uts/sun/io/zs_async.c b/usr/src/uts/sun/io/zs_async.c
index 6470434f6c..afdf563c4f 100644
--- a/usr/src/uts/sun/io/zs_async.c
+++ b/usr/src/uts/sun/io/zs_async.c
@@ -225,7 +225,7 @@ ushort_t zshiwat[NSPEED] = {
*/
#define ZSA_GETBLOCK(zs, allocbcount) \
{ \
- register int n = zsa_rstandby; \
+ int n = zsa_rstandby; \
while (--n >= 0 && allocbcount > 0) { \
if (!za->za_rstandby[n]) { \
if ((za->za_rstandby[n] = allocb(ZSA_RCV_SIZE, \
@@ -243,7 +243,7 @@ ushort_t zshiwat[NSPEED] = {
if (za->za_ttycommon.t_cflag & CRTSXOFF) { \
mutex_enter(zs->zs_excl_hi); \
if (!(zs->zs_wreg[5] & ZSWR5_RTS)) { \
- register int usedcnt = 0; \
+ int usedcnt = 0; \
for (n = 0; n < zsa_rstandby; n++) \
if (!za->za_rstandby[n]) \
usedcnt++; \
@@ -260,7 +260,7 @@ ushort_t zshiwat[NSPEED] = {
*/
#define ZSA_ALLOCB(mp) \
{ \
- register int n = zsa_rstandby; \
+ int n = zsa_rstandby; \
while (--n >= 0) { \
if ((mp = za->za_rstandby[n]) != NULL) { \
za->za_rstandby[n] = NULL; \
@@ -274,7 +274,7 @@ ushort_t zshiwat[NSPEED] = {
cmn_err(CE_WARN, "zs%d: message lost\n", \
UNIT(za->za_dev)); \
} else if (zs->zs_wreg[5] & ZSWR5_RTS) { \
- register int usedcnt = 0; \
+ int usedcnt = 0; \
for (n = 0; n < zsa_rstandby; n++) \
if (!za->za_rstandby[n]) \
usedcnt++; \
@@ -301,7 +301,7 @@ ushort_t zshiwat[NSPEED] = {
*/
#define ZSA_PUTQ(mp) \
{ \
- register int wptr, rptr; \
+ int wptr, rptr; \
wptr = za->za_rdone_wptr; \
rptr = za->za_rdone_rptr; \
za->za_rdone[wptr] = mp; \
@@ -321,7 +321,7 @@ ushort_t zshiwat[NSPEED] = {
*/
#define ZSA_KICK_RCV \
{ \
- register mblk_t *mp = za->za_rcvblk; \
+ mblk_t *mp = za->za_rcvblk; \
if (mp) { \
if (zs->zs_rd_cur) { /* M_DATA */ \
mp->b_wptr = zs->zs_rd_cur; \
@@ -364,7 +364,7 @@ ushort_t zshiwat[NSPEED] = {
*/
#define ZSA_FLUSHQ \
{ \
- register mblk_t *tmp; \
+ mblk_t *tmp; \
for (;;) { \
ZSA_GETQ(tmp); \
if (!(tmp)) \
@@ -412,7 +412,7 @@ int zsa_h_log_n[40];
#define zsa_h_log_clear \
{ \
- register char *p; \
+ char *p; \
for (p = &zsa_h_log[zs->zs_unit][ZSA_H_LOG_MAX]; \
p >= &zsa_h_log[zs->zs_unit][0]; /* null */) \
*p-- = '\0'; \
@@ -498,8 +498,7 @@ static int zsa_resume(struct zscom *zs);
static void
zsa_null(struct zscom *zs)
{
- /* LINTED */
- register short c;
+ short c;
SCC_WRITE0(ZSWR0_RESET_TXINT);
SCC_WRITE0(ZSWR0_RESET_STATUS);
@@ -542,8 +541,8 @@ static void zsa_reioctl(void *);
static void zsa_ioctl(struct asyncline *za, queue_t *q, mblk_t *mp);
static void zsa_program(struct asyncline *za, int setibaud);
static void zsa_start(struct zscom *zs);
-static void zsa_kick_rcv(void *);
-static void zsa_callback(void *);
+static void zsa_kick_rcv(void *);
+static void zsa_callback(void *);
static void zsa_set_za_rcv_flags_mask(struct asyncline *za);
int zsgetspeed(dev_t dev);
@@ -554,9 +553,9 @@ int
zsc_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg,
void **result)
{
- register dev_t dev = (dev_t)arg;
- register int unit, error;
- register struct zscom *zs;
+ dev_t dev = (dev_t)arg;
+ int unit, error;
+ struct zscom *zs;
if ((unit = UNIT(dev)) >= nzs)
return (DDI_FAILURE);
@@ -716,12 +715,12 @@ zsa_init(struct zscom *zs)
static int
zsa_open(queue_t *rq, dev_t *dev, int flag, int sflag, cred_t *cr)
{
- register struct zscom *zs;
- register struct asyncline *za;
- register int speed, unit;
+ struct zscom *zs;
+ struct asyncline *za;
+ int speed, unit;
struct termios *termiosp;
int len;
- register int allocbcount = zsa_rstandby;
+ int allocbcount = zsa_rstandby;
boolean_t set_zsoptinit = B_FALSE;
unit = UNIT(*dev);
@@ -1205,10 +1204,10 @@ out:
static void
zsa_wput(queue_t *q, mblk_t *mp)
{
- register struct asyncline *za;
- register struct zscom *zs;
- register struct copyresp *resp;
- register mblk_t *bp = NULL;
+ struct asyncline *za;
+ struct zscom *zs;
+ struct copyresp *resp;
+ mblk_t *bp = NULL;
int error;
struct iocblk *iocp;
@@ -1321,7 +1320,7 @@ zsa_wput(queue_t *q, mblk_t *mp)
freemsg(mp->b_cont);
mp->b_cont = NULL;
}
- if (za->za_pps == NULL) {
+ if (za->za_pps == 0) {
mp->b_datap->db_type = M_IOCNAK;
iocp->ioc_error = ENXIO;
ZSA_QREPLY(q, mp);
@@ -1640,9 +1639,9 @@ zsa_rsrv(queue_t *q)
static void
zsa_txint(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register uchar_t *wr_cur;
- register uchar_t s0;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ uchar_t *wr_cur;
+ uchar_t s0;
s0 = SCC_READ0();
@@ -1701,8 +1700,8 @@ zsa_txint(struct zscom *zs)
static void
zsa_xsint(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register uchar_t s0, x0;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ uchar_t s0, x0;
s0 = SCC_READ0();
ZSA_R0_LOG(s0);
@@ -1833,12 +1832,12 @@ zsa_xsint(struct zscom *zs)
static void
zsa_rxint(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register uchar_t c;
- register uchar_t *rd_cur = zs->zs_rd_cur;
- register uchar_t *rd_lim = zs->zs_rd_lim;
- register mblk_t *bp;
- register uint_t fm = za->za_rcv_flags_mask;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ uchar_t c;
+ uchar_t *rd_cur = zs->zs_rd_cur;
+ uchar_t *rd_lim = zs->zs_rd_lim;
+ mblk_t *bp;
+ uint_t fm = za->za_rcv_flags_mask;
#ifdef ZSA_DEBUG
@@ -1956,12 +1955,12 @@ zsa_rxint(struct zscom *zs)
static void
zsa_srint(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register short s1;
- register uchar_t c;
- register uchar_t c1;
- register mblk_t *bp = za->za_rcvblk;
- register uchar_t *rd_cur = zs->zs_rd_cur;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ short s1;
+ uchar_t c;
+ uchar_t c1;
+ mblk_t *bp = za->za_rcvblk;
+ uchar_t *rd_cur = zs->zs_rd_cur;
SCC_READ(1, s1);
if (s1 & (ZSRR1_FE | ZSRR1_PE | ZSRR1_DO)) {
@@ -2080,17 +2079,17 @@ zsa_srint(struct zscom *zs)
static int
zsa_softint(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register uchar_t r0;
- register uchar_t za_kick_active;
- register int m_error;
- register int allocbcount = 0;
- register int do_ttycommon_qfull = 0;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ uchar_t r0;
+ uchar_t za_kick_active;
+ int m_error;
+ int allocbcount = 0;
+ int do_ttycommon_qfull = 0;
boolean_t hangup = B_FALSE, unhangup = B_FALSE;
boolean_t m_break = B_FALSE, wakeup = B_FALSE;
- register queue_t *q;
- register mblk_t *bp;
- register mblk_t *head = NULL, *tail = NULL;
+ queue_t *q;
+ mblk_t *bp;
+ mblk_t *head = NULL, *tail = NULL;
mutex_enter(zs->zs_excl);
if (zs->zs_suspended || (zs->zs_flags & ZS_CLOSED)) {
@@ -2351,10 +2350,10 @@ zsa_softint(struct zscom *zs)
static void
zsa_start(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register int cc;
- register queue_t *q;
- register mblk_t *bp;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ int cc;
+ queue_t *q;
+ mblk_t *bp;
uchar_t *rptr, *wptr;
/*
@@ -2501,8 +2500,8 @@ zsa_start_transmit:
* so we need to explicitly mask before transmitting
*/
if ((za->za_ttycommon.t_cflag & CSIZE) == CS5) {
- register unsigned char *p = rptr;
- register int cnt = cc;
+ unsigned char *p = rptr;
+ int cnt = cc;
while (cnt--)
*p++ &= (unsigned char) 0x1f;
@@ -2741,11 +2740,11 @@ zsa_reioctl(void *arg)
static void
zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
{
- register struct zscom *zs = za->za_common;
- register struct iocblk *iocp;
- register unsigned datasize;
+ struct zscom *zs = za->za_common;
+ struct iocblk *iocp;
+ unsigned datasize;
int error;
- register mblk_t *tmp;
+ mblk_t *tmp;
if (za->za_ttycommon.t_iocpending != NULL) {
/*
@@ -2934,7 +2933,7 @@ zsa_ioctl(struct asyncline *za, queue_t *wq, mblk_t *mp)
static int
dmtozs(int bits)
{
- register int b = 0;
+ int b = 0;
if (bits & TIOCM_CAR)
b |= ZSRR0_CD;
@@ -2950,7 +2949,7 @@ dmtozs(int bits)
static int
zstodm(int bits)
{
- register int b;
+ int b;
b = 0;
if (bits & ZSRR0_CD)
@@ -2972,9 +2971,9 @@ zstodm(int bits)
static void
zsa_program(struct asyncline *za, int setibaud)
{
- register struct zscom *zs = za->za_common;
- register struct zs_prog *zspp;
- register int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
+ struct zscom *zs = za->za_common;
+ struct zs_prog *zspp;
+ int wr3, wr4, wr5, wr15, speed, baudrate, flags = 0;
if ((baudrate = SPEED(za->za_ttycommon.t_cflag)) == 0) {
/*
@@ -3129,9 +3128,9 @@ zsa_program(struct asyncline *za, int setibaud)
int
zsgetspeed(dev_t dev)
{
- register struct zscom *zs;
- register int uspeed, zspeed;
- register uchar_t rr;
+ struct zscom *zs;
+ int uspeed, zspeed;
+ uchar_t rr;
zs = &zscom[UNIT(dev)];
SCC_READ(12, zspeed);
@@ -3170,7 +3169,7 @@ zsa_callback(void *arg)
static void
zsa_set_za_rcv_flags_mask(struct asyncline *za)
{
- register uint_t mask;
+ uint_t mask;
za->za_rcv_flags_mask &= ~0xFF;
switch (za->za_ttycommon.t_cflag & CSIZE) {
@@ -3303,7 +3302,7 @@ zsa_suspend(struct zscom *zs)
static int
zsa_resume(struct zscom *zs)
{
- register struct asyncline *za;
+ struct asyncline *za;
struct zs_prog *zspp;
za = (struct asyncline *)&zs->zs_priv_str;
@@ -3343,8 +3342,8 @@ zsa_resume(struct zscom *zs)
static void
zsa_print_info(struct zscom *zs)
{
- register struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
- register queue_t *q = za->za_ttycommon.t_writeq;
+ struct asyncline *za = (struct asyncline *)&zs->zs_priv_str;
+ queue_t *q = za->za_ttycommon.t_writeq;
printf(" next q=%s\n", (RD(q))->q_next->q_qinfo->qi_minfo->mi_idname);
printf("unit=%d\n", zs->zs_unit);
diff --git a/usr/src/uts/sun/io/zs_common.c b/usr/src/uts/sun/io/zs_common.c
index 7c39106941..43e5a2b4ec 100644
--- a/usr/src/uts/sun/io/zs_common.c
+++ b/usr/src/uts/sun/io/zs_common.c
@@ -595,14 +595,14 @@ zsattach(dev_info_t *dev, ddi_attach_cmd_t cmd)
(void) strcpy(name, "a");
if (ddi_create_minor_node(dev, name, S_IFCHR,
ddi_get_instance(dev) * 2,
- obp_type, NULL) == DDI_FAILURE) {
+ obp_type, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
(void) strcpy(name, "b");
if (ddi_create_minor_node(dev, name, S_IFCHR,
(ddi_get_instance(dev) * 2) + 1,
- obp_type, NULL) == DDI_FAILURE) {
+ obp_type, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
@@ -614,28 +614,28 @@ zsattach(dev_info_t *dev, ddi_attach_cmd_t cmd)
(void) sprintf(name, "%c", (ddi_get_instance(dev) + 'a'));
if (ddi_create_minor_node(dev, name, S_IFCHR,
ddi_get_instance(dev) * 2,
- serial_line, NULL) == DDI_FAILURE) {
+ serial_line, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
(void) sprintf(name, "%c", (ddi_get_instance(dev) + 'b'));
if (ddi_create_minor_node(dev, name, S_IFCHR,
(ddi_get_instance(dev) * 2) + 1,
- serial_line, NULL) == DDI_FAILURE) {
+ serial_line, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
(void) sprintf(name, "%c,cu", (ddi_get_instance(dev) + 'a'));
if (ddi_create_minor_node(dev, name, S_IFCHR,
(ddi_get_instance(dev) * 2) | OUTLINE,
- dial_out, NULL) == DDI_FAILURE) {
+ dial_out, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
(void) sprintf(name, "%c,cu", (ddi_get_instance(dev) + 'b'));
if (ddi_create_minor_node(dev, name, S_IFCHR,
((ddi_get_instance(dev) * 2) + 1) | OUTLINE,
- dial_out, NULL) == DDI_FAILURE) {
+ dial_out, 0) == DDI_FAILURE) {
ddi_remove_minor_node(dev, NULL);
return (DDI_FAILURE);
}
@@ -871,7 +871,7 @@ zsintr(caddr_t intarg)
for (zs = &zscom[0]; zs <= zslast; zs++) {
if (zs->zs_flags & ZS_NEEDSOFT) {
zs->zs_flags &= ~ZS_NEEDSOFT;
- (*zs->zs_ops->zsop_softint)(zs);
+ (void) (*zs->zs_ops->zsop_softint)(zs);
if (zs->intrstats) {
KIOIP->intrs[KSTAT_INTR_SOFT]++;
}
diff --git a/usr/src/uts/sun4u/zs/Makefile b/usr/src/uts/sun4u/zs/Makefile
index 198362da01..0af5aa7379 100644
--- a/usr/src/uts/sun4u/zs/Makefile
+++ b/usr/src/uts/sun4u/zs/Makefile
@@ -40,7 +40,6 @@ UTSBASE = ../..
#
MODULE = zs
OBJECTS = $(ZS_OBJS:%=$(OBJS_DIR)/%)
-LINTS = $(ZS_OBJS:%.o=$(LINTS_DIR)/%.ln)
ROOTMODULE = $(ROOT_PSM_DRV_DIR)/$(MODULE)
#
@@ -60,23 +59,8 @@ CLEANFILES += $(MODSTUBS_O)
# Define targets
#
ALL_TARGET = $(BINARY)
-LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
-#
-# lint pass one enforcement
-#
-CFLAGS += $(CCVERBOSE)
-
-#
-# For now, disable these lint checks; maintainers should endeavor
-# to investigate and remove these for maximum lint coverage.
-# Please do not carry these forward to new Makefiles.
-#
-LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
-LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV
-LINTTAGS += -erroff=E_PTRDIFF_OVERFLOW
-
CERRWARN += -_gcc=-Wno-parentheses
CERRWARN += $(CNOWARN_UNINIT)
@@ -93,12 +77,6 @@ clean: $(CLEAN_DEPS)
clobber: $(CLOBBER_DEPS)
-lint: $(LINT_DEPS)
-
-modlintlib: $(MODLINTLIB_DEPS)
-
-clean.lint: $(CLEAN_LINT_DEPS)
-
install: $(INSTALL_DEPS)
#