Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 17 Feb 2020 20:27:06 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r358049 - in projects/clang1000-import: . contrib/capsicum-test lib/libkvm sys/cam/ata sys/cam/nvme sys/cam/scsi sys/dev/acpica sys/dev/altera/sdcard sys/dev/drm2 sys/dev/pci sys/kern s...
Message-ID:  <202002172027.01HKR6l8077920@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Mon Feb 17 20:27:05 2020
New Revision: 358049
URL: https://svnweb.freebsd.org/changeset/base/358049

Log:
  Merge ^/head r358000 through r358048.

Modified:
  projects/clang1000-import/UPDATING
  projects/clang1000-import/contrib/capsicum-test/capsicum-test.h
  projects/clang1000-import/contrib/capsicum-test/procdesc.cc
  projects/clang1000-import/lib/libkvm/kvm.c
  projects/clang1000-import/lib/libkvm/kvm_getswapinfo.c
  projects/clang1000-import/lib/libkvm/kvm_private.c
  projects/clang1000-import/lib/libkvm/kvm_vnet.c
  projects/clang1000-import/sys/cam/ata/ata_da.c
  projects/clang1000-import/sys/cam/nvme/nvme_da.c
  projects/clang1000-import/sys/cam/scsi/scsi_da.c
  projects/clang1000-import/sys/dev/acpica/acpi.c
  projects/clang1000-import/sys/dev/altera/sdcard/altera_sdcard_io.c
  projects/clang1000-import/sys/dev/drm2/drm_pci.c
  projects/clang1000-import/sys/dev/drm2/drm_sysctl.c
  projects/clang1000-import/sys/dev/pci/pci.c
  projects/clang1000-import/sys/dev/pci/pcireg.h
  projects/clang1000-import/sys/kern/kern_synch.c
  projects/clang1000-import/sys/modules/Makefile
  projects/clang1000-import/sys/net/if.c
  projects/clang1000-import/sys/net/netisr.c
  projects/clang1000-import/sys/net/vnet.c
  projects/clang1000-import/sys/net/vnet.h
  projects/clang1000-import/sys/netinet/igmp.c
  projects/clang1000-import/sys/netinet/sctp_ss_functions.c
  projects/clang1000-import/sys/netinet/tcp_hostcache.c
  projects/clang1000-import/sys/netinet6/mld6.c
  projects/clang1000-import/sys/sys/param.h
  projects/clang1000-import/sys/sys/refcount.h
  projects/clang1000-import/sys/ufs/ffs/ffs_softdep.c
  projects/clang1000-import/sys/ufs/ffs/ffs_vfsops.c
  projects/clang1000-import/sys/ufs/ufs/ufsmount.h
  projects/clang1000-import/sys/vm/swap_pager.c
  projects/clang1000-import/sys/vm/swap_pager.h
  projects/clang1000-import/sys/vm/uma.h
  projects/clang1000-import/sys/vm/uma_core.c
  projects/clang1000-import/sys/vm/vm_page.c
  projects/clang1000-import/sys/vm/vm_page.h
  projects/clang1000-import/tests/sys/net/if_lagg_test.sh
  projects/clang1000-import/tests/sys/netinet/fibs_test.sh
  projects/clang1000-import/tests/sys/netinet6/frag6/frag6_07.sh
  projects/clang1000-import/usr.sbin/pciconf/cap.c
Directory Properties:
  projects/clang1000-import/   (props changed)

Modified: projects/clang1000-import/UPDATING
==============================================================================
--- projects/clang1000-import/UPDATING	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/UPDATING	Mon Feb 17 20:27:05 2020	(r358049)
@@ -32,6 +32,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 13.x IS SLOW:
 	information about prerequisites and upgrading, if you are not already
 	using clang 3.5.0 or higher.
 
+20200217:
+	The size of struct vnet and the magic cookie have changed.
+	Users need to recompile libkvm and all modules using VIMAGE
+	together with their new kernel.
+
 20200212:
 	Defining the long deprecated NO_CTF, NO_DEBUG_FILES, NO_INSTALLLIB,
 	NO_MAN, NO_PROFILE, and NO_WARNS variables is now an error.  Update

Modified: projects/clang1000-import/contrib/capsicum-test/capsicum-test.h
==============================================================================
--- projects/clang1000-import/contrib/capsicum-test/capsicum-test.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/contrib/capsicum-test/capsicum-test.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -248,6 +248,7 @@ void TestSkipped(const char *testcase, const char *tes
     const ::testing::TestInfo* const info = ::testing::UnitTest::GetInstance()->current_test_info(); \
     std::cerr << "Skipping " << info->test_case_name() << "::" << info->name() << " because: " << reason << std::endl; \
     TestSkipped(info->test_case_name(), info->name(), reason);          \
+    GTEST_SKIP(); \
   } while (0)
 
 // Mark a test that can only be run as root.

Modified: projects/clang1000-import/contrib/capsicum-test/procdesc.cc
==============================================================================
--- projects/clang1000-import/contrib/capsicum-test/procdesc.cc	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/contrib/capsicum-test/procdesc.cc	Mon Feb 17 20:27:05 2020	(r358049)
@@ -763,6 +763,7 @@ TEST_F(PipePdfork, ModeBits) {
 #endif
 
 TEST_F(PipePdfork, WildcardWait) {
+  TEST_SKIPPED("https://bugs.freebsd.org/244165");
   // TODO(FreeBSD): make wildcard wait ignore pdfork()ed children
   // https://bugs.freebsd.org/201054
   TerminateChild();

Modified: projects/clang1000-import/lib/libkvm/kvm.c
==============================================================================
--- projects/clang1000-import/lib/libkvm/kvm.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/lib/libkvm/kvm.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -49,6 +49,7 @@ __SCCSID("@(#)kvm.c	8.2 (Berkeley) 2/13/94");
 #include <sys/sysctl.h>
 #include <sys/mman.h>
 
+#include <stdbool.h>
 #include <net/vnet.h>
 
 #include <fcntl.h>

Modified: projects/clang1000-import/lib/libkvm/kvm_getswapinfo.c
==============================================================================
--- projects/clang1000-import/lib/libkvm/kvm_getswapinfo.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/lib/libkvm/kvm_getswapinfo.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -115,8 +115,7 @@ int
 kvm_getswapinfo_kvm(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max,
     int flags)
 {
-	int i;
-	swblk_t ttl;
+	int i, ttl;
 	TAILQ_HEAD(, swdevt) swtailq;
 	struct swdevt *sp, swinfo;
 	struct kvm_swap tot;
@@ -167,8 +166,7 @@ int
 kvm_getswapinfo_sysctl(kvm_t *kd, struct kvm_swap *swap_ary, int swap_max,
     int flags)
 {
-	int ti;
-	swblk_t ttl;
+	int ti, ttl;
 	size_t mibi, len;
 	int soid[SWI_MAXMIB];
 	struct xswdev xsd;

Modified: projects/clang1000-import/lib/libkvm/kvm_private.c
==============================================================================
--- projects/clang1000-import/lib/libkvm/kvm_private.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/lib/libkvm/kvm_private.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/stat.h>
 #include <sys/mman.h>
 
+#include <stdbool.h>
 #include <net/vnet.h>
 
 #include <assert.h>

Modified: projects/clang1000-import/lib/libkvm/kvm_vnet.c
==============================================================================
--- projects/clang1000-import/lib/libkvm/kvm_vnet.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/lib/libkvm/kvm_vnet.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/types.h>
 
+#include <stdbool.h>
 #include <net/vnet.h>
 
 #include <kvm.h>

Modified: projects/clang1000-import/sys/cam/ata/ata_da.c
==============================================================================
--- projects/clang1000-import/sys/cam/ata/ata_da.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/cam/ata/ata_da.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -50,6 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/proc.h>
 #include <sys/reboot.h>
 #include <sys/sbuf.h>
+#include <geom/geom.h>
 #include <geom/geom_disk.h>
 #endif /* _KERNEL */
 
@@ -878,6 +879,7 @@ static int ada_spindown_shutdown = ADA_DEFAULT_SPINDOW
 static int ada_spindown_suspend = ADA_DEFAULT_SPINDOWN_SUSPEND;
 static int ada_read_ahead = ADA_DEFAULT_READ_AHEAD;
 static int ada_write_cache = ADA_DEFAULT_WRITE_CACHE;
+static int ada_enable_biospeedup = 1;
 
 static SYSCTL_NODE(_kern_cam, OID_AUTO, ada, CTLFLAG_RD, 0,
             "CAM Direct Access Disk driver");
@@ -895,6 +897,8 @@ SYSCTL_INT(_kern_cam_ada, OID_AUTO, read_ahead, CTLFLA
            &ada_read_ahead, 0, "Enable disk read-ahead");
 SYSCTL_INT(_kern_cam_ada, OID_AUTO, write_cache, CTLFLAG_RWTUN,
            &ada_write_cache, 0, "Enable disk write cache");
+SYSCTL_INT(_kern_cam_ada, OID_AUTO, enable_biospeedup, CTLFLAG_RDTUN,
+	   &ada_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
 
 /*
  * ADA_ORDEREDTAG_INTERVAL determines how often, relative
@@ -1565,6 +1569,9 @@ adagetattr(struct bio *bp)
 {
 	int ret;
 	struct cam_periph *periph;
+
+	if (g_handleattr_int(bp, "GEOM::canspeedup", ada_enable_biospeedup))
+		return (EJUSTRETURN);
 
 	periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 	cam_periph_lock(periph);

Modified: projects/clang1000-import/sys/cam/nvme/nvme_da.c
==============================================================================
--- projects/clang1000-import/sys/cam/nvme/nvme_da.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/cam/nvme/nvme_da.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/cons.h>
 #include <sys/proc.h>
 #include <sys/reboot.h>
+#include <geom/geom.h>
 #include <geom/geom_disk.h>
 #endif /* _KERNEL */
 
@@ -174,9 +175,12 @@ static SYSCTL_NODE(_kern_cam, OID_AUTO, nda, CTLFLAG_R
 static int nda_send_ordered = NDA_DEFAULT_SEND_ORDERED;
 static int nda_default_timeout = NDA_DEFAULT_TIMEOUT;
 static int nda_max_trim_entries = NDA_MAX_TRIM_ENTRIES;
+static int nda_enable_biospeedup = 1;
 SYSCTL_INT(_kern_cam_nda, OID_AUTO, max_trim, CTLFLAG_RDTUN,
     &nda_max_trim_entries, NDA_MAX_TRIM_ENTRIES,
     "Maximum number of BIO_DELETE to send down as a DSM TRIM.");
+SYSCTL_INT(_kern_cam_nda, OID_AUTO, enable_biospeedup, CTLFLAG_RDTUN,
+    &nda_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
 
 /*
  * All NVMe media is non-rotational, so all nvme device instances
@@ -699,6 +703,9 @@ ndagetattr(struct bio *bp)
 {
 	int ret;
 	struct cam_periph *periph;
+
+	if (g_handleattr_int(bp, "GEOM::canspeedup", nda_enable_biospeedup))
+		return (EJUSTRETURN);
 
 	periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 	cam_periph_lock(periph);

Modified: projects/clang1000-import/sys/cam/scsi/scsi_da.c
==============================================================================
--- projects/clang1000-import/sys/cam/scsi/scsi_da.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/cam/scsi/scsi_da.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -1547,6 +1547,7 @@ static int da_default_timeout = DA_DEFAULT_TIMEOUT;
 static sbintime_t da_default_softtimeout = DA_DEFAULT_SOFTTIMEOUT;
 static int da_send_ordered = DA_DEFAULT_SEND_ORDERED;
 static int da_disable_wp_detection = 0;
+static int da_enable_biospeedup = 1;
 
 static SYSCTL_NODE(_kern_cam, OID_AUTO, da, CTLFLAG_RD, 0,
             "CAM Direct Access Disk driver");
@@ -1561,6 +1562,8 @@ SYSCTL_INT(_kern_cam_da, OID_AUTO, send_ordered, CTLFL
 SYSCTL_INT(_kern_cam_da, OID_AUTO, disable_wp_detection, CTLFLAG_RWTUN,
            &da_disable_wp_detection, 0,
 	   "Disable detection of write-protected disks");
+SYSCTL_INT(_kern_cam_da, OID_AUTO, enable_biospeedup, CTLFLAG_RDTUN,
+	    &da_enable_biospeedup, 0, "Enable BIO_SPEEDUP processing");
 
 SYSCTL_PROC(_kern_cam_da, OID_AUTO, default_softtimeout,
     CTLTYPE_UINT | CTLFLAG_RW, NULL, 0, dasysctlsofttimeout, "I",
@@ -1966,6 +1969,9 @@ dagetattr(struct bio *bp)
 {
 	int ret;
 	struct cam_periph *periph;
+
+	if (g_handleattr_int(bp, "GEOM::canspeedup", da_enable_biospeedup))
+		return (EJUSTRETURN);
 
 	periph = (struct cam_periph *)bp->bio_disk->d_drv1;
 	cam_periph_lock(periph);

Modified: projects/clang1000-import/sys/dev/acpica/acpi.c
==============================================================================
--- projects/clang1000-import/sys/dev/acpica/acpi.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/acpica/acpi.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -237,7 +237,8 @@ static driver_t acpi_driver = {
 };
 
 static devclass_t acpi_devclass;
-DRIVER_MODULE(acpi, nexus, acpi_driver, acpi_devclass, acpi_modevent, 0);
+EARLY_DRIVER_MODULE(acpi, nexus, acpi_driver, acpi_devclass, acpi_modevent, 0,
+    BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
 MODULE_VERSION(acpi, 1);
 
 ACPI_SERIAL_DECL(acpi, "ACPI root bus");

Modified: projects/clang1000-import/sys/dev/altera/sdcard/altera_sdcard_io.c
==============================================================================
--- projects/clang1000-import/sys/dev/altera/sdcard/altera_sdcard_io.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/altera/sdcard/altera_sdcard_io.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -293,27 +293,31 @@ recheck:
 }
 
 static void
-altera_sdcard_io_start_internal(struct altera_sdcard_softc *sc, struct bio **bp)
+altera_sdcard_io_start_internal(struct altera_sdcard_softc *sc,
+    struct bio **bpp)
 {
+	struct bio *bp;
 
-	switch (*bp->bio_cmd) {
+	bp = *bpp;
+
+	switch (bp->bio_cmd) {
 	case BIO_READ:
-		altera_sdcard_write_cmd_arg(sc, *bp->bio_pblkno *
+		altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
 		    ALTERA_SDCARD_SECTORSIZE);
 		altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_READ_BLOCK);
 		break;
 
 	case BIO_WRITE:
-		altera_sdcard_write_rxtx_buffer(sc, *bp->bio_data,
-		    *bp->bio_bcount);
-		altera_sdcard_write_cmd_arg(sc, *bp->bio_pblkno *
+		altera_sdcard_write_rxtx_buffer(sc, bp->bio_data,
+		    bp->bio_bcount);
+		altera_sdcard_write_cmd_arg(sc, bp->bio_pblkno *
 		    ALTERA_SDCARD_SECTORSIZE);
 		altera_sdcard_write_cmd(sc, ALTERA_SDCARD_CMD_WRITE_BLOCK);
 		break;
 
 	default:
-		biofinish(*bp, NULL, EOPNOTSUPP);
-		*bp = NULL;
+		biofinish(bp, NULL, EOPNOTSUPP);
+		*bpp = NULL;
 	}
 }
 
@@ -333,7 +337,7 @@ altera_sdcard_io_start(struct altera_sdcard_softc *sc,
 	KASSERT(bp->bio_bcount == ALTERA_SDCARD_SECTORSIZE,
 	    ("%s: I/O size not %d", __func__, ALTERA_SDCARD_SECTORSIZE));
 	altera_sdcard_io_start_internal(sc, &bp);
-	sc->as_currentbio = *bp;
+	sc->as_currentbio = bp;
 	sc->as_retriesleft = ALTERA_SDCARD_RETRY_LIMIT;
 }
 

Modified: projects/clang1000-import/sys/dev/drm2/drm_pci.c
==============================================================================
--- projects/clang1000-import/sys/dev/drm2/drm_pci.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/drm2/drm_pci.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -42,7 +42,8 @@ __FBSDID("$FreeBSD$");
 #include <dev/drm2/drmP.h>
 
 static int drm_msi = 1;	/* Enable by default. */
-SYSCTL_NODE(_hw, OID_AUTO, drm, CTLFLAG_RW, NULL, "DRM device");
+SYSCTL_NODE(_hw, OID_AUTO, drm, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL,
+    "DRM device");
 SYSCTL_INT(_hw_drm, OID_AUTO, msi, CTLFLAG_RDTUN, &drm_msi, 1,
     "Enable MSI interrupts for drm devices");
 

Modified: projects/clang1000-import/sys/dev/drm2/drm_sysctl.c
==============================================================================
--- projects/clang1000-import/sys/dev/drm2/drm_sysctl.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/drm2/drm_sysctl.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -69,7 +69,7 @@ int drm_sysctl_init(struct drm_device *dev)
 
 	/* Add the sysctl node for DRI if it doesn't already exist */
 	drioid = SYSCTL_ADD_NODE(&info->ctx, SYSCTL_CHILDREN(&sysctl___hw), OID_AUTO,
-	    "dri", CTLFLAG_RW, NULL, "DRI Graphics");
+	    "dri", CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, "DRI Graphics");
 	if (!drioid) {
 		free(dev->sysctl, DRM_MEM_DRIVER);
 		dev->sysctl = NULL;
@@ -92,23 +92,17 @@ int drm_sysctl_init(struct drm_device *dev)
 	info->name[0] = '0' + i;
 	info->name[1] = 0;
 	top = SYSCTL_ADD_NODE(&info->ctx, SYSCTL_CHILDREN(drioid),
-	    OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
+	    OID_AUTO, info->name, CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, NULL);
 	if (!top) {
 		drm_sysctl_cleanup(dev);
 		return (-ENOMEM);
 	}
 
 	for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
-		oid = SYSCTL_ADD_OID(&info->ctx,
-			SYSCTL_CHILDREN(top),
-			OID_AUTO,
-			drm_sysctl_list[i].name,
-			CTLTYPE_STRING | CTLFLAG_RD,
-			dev,
-			0,
-			drm_sysctl_list[i].f,
-			"A",
-			NULL);
+		oid = SYSCTL_ADD_OID(&info->ctx, SYSCTL_CHILDREN(top),
+			OID_AUTO, drm_sysctl_list[i].name,
+			CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_NEEDGIANT,
+			dev, 0, drm_sysctl_list[i].f, "A", NULL);
 		if (!oid) {
 			drm_sysctl_cleanup(dev);
 			return (-ENOMEM);

Modified: projects/clang1000-import/sys/dev/pci/pci.c
==============================================================================
--- projects/clang1000-import/sys/dev/pci/pci.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/pci/pci.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -332,7 +332,8 @@ uint32_t pci_numdevs = 0;
 static int pcie_chipset, pcix_chipset;
 
 /* sysctl vars */
-SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD, 0, "PCI bus tuning parameters");
+SYSCTL_NODE(_hw, OID_AUTO, pci, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
+    "PCI bus tuning parameters");
 
 static int pci_enable_io_modes = 1;
 SYSCTL_INT(_hw_pci, OID_AUTO, enable_io_modes, CTLFLAG_RWTUN,

Modified: projects/clang1000-import/sys/dev/pci/pcireg.h
==============================================================================
--- projects/clang1000-import/sys/dev/pci/pcireg.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/dev/pci/pcireg.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -192,7 +192,7 @@
 #define	PCIZ_PMUX	0x001a	/* Protocol Multiplexing */
 #define	PCIZ_PASID	0x001b	/* Process Address Space ID */
 #define	PCIZ_LN_REQ	0x001c	/* LN Requester */
-#define	PCIZ_DPC	0x001d	/* Downstream Porto Containment */
+#define	PCIZ_DPC	0x001d	/* Downstream Port Containment */
 #define	PCIZ_L1PM	0x001e	/* L1 PM Substates */
 
 /* config registers for header type 0 devices */

Modified: projects/clang1000-import/sys/kern/kern_synch.c
==============================================================================
--- projects/clang1000-import/sys/kern/kern_synch.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/kern/kern_synch.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -368,8 +368,8 @@ refcount_release_last(volatile u_int *count, u_int n, 
 	/*
 	 * Last reference.  Signal the user to call the destructor.
 	 *
-	 * Ensure that the destructor sees all updates.  The fence_rel
-	 * at the start of refcount_releasen synchronizes with this fence.
+	 * Ensure that the destructor sees all updates. This synchronizes
+	 * with release fences from all routines which drop the count.
 	 */
 	atomic_thread_fence_acq();
 	return (true);

Modified: projects/clang1000-import/sys/modules/Makefile
==============================================================================
--- projects/clang1000-import/sys/modules/Makefile	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/modules/Makefile	Mon Feb 17 20:27:05 2020	(r358049)
@@ -8,6 +8,8 @@ SUBDIR_PARALLEL=
 # Modules that include binary-only blobs of microcode should be selectable by
 # MK_SOURCELESS_UCODE option (see below).
 
+.include "${SYSDIR}/conf/config.mk"
+
 .if defined(MODULES_OVERRIDE) && !defined(ALL_MODULES)
 SUBDIR=${MODULES_OVERRIDE}
 .else
@@ -396,8 +398,10 @@ _autofs=	autofs
 .if ${MK_CDDL} != "no" || defined(ALL_MODULES)
 .if (${MACHINE_CPUARCH} != "arm" || ${MACHINE_ARCH:Marmv[67]*} != "") && \
 	${MACHINE_CPUARCH} != "mips"
+.if ${KERN_OPTS:MKDTRACE_HOOKS}
 SUBDIR+=	dtrace
 .endif
+.endif
 SUBDIR+=	opensolaris
 .endif
 
@@ -712,9 +716,11 @@ _sgx_linux=	sgx_linux
 _smartpqi=	smartpqi
 
 .if ${MK_BHYVE} != "no" || defined(ALL_MODULES)
+.if ${KERN_OPTS:MSMP}
 _vmm=		vmm
 .endif
 .endif
+.endif
 
 .if ${MACHINE_CPUARCH} == "i386"
 # XXX some of these can move to the general case when de-i386'ed
@@ -798,8 +804,6 @@ afterinstall: .PHONY
 		${KLDXREF_CMD} ${DESTDIR}${KMODDIR}; \
 	fi
 .endif
-
-.include "${SYSDIR}/conf/config.mk"
 
 SUBDIR:= ${SUBDIR:u:O}
 

Modified: projects/clang1000-import/sys/net/if.c
==============================================================================
--- projects/clang1000-import/sys/net/if.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/net/if.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -322,6 +322,11 @@ SX_SYSINIT_FLAGS(ifnet_sx, &ifnet_sxlock, "ifnet_sx", 
  */
 #define	IFNET_HOLD	(void *)(uintptr_t)(-1)
 
+#ifdef VIMAGE
+#define	VNET_IS_SHUTTING_DOWN(_vnet)					\
+    ((_vnet)->vnet_shutdown && (_vnet)->vnet_state < SI_SUB_VNET_DONE)
+#endif
+
 static	if_com_alloc_t *if_com_alloc[256];
 static	if_com_free_t *if_com_free[256];
 
@@ -1080,7 +1085,7 @@ if_detach_internal(struct ifnet *ifp, int vmove, struc
 #ifdef VIMAGE
 	bool shutdown;
 
-	shutdown = ifp->if_vnet->vnet_shutdown;
+	shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet);
 #endif
 	IFNET_WLOCK();
 	CK_STAILQ_FOREACH(iter, &V_ifnet, if_link)
@@ -1339,6 +1344,7 @@ if_vmove_loan(struct thread *td, struct ifnet *ifp, ch
 	struct prison *pr;
 	struct ifnet *difp;
 	int error;
+	bool shutdown;
 
 	/* Try to find the prison within our visibility. */
 	sx_slock(&allprison_lock);
@@ -1366,7 +1372,8 @@ if_vmove_loan(struct thread *td, struct ifnet *ifp, ch
 	}
 
 	/* Make sure the VNET is stable. */
-	if (ifp->if_vnet->vnet_shutdown) {
+	shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet);
+	if (shutdown) {
 		CURVNET_RESTORE();
 		prison_free(pr);
 		return (EBUSY);
@@ -1391,6 +1398,7 @@ if_vmove_reclaim(struct thread *td, char *ifname, int 
 	struct vnet *vnet_dst;
 	struct ifnet *ifp;
 	int error;
+ 	bool shutdown;
 
 	/* Try to find the prison within our visibility. */
 	sx_slock(&allprison_lock);
@@ -1419,7 +1427,8 @@ if_vmove_reclaim(struct thread *td, char *ifname, int 
 	}
 
 	/* Make sure the VNET is stable. */
-	if (ifp->if_vnet->vnet_shutdown) {
+	shutdown = VNET_IS_SHUTTING_DOWN(ifp->if_vnet);
+	if (shutdown) {
 		CURVNET_RESTORE();
 		prison_free(pr);
 		return (EBUSY);
@@ -2950,11 +2959,15 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, s
 	struct ifreq *ifr;
 	int error;
 	int oif_flags;
+#ifdef VIMAGE
+	bool shutdown;
+#endif
 
 	CURVNET_SET(so->so_vnet);
 #ifdef VIMAGE
 	/* Make sure the VNET is stable. */
-	if (so->so_vnet->vnet_shutdown) {
+	shutdown = VNET_IS_SHUTTING_DOWN(so->so_vnet);
+	if (shutdown) {
 		CURVNET_RESTORE();
 		return (EBUSY);
 	}

Modified: projects/clang1000-import/sys/net/netisr.c
==============================================================================
--- projects/clang1000-import/sys/net/netisr.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/net/netisr.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -1056,6 +1056,8 @@ netisr_queue_src(u_int proto, uintptr_t source, struct
 	if (m != NULL) {
 		KASSERT(!CPU_ABSENT(cpuid), ("%s: CPU %u absent", __func__,
 		    cpuid));
+		VNET_ASSERT(m->m_pkthdr.rcvif != NULL,
+		    ("%s:%d rcvif == NULL: m=%p", __func__, __LINE__, m));
 		error = netisr_queue_internal(proto, m, cpuid);
 	} else
 		error = ENOBUFS;

Modified: projects/clang1000-import/sys/net/vnet.c
==============================================================================
--- projects/clang1000-import/sys/net/vnet.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/net/vnet.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -279,6 +279,9 @@ vnet_destroy(struct vnet *vnet)
 	LIST_REMOVE(vnet, vnet_le);
 	VNET_LIST_WUNLOCK();
 
+	/* Signal that VNET is being shutdown. */
+	vnet->vnet_shutdown = true;
+
 	CURVNET_SET_QUIET(vnet);
 	vnet_sysuninit();
 	CURVNET_RESTORE();
@@ -350,15 +353,15 @@ vnet_data_startup(void *dummy __unused)
 }
 SYSINIT(vnet_data, SI_SUB_KLD, SI_ORDER_FIRST, vnet_data_startup, NULL);
 
+/* Dummy VNET_SYSINIT to make sure we always reach the final end state. */
 static void
-vnet_sysuninit_shutdown(void *unused __unused)
+vnet_sysinit_done(void *unused __unused)
 {
 
-	/* Signal that VNET is being shutdown. */
-	curvnet->vnet_shutdown = 1;
+	return;
 }
-VNET_SYSUNINIT(vnet_sysuninit_shutdown, SI_SUB_VNET_DONE, SI_ORDER_FIRST,
-    vnet_sysuninit_shutdown, NULL);
+VNET_SYSINIT(vnet_sysinit_done, SI_SUB_VNET_DONE, SI_ORDER_ANY,
+    vnet_sysinit_done, NULL);
 
 /*
  * When a module is loaded and requires storage for a virtualized global
@@ -572,8 +575,10 @@ vnet_sysinit(void)
 	struct vnet_sysinit *vs;
 
 	VNET_SYSINIT_RLOCK();
-	TAILQ_FOREACH(vs, &vnet_constructors, link)
+	TAILQ_FOREACH(vs, &vnet_constructors, link) {
+		curvnet->vnet_state = vs->subsystem;
 		vs->func(vs->arg);
+	}
 	VNET_SYSINIT_RUNLOCK();
 }
 
@@ -589,8 +594,10 @@ vnet_sysuninit(void)
 
 	VNET_SYSINIT_RLOCK();
 	TAILQ_FOREACH_REVERSE(vs, &vnet_destructors, vnet_sysuninit_head,
-	    link)
+	    link) {
+		curvnet->vnet_state = vs->subsystem;
 		vs->func(vs->arg);
+	}
 	VNET_SYSINIT_RUNLOCK();
 }
 
@@ -704,7 +711,8 @@ db_vnet_print(struct vnet *vnet)
 	db_printf(" vnet_data_mem  = %p\n", vnet->vnet_data_mem);
 	db_printf(" vnet_data_base = %#jx\n",
 	    (uintmax_t)vnet->vnet_data_base);
-	db_printf(" vnet_shutdown  = %#08x\n", vnet->vnet_shutdown);
+	db_printf(" vnet_state     = %#08x\n", vnet->vnet_state);
+	db_printf(" vnet_shutdown  = %#03x\n", vnet->vnet_shutdown);
 	db_printf("\n");
 }
 

Modified: projects/clang1000-import/sys/net/vnet.h
==============================================================================
--- projects/clang1000-import/sys/net/vnet.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/net/vnet.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -72,11 +72,12 @@ struct vnet {
 	u_int			 vnet_magic_n;
 	u_int			 vnet_ifcnt;
 	u_int			 vnet_sockcnt;
-	u_int			 vnet_shutdown; /* Shutdown in progress. */
+	u_int			 vnet_state;	/* SI_SUB_* */
 	void			*vnet_data_mem;
 	uintptr_t		 vnet_data_base;
-};
-#define	VNET_MAGIC_N	0x3e0d8f29
+	bool			 vnet_shutdown;	/* Shutdown in progress. */
+} __aligned(CACHE_LINE_SIZE);
+#define	VNET_MAGIC_N	0x5e4a6f28
 
 /*
  * These two virtual network stack allocator definitions are also required

Modified: projects/clang1000-import/sys/netinet/igmp.c
==============================================================================
--- projects/clang1000-import/sys/netinet/igmp.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/netinet/igmp.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -303,6 +303,7 @@ igmp_save_context(struct mbuf *m, struct ifnet *ifp)
 #ifdef VIMAGE
 	m->m_pkthdr.PH_loc.ptr = ifp->if_vnet;
 #endif /* VIMAGE */
+	m->m_pkthdr.rcvif = ifp;
 	m->m_pkthdr.flowid = ifp->if_index;
 }
 

Modified: projects/clang1000-import/sys/netinet/sctp_ss_functions.c
==============================================================================
--- projects/clang1000-import/sys/netinet/sctp_ss_functions.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/netinet/sctp_ss_functions.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -517,6 +517,9 @@ sctp_ss_prio_select(struct sctp_tcb *stcb SCTP_UNUSED,
 {
 	struct sctp_stream_out *strq, *strqt, *strqn;
 
+	if (asoc->ss_data.locked_on_sending) {
+		return (asoc->ss_data.locked_on_sending);
+	}
 	strqt = asoc->ss_data.last_out_stream;
 prio_again:
 	/* Find the next stream to use */
@@ -694,6 +697,9 @@ sctp_ss_fb_select(struct sctp_tcb *stcb SCTP_UNUSED, s
 {
 	struct sctp_stream_out *strq = NULL, *strqt;
 
+	if (asoc->ss_data.locked_on_sending) {
+		return (asoc->ss_data.locked_on_sending);
+	}
 	if (asoc->ss_data.last_out_stream == NULL ||
 	    TAILQ_FIRST(&asoc->ss_data.out.wheel) == TAILQ_LAST(&asoc->ss_data.out.wheel, sctpwheel_listhead)) {
 		strqt = TAILQ_FIRST(&asoc->ss_data.out.wheel);
@@ -900,6 +906,9 @@ sctp_ss_fcfs_select(struct sctp_tcb *stcb SCTP_UNUSED,
 	struct sctp_stream_out *strq;
 	struct sctp_stream_queue_pending *sp;
 
+	if (asoc->ss_data.locked_on_sending) {
+		return (asoc->ss_data.locked_on_sending);
+	}
 	sp = TAILQ_FIRST(&asoc->ss_data.out.list);
 default_again:
 	if (sp != NULL) {

Modified: projects/clang1000-import/sys/netinet/tcp_hostcache.c
==============================================================================
--- projects/clang1000-import/sys/netinet/tcp_hostcache.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/netinet/tcp_hostcache.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -437,8 +437,10 @@ tcp_hc_get(struct in_conninfo *inc, struct hc_metrics_
 {
 	struct hc_metrics *hc_entry;
 
-	if (!V_tcp_use_hostcache)
+	if (!V_tcp_use_hostcache) {
+		bzero(hc_metrics_lite, sizeof(*hc_metrics_lite));
 		return;
+	}
 
 	/*
 	 * Find the right bucket.

Modified: projects/clang1000-import/sys/netinet6/mld6.c
==============================================================================
--- projects/clang1000-import/sys/netinet6/mld6.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/netinet6/mld6.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -283,6 +283,7 @@ mld_save_context(struct mbuf *m, struct ifnet *ifp)
 #ifdef VIMAGE
 	m->m_pkthdr.PH_loc.ptr = ifp->if_vnet;
 #endif /* VIMAGE */
+	m->m_pkthdr.rcvif = ifp;
 	m->m_pkthdr.flowid = ifp->if_index;
 }
 

Modified: projects/clang1000-import/sys/sys/param.h
==============================================================================
--- projects/clang1000-import/sys/sys/param.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/sys/param.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -60,7 +60,7 @@
  *		in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1300077	/* Master, propagated to newvers */
+#define __FreeBSD_version 1300078	/* Master, propagated to newvers */
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

Modified: projects/clang1000-import/sys/sys/refcount.h
==============================================================================
--- projects/clang1000-import/sys/sys/refcount.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/sys/refcount.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -119,6 +119,9 @@ refcount_releasen(volatile u_int *count, u_int n)
 	KASSERT(n < REFCOUNT_SATURATION_VALUE / 2,
 	    ("refcount_releasen: n=%u too large", n));
 
+	/*
+	 * Paired with acquire fence in refcount_release_last.
+	 */
 	atomic_thread_fence_rel();
 	old = atomic_fetchadd_int(count, -n);
 	if (__predict_false(n >= REFCOUNT_COUNT(old) ||
@@ -198,6 +201,9 @@ refcount_release_if_gt(volatile u_int *count, u_int n)
 			return (false);
 		if (__predict_false(REFCOUNT_SATURATED(old)))
 			return (true);
+		/*
+		 * Paired with acquire fence in refcount_release_last.
+		 */
 		if (atomic_fcmpset_rel_int(count, &old, old - 1))
 			return (true);
 	}

Modified: projects/clang1000-import/sys/ufs/ffs/ffs_softdep.c
==============================================================================
--- projects/clang1000-import/sys/ufs/ffs/ffs_softdep.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/ufs/ffs/ffs_softdep.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -1464,6 +1464,9 @@ softdep_send_speedup(struct ufsmount *ump, size_t shor
 {
 	struct buf *bp;
 
+	if ((ump->um_flags & UM_CANSPEEDUP) == 0)
+		return;
+
 	bp = malloc(sizeof(*bp), M_TRIM, M_WAITOK | M_ZERO);
 	bp->b_iocmd = BIO_SPEEDUP;
 	bp->b_ioflags = flags;

Modified: projects/clang1000-import/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- projects/clang1000-import/sys/ufs/ffs/ffs_vfsops.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/ufs/ffs/ffs_vfsops.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -794,7 +794,7 @@ ffs_mountfs(devvp, mp, td)
 	struct ucred *cred;
 	struct g_consumer *cp;
 	struct mount *nmp;
-	int candelete;
+	int candelete, canspeedup;
 	off_t loc;
 
 	fs = NULL;
@@ -1009,6 +1009,12 @@ ffs_mountfs(devvp, mp, td)
 			ump->um_trimhash = hashinit(MAXTRIMIO, M_TRIM,
 			    &ump->um_trimlisthashsize);
 		}
+	}
+
+	len = sizeof(int);
+	if (g_io_getattr("GEOM::canspeedup", cp, &len, &canspeedup) == 0) {
+		if (canspeedup)
+			ump->um_flags |= UM_CANSPEEDUP;
 	}
 
 	ump->um_mountp = mp;

Modified: projects/clang1000-import/sys/ufs/ufs/ufsmount.h
==============================================================================
--- projects/clang1000-import/sys/ufs/ufs/ufsmount.h	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/ufs/ufs/ufsmount.h	Mon Feb 17 20:27:05 2020	(r358049)
@@ -131,6 +131,7 @@ struct ufsmount {
  */
 #define UM_CANDELETE		0x00000001	/* devvp supports TRIM */
 #define UM_WRITESUSPENDED	0x00000002	/* suspension in progress */
+#define UM_CANSPEEDUP		0x00000004	/* devvp supports SPEEDUP */
 
 /*
  * function prototypes

Modified: projects/clang1000-import/sys/vm/swap_pager.c
==============================================================================
--- projects/clang1000-import/sys/vm/swap_pager.c	Mon Feb 17 20:25:33 2020	(r358048)
+++ projects/clang1000-import/sys/vm/swap_pager.c	Mon Feb 17 20:27:05 2020	(r358049)
@@ -1188,8 +1188,8 @@ swap_pager_unswapped(vm_page_t m)
  *	The pages in "ma" must be busied and will remain busied upon return.
  */
 static int
-swap_pager_getpages(vm_object_t object, vm_page_t *ma, int count, int *rbehind,
-    int *rahead)
+swap_pager_getpages_locked(vm_object_t object, vm_page_t *ma, int count,
+    int *rbehind, int *rahead)
 {
 	struct buf *bp;
 	vm_page_t bm, mpred, msucc, p;
@@ -1197,7 +1197,7 @@ swap_pager_getpages(vm_object_t object, vm_page_t *ma,
 	daddr_t blk;
 	int i, maxahead, maxbehind, reqcount;
 
-	VM_OBJECT_WLOCK(object);
+	VM_OBJECT_ASSERT_WLOCKED(object);
 	reqcount = count;
 
 	KASSERT(object->type == OBJT_SWAP,
@@ -1352,6 +1352,15 @@ swap_pager_getpages(vm_object_t object, vm_page_t *ma,
 	 */
 }
 
+static int
+swap_pager_getpages(vm_object_t object, vm_page_t *ma, int count,
+    int *rbehind, int *rahead)
+{
+
+	VM_OBJECT_WLOCK(object);
+	return (swap_pager_getpages_locked(object, ma, count, rbehind, rahead));
+}
+
 /*
  * 	swap_pager_getpages_async():
  *
@@ -1444,18 +1453,6 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma,
 		/* Maximum I/O size is limited by maximum swap block size. */
 		n = min(count - i, nsw_cluster_max);
 
-		/* Get a block of swap of size up to size n. */
-		blk = swp_pager_getswapspace(&n, 4);
-		if (blk == SWAPBLK_NONE) {
-			for (j = 0; j < n; ++j)
-				rtvals[i + j] = VM_PAGER_FAIL;
-			continue;
-		}
-
-		/*
-		 * All I/O parameters have been satisfied.  Build the I/O
-		 * request and assign the swap space.
-		 */
 		if (async) {
 			mtx_lock(&swbuf_mtx);
 			while (nsw_wcount_async == 0)
@@ -1464,19 +1461,20 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma,
 			nsw_wcount_async--;
 			mtx_unlock(&swbuf_mtx);
 		}
-		bp = uma_zalloc(swwbuf_zone, M_WAITOK);
-		if (async)
-			bp->b_flags = B_ASYNC;
-		bp->b_flags |= B_PAGING;
-		bp->b_iocmd = BIO_WRITE;
 
-		bp->b_rcred = crhold(thread0.td_ucred);
-		bp->b_wcred = crhold(thread0.td_ucred);
-		bp->b_bcount = PAGE_SIZE * n;
-		bp->b_bufsize = PAGE_SIZE * n;
-		bp->b_blkno = blk;
-
+		/* Get a block of swap of size up to size n. */
 		VM_OBJECT_WLOCK(object);
+		blk = swp_pager_getswapspace(&n, 4);
+		if (blk == SWAPBLK_NONE) {
+			VM_OBJECT_WUNLOCK(object);
+			mtx_lock(&swbuf_mtx);
+			if (++nsw_wcount_async == 1)
+				wakeup(&nsw_wcount_async);
+			mtx_unlock(&swbuf_mtx);
+			for (j = 0; j < n; ++j)
+				rtvals[i + j] = VM_PAGER_FAIL;
+			continue;
+		}
 		for (j = 0; j < n; ++j) {
 			mreq = ma[i + j];
 			vm_page_aflag_clear(mreq, PGA_SWAP_FREE);
@@ -1487,10 +1485,24 @@ swap_pager_putpages(vm_object_t object, vm_page_t *ma,
 				    addr);
 			MPASS(mreq->dirty == VM_PAGE_BITS_ALL);
 			mreq->oflags |= VPO_SWAPINPROG;
-			bp->b_pages[j] = mreq;
 		}
 		VM_OBJECT_WUNLOCK(object);
+
+		bp = uma_zalloc(swwbuf_zone, M_WAITOK);
+		if (async)
+			bp->b_flags = B_ASYNC;
+		bp->b_flags |= B_PAGING;
+		bp->b_iocmd = BIO_WRITE;
+
+		bp->b_rcred = crhold(thread0.td_ucred);
+		bp->b_wcred = crhold(thread0.td_ucred);
+		bp->b_bcount = PAGE_SIZE * n;
+		bp->b_bufsize = PAGE_SIZE * n;
+		bp->b_blkno = blk;
+		for (j = 0; j < n; j++)
+			bp->b_pages[j] = ma[i + j];
 		bp->b_npages = n;
+
 		/*
 		 * Must set dirty range for NFS to work.
 		 */
@@ -1712,72 +1724,11 @@ swp_pager_force_dirty(vm_page_t m)
 {
 
 	vm_page_dirty(m);
-#ifdef INVARIANTS
-	if (!vm_page_wired(m) && m->a.queue == PQ_NONE)
-		panic("page %p is neither wired nor queued", m);
-#endif
-	vm_page_xunbusy(m);
 	swap_pager_unswapped(m);
-}
-
-static void
-swp_pager_force_launder(vm_page_t m)
-{
-
-	vm_page_dirty(m);
 	vm_page_launder(m);
-	vm_page_xunbusy(m);
-	swap_pager_unswapped(m);
 }
 
 /*
- * SWP_PAGER_FORCE_PAGEIN() - force swap blocks to be paged in
- *
- *	This routine dissociates pages starting at the given index within an
- *	object from their backing store, paging them in if they do not reside
- *	in memory.  Pages that are paged in are marked dirty and placed in the
- *	laundry queue.  Pages are marked dirty because they no longer have
- *	backing store.  They are placed in the laundry queue because they have
- *	not been accessed recently.  Otherwise, they would already reside in
- *	memory.
- */
-static void
-swp_pager_force_pagein(vm_object_t object, vm_pindex_t pindex, int npages)
-{
-	vm_page_t ma[npages];
-	int i, j;
-
-	KASSERT(npages > 0, ("%s: No pages", __func__));
-	KASSERT(npages <= MAXPHYS / PAGE_SIZE,
-	    ("%s: Too many pages: %d", __func__, npages));
-	KASSERT(object->type == OBJT_SWAP,
-	    ("%s: Object not swappable", __func__));
-	vm_object_pip_add(object, npages);
-	vm_page_grab_pages(object, pindex, VM_ALLOC_NORMAL, ma, npages);
-	for (i = j = 0;; i++) {
-		/* Count nonresident pages, to page-in all at once. */
-		if (i < npages && ma[i]->valid != VM_PAGE_BITS_ALL)
-			continue;
-		if (j < i) {
-			VM_OBJECT_WUNLOCK(object);
-			/* Page-in nonresident pages. Mark for laundering. */
-			if (swap_pager_getpages(object, &ma[j], i - j, NULL,
-			    NULL) != VM_PAGER_OK)
-				panic("%s: read from swap failed", __func__);
-			VM_OBJECT_WLOCK(object);
-			do {
-				swp_pager_force_launder(ma[j]);
-			} while (++j < i);
-		}
-		if (i == npages)
-			break;
-		/* Mark dirty a resident page. */
-		swp_pager_force_dirty(ma[j++]);
-	}
-	vm_object_pip_wakeupn(object, npages);
-}
-
-/*
  *	swap_pager_swapoff_object:
  *
  *	Page in all of the pages that have been paged out for an object
@@ -1787,62 +1738,95 @@ static void
 swap_pager_swapoff_object(struct swdevt *sp, vm_object_t object)
 {
 	struct swblk *sb;
-	vm_pindex_t pi, s_pindex;
-	daddr_t blk, n_blks, s_blk;
-	int i;
+	vm_page_t m;
+	vm_pindex_t pi;
+	daddr_t blk;
+	int i, nv, rahead, rv;
 
 	KASSERT(object->type == OBJT_SWAP,
 	    ("%s: Object not swappable", __func__));
-	n_blks = 0;
+
 	for (pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE(
 	    &object->un_pager.swp.swp_blks, pi)) != NULL; ) {
+		if ((object->flags & OBJ_DEAD) != 0) {
+			/*
+			 * Make sure that pending writes finish before
+			 * returning.
+			 */
+			vm_object_pip_wait(object, "swpoff");
+			swp_pager_meta_free_all(object);
+			break;
+		}
 		for (i = 0; i < SWAP_META_PAGES; i++) {
-			blk = sb->d[i];
-			if (!swp_pager_isondev(blk, sp))
-				blk = SWAPBLK_NONE;
-
 			/*
-			 * If there are no blocks/pages accumulated, start a new
-			 * accumulation here.
+			 * Count the number of contiguous valid blocks.
 			 */
-			if (n_blks == 0) {
-				if (blk != SWAPBLK_NONE) {
-					s_blk = blk;
-					s_pindex = sb->p + i;
-					n_blks = 1;
-				}
-				continue;
+			for (nv = 0; nv < SWAP_META_PAGES - i; nv++) {
+				blk = sb->d[i + nv];
+				if (!swp_pager_isondev(blk, sp) ||
+				    blk == SWAPBLK_NONE)
+					break;
 			}
+			if (nv == 0)
+				continue;
 
 			/*
-			 * If the accumulation can be extended without breaking
-			 * the sequence of consecutive blocks and pages that
-			 * swp_pager_force_pagein() depends on, do so.
+			 * Look for a page corresponding to the first
+			 * valid block and ensure that any pending paging
+			 * operations on it are complete.  If the page is valid,
+			 * mark it dirty and free the swap block.  Try to batch
+			 * this operation since it may cause sp to be freed,
+			 * meaning that we must restart the scan.  Avoid busying
+			 * valid pages since we may block forever on kernel
+			 * stack pages.
 			 */
-			if (n_blks < MAXPHYS / PAGE_SIZE &&
-			    s_blk + n_blks == blk &&
-			    s_pindex + n_blks == sb->p + i) {
-				++n_blks;
-				continue;
+			m = vm_page_lookup(object, sb->p + i);
+			if (m == NULL) {
+				m = vm_page_alloc(object, sb->p + i,
+				    VM_ALLOC_NORMAL | VM_ALLOC_WAITFAIL);
+				if (m == NULL)
+					break;
+			} else {
+				if ((m->oflags & VPO_SWAPINPROG) != 0) {
+					m->oflags |= VPO_SWAPSLEEP;
+					VM_OBJECT_SLEEP(object, &object->handle,
+					    PSWP, "swpoff", 0);
+					break;
+				}
+				if (vm_page_all_valid(m)) {
+					do {
+						swp_pager_force_dirty(m);
+					} while (--nv > 0 &&
+					    (m = vm_page_next(m)) != NULL &&
+					    vm_page_all_valid(m) &&
+					    (m->oflags & VPO_SWAPINPROG) == 0);
+					break;
+				}
+				if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL))
+					break;
 			}
 
+			vm_object_pip_add(object, 1);
+			rahead = SWAP_META_PAGES;
+			rv = swap_pager_getpages_locked(object, &m, 1, NULL,
+			    &rahead);
+			if (rv != VM_PAGER_OK)
+				panic("%s: read from swap failed: %d",
+				    __func__, rv);
+			vm_object_pip_wakeupn(object, 1);
+			VM_OBJECT_WLOCK(object);
+			vm_page_xunbusy(m);
+
 			/*
-			 * The sequence of consecutive blocks and pages cannot
-			 * be extended, so page them all in here.  Then,
-			 * because doing so involves releasing and reacquiring
-			 * a lock that protects the swap block pctrie, do not
-			 * rely on the current swap block.  Break this loop and
-			 * re-fetch the same pindex from the pctrie again.
+			 * The object lock was dropped so we must restart the

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002172027.01HKR6l8077920>