diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-06-02 11:42:39 +0000 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2020-06-02 11:42:39 +0000 |
| commit | acc9d73392734e746e249c426a1558b911389dfb (patch) | |
| tree | d7fd81266a9a2c842c257909e78eed5e1dc4e4cd | |
| parent | 5cd90a78a9b9930e642ce913b44316f5a4ae6632 (diff) | |
| parent | b39b008f8a57ea7ddfd0f69b24529deba7c25ae1 (diff) | |
| download | illumos-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_rtime | 1 | ||||
| -rw-r--r-- | exception_lists/copyright | 9 | ||||
| -rw-r--r-- | exception_lists/cstyle | 8 | ||||
| -rw-r--r-- | exception_lists/hdrchk | 7 | ||||
| -rw-r--r-- | exception_lists/wscheck | 8 | ||||
| -rw-r--r-- | usr/src/Makefile.master | 2 | ||||
| -rw-r--r-- | usr/src/cmd/Makefile | 3 | ||||
| -rw-r--r-- | usr/src/cmd/bhyve/Makefile | 8 | ||||
| -rw-r--r-- | usr/src/cmd/bhyve/test/Makefile.com | 8 | ||||
| -rw-r--r-- | usr/src/cmd/bhyvectl/Makefile | 6 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/include/tlm.h | 12 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_common.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_data.c | 15 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_mover.c | 52 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_tar.c | 37 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_tar3.c | 50 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/ndmp/ndmpd_zfs.c | 89 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/tlm/tlm_proto.h | 6 | ||||
| -rw-r--r-- | usr/src/cmd/ndmpd/tlm/tlm_restore_writer.c | 21 | ||||
| -rw-r--r-- | usr/src/cmd/raidz_test/Makefile | 61 | ||||
| -rw-r--r-- | usr/src/cmd/raidz_test/raidz_bench.c | 228 | ||||
| -rw-r--r-- | usr/src/cmd/raidz_test/raidz_test.c | 761 | ||||
| -rw-r--r-- | usr/src/cmd/raidz_test/raidz_test.h | 117 | ||||
| -rw-r--r-- | usr/src/compat/bhyve/README | 9 | ||||
| -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/README | 12 | ||||
| -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.com | 4 | ||||
| -rw-r--r-- | usr/src/lib/libvmmapi/Makefile.com | 4 | ||||
| -rw-r--r-- | usr/src/lib/libvmmapi/amd64/Makefile | 2 | ||||
| -rw-r--r-- | usr/src/pkg/manifests/system-file-system-zfs-tests.mf | 2 | ||||
| -rw-r--r-- | usr/src/pkg/manifests/system-test-zfstest.mf | 5 | ||||
| -rw-r--r-- | usr/src/req.flg | 2 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/include/commands.cfg | 3 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/runfiles/delphix.run | 3 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/runfiles/omnios.run | 3 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/runfiles/openindiana.run | 3 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/runfiles/smartos.run | 3 | ||||
| -rw-r--r-- | usr/src/test/zfs-tests/tests/functional/raidz/Makefile | 21 | ||||
| -rwxr-xr-x | usr/src/test/zfs-tests/tests/functional/raidz/cleanup.ksh | 30 | ||||
| -rwxr-xr-x | usr/src/test/zfs-tests/tests/functional/raidz/raidz_001_neg.ksh | 38 | ||||
| -rwxr-xr-x | usr/src/test/zfs-tests/tests/functional/raidz/raidz_002_pos.ksh | 41 | ||||
| -rwxr-xr-x | usr/src/test/zfs-tests/tests/functional/raidz/setup.ksh | 32 | ||||
| -rw-r--r-- | usr/src/uts/common/Makefile.files | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/abd.c | 181 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/spa_misc.c | 3 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/abd.h | 9 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/simd.h | 40 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/vdev_raidz.h | 65 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/sys/vdev_raidz_impl.h | 351 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/vdev_raidz.c | 265 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/vdev_raidz_math.c | 571 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/vdev_raidz_math_impl.h | 1477 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/vdev_raidz_math_scalar.c | 337 | ||||
| -rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_vfsops.c | 39 | ||||
| -rw-r--r-- | usr/src/uts/common/io/ixgbe/ixgbe_osdep.h | 2 | ||||
| -rw-r--r-- | usr/src/uts/common/sys/sysevent.h | 2 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/io/vmm/vmm_sol_dev.c | 99 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/ppt/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/uts/i86pc/vmm/Makefile | 4 | ||||
| -rw-r--r-- | usr/src/uts/req.flg | 4 | ||||
| -rw-r--r-- | usr/src/uts/sun/io/zs_async.c | 143 | ||||
| -rw-r--r-- | usr/src/uts/sun/io/zs_common.c | 14 | ||||
| -rw-r--r-- | usr/src/uts/sun4u/zs/Makefile | 22 |
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) # |
