Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Nov 2016 20:16:02 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r309263 - in projects/clang391-import: bin/kenv release/packages sys/arm64/include sys/cddl/contrib/opensolaris/uts/common/fs/zfs sys/dev/ahci sys/dev/ath sys/dev/hyperv/include sys/dev...
Message-ID:  <201611282016.uASKG2cp050065@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Mon Nov 28 20:16:02 2016
New Revision: 309263
URL: https://svnweb.freebsd.org/changeset/base/309263

Log:
  Merge ^/head r309213 through r309262.

Added:
  projects/clang391-import/release/packages/lld.ucl
     - copied unchanged from r309262, head/release/packages/lld.ucl
  projects/clang391-import/release/packages/lldb.ucl
     - copied unchanged from r309262, head/release/packages/lldb.ucl
Modified:
  projects/clang391-import/bin/kenv/kenv.c
  projects/clang391-import/release/packages/clang.ucl
  projects/clang391-import/sys/arm64/include/armreg.h
  projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
  projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
  projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
  projects/clang391-import/sys/dev/ahci/ahci.c
  projects/clang391-import/sys/dev/ahci/ahci_pci.c
  projects/clang391-import/sys/dev/ath/if_ath.c
  projects/clang391-import/sys/dev/ath/if_ath_beacon.c
  projects/clang391-import/sys/dev/ath/if_ath_ioctl.c
  projects/clang391-import/sys/dev/ath/if_ath_misc.h
  projects/clang391-import/sys/dev/ath/if_ath_rx.c
  projects/clang391-import/sys/dev/ath/if_ath_tx_edma.c
  projects/clang391-import/sys/dev/ath/if_athioctl.h
  projects/clang391-import/sys/dev/hyperv/include/vmbus.h
  projects/clang391-import/sys/dev/hyperv/include/vmbus_xact.h
  projects/clang391-import/sys/dev/hyperv/netvsc/hn_nvs.c
  projects/clang391-import/sys/dev/hyperv/netvsc/hn_rndis.c
  projects/clang391-import/sys/dev/hyperv/netvsc/if_hn.c
  projects/clang391-import/sys/dev/hyperv/netvsc/if_hnvar.h
  projects/clang391-import/sys/dev/hyperv/vmbus/vmbus.c
  projects/clang391-import/sys/dev/hyperv/vmbus/vmbus_chan.c
  projects/clang391-import/sys/dev/hyperv/vmbus/vmbus_var.h
  projects/clang391-import/sys/dev/hyperv/vmbus/vmbus_xact.c
  projects/clang391-import/sys/dev/usb/wlan/if_rsu.c
  projects/clang391-import/sys/dev/usb/wlan/if_rsureg.h
  projects/clang391-import/sys/netinet/ip_fastfwd.c
  projects/clang391-import/usr.bin/clang/clang.prog.mk
  projects/clang391-import/usr.bin/clang/lld/Makefile
  projects/clang391-import/usr.bin/clang/lldb/Makefile
  projects/clang391-import/usr.bin/clang/llvm.prog.mk
  projects/clang391-import/usr.bin/indent/indent.c
  projects/clang391-import/usr.bin/indent/indent_codes.h
  projects/clang391-import/usr.bin/indent/lexi.c
  projects/clang391-import/usr.bin/indent/parse.c
  projects/clang391-import/usr.bin/indent/pr_comment.c
  projects/clang391-import/usr.bin/sort/bwstring.c
  projects/clang391-import/usr.bin/sort/sort.c
  projects/clang391-import/usr.sbin/ctld/ctld.c
  projects/clang391-import/usr.sbin/syslogd/syslogd.c
Directory Properties:
  projects/clang391-import/   (props changed)
  projects/clang391-import/sys/cddl/contrib/opensolaris/   (props changed)

Modified: projects/clang391-import/bin/kenv/kenv.c
==============================================================================
--- projects/clang391-import/bin/kenv/kenv.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/bin/kenv/kenv.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -63,7 +63,6 @@ main(int argc, char **argv)
 	char *env, *eq, *val;
 	int ch, error;
 
-	error = 0;
 	val = NULL;
 	env = NULL;
 	while ((ch = getopt(argc, argv, "hNquv")) != -1) {
@@ -128,7 +127,7 @@ main(int argc, char **argv)
 static int
 kdumpenv(void)
 {
-	char *buf, *cp;
+	char *buf, *bp, *cp;
 	int buflen, envlen;
 
 	envlen = kenv(KENV_DUMP, NULL, NULL, 0);
@@ -136,10 +135,9 @@ kdumpenv(void)
 		return (-1);
 	for (;;) {
 		buflen = envlen * 120 / 100;
-		buf = malloc(buflen + 1);
+		buf = calloc(1, buflen + 1);
 		if (buf == NULL)
 			return (-1);
-		memset(buf, 0, buflen + 1);	/* Be defensive */
 		envlen = kenv(KENV_DUMP, NULL, buf, buflen);
 		if (envlen < 0) {
 			free(buf);
@@ -151,21 +149,23 @@ kdumpenv(void)
 			break;
 	}
 
-	for (; *buf != '\0'; buf += strlen(buf) + 1) {
+	for (bp = buf; *bp != '\0'; bp += strlen(bp) + 1) {
 		if (hflag) {
-			if (strncmp(buf, "hint.", 5) != 0)
+			if (strncmp(bp, "hint.", 5) != 0)
 				continue;
 		}
-		cp = strchr(buf, '=');
+		cp = strchr(bp, '=');
 		if (cp == NULL)
 			continue;
 		*cp++ = '\0';
 		if (Nflag)
-			printf("%s\n", buf);
+			printf("%s\n", bp);
 		else
-			printf("%s=\"%s\"\n", buf, cp);
-		buf = cp;
+			printf("%s=\"%s\"\n", bp, cp);
+		bp = cp;
 	}
+
+	free(buf);
 	return (0);
 }
 
@@ -190,7 +190,7 @@ ksetenv(const char *env, char *val)
 {
 	int ret;
 
-	ret = kenv(KENV_SET, env, val, strlen(val)+1);
+	ret = kenv(KENV_SET, env, val, strlen(val) + 1);
 	if (ret == 0)
 		printf("%s=\"%s\"\n", env, val);
 	return (ret);
@@ -200,7 +200,7 @@ static int
 kunsetenv(const char *env)
 {
 	int ret;
-	
+
 	ret = kenv(KENV_UNSET, env, NULL, 0);
 	return (ret);
 }

Modified: projects/clang391-import/release/packages/clang.ucl
==============================================================================
--- projects/clang391-import/release/packages/clang.ucl	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/release/packages/clang.ucl	Mon Nov 28 20:16:02 2016	(r309263)
@@ -11,7 +11,7 @@ maintainer = "re@FreeBSD.org"
 www = "https://www.FreeBSD.org"
 prefix = "/"
 licenselogic = "single"
-licenses = [ BSD2CLAUSE ]
+licenses = [ NCSA ]
 desc = <<EOD
 %DESC%
 EOD

Copied: projects/clang391-import/release/packages/lld.ucl (from r309262, head/release/packages/lld.ucl)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/clang391-import/release/packages/lld.ucl	Mon Nov 28 20:16:02 2016	(r309263, copy of r309262, head/release/packages/lld.ucl)
@@ -0,0 +1,24 @@
+#
+# $FreeBSD$
+#
+
+name = "FreeBSD-%PKGNAME%"
+origin = "base"
+version = "%VERSION%"
+comment = "%COMMENT%"
+categories = [ base ]
+maintainer = "re@FreeBSD.org"
+www = "https://www.FreeBSD.org"
+prefix = "/"
+licenselogic = "single"
+licenses = [ NCSA ]
+desc = <<EOD
+%DESC%
+EOD
+deps: {
+    FreeBSD-%PKGDEPS%: {
+        origin: "base",
+        version: "%VERSION%"
+    }
+}
+

Copied: projects/clang391-import/release/packages/lldb.ucl (from r309262, head/release/packages/lldb.ucl)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/clang391-import/release/packages/lldb.ucl	Mon Nov 28 20:16:02 2016	(r309263, copy of r309262, head/release/packages/lldb.ucl)
@@ -0,0 +1,24 @@
+#
+# $FreeBSD$
+#
+
+name = "FreeBSD-%PKGNAME%"
+origin = "base"
+version = "%VERSION%"
+comment = "%COMMENT%"
+categories = [ base ]
+maintainer = "re@FreeBSD.org"
+www = "https://www.FreeBSD.org"
+prefix = "/"
+licenselogic = "single"
+licenses = [ NCSA ]
+desc = <<EOD
+%DESC%
+EOD
+deps: {
+    FreeBSD-%PKGDEPS%: {
+        origin: "base",
+        version: "%VERSION%"
+    }
+}
+

Modified: projects/clang391-import/sys/arm64/include/armreg.h
==============================================================================
--- projects/clang391-import/sys/arm64/include/armreg.h	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/arm64/include/armreg.h	Mon Nov 28 20:16:02 2016	(r309263)
@@ -89,7 +89,7 @@
 #define	 ISS_DATa_CM		(0x01 << 8)
 #define	 ISS_INSN_S1PTW		(0x01 << 7)
 #define	 ISS_DATa_WnR		(0x01 << 6)
-#define	 ISS_DATA_DFSC_MASK	(0x1f << 0)
+#define	 ISS_DATA_DFSC_MASK	(0x3f << 0)
 #define	 ISS_DATA_DFSC_ASF_L0	(0x00 << 0)
 #define	 ISS_DATA_DFSC_ASF_L1	(0x01 << 0)
 #define	 ISS_DATA_DFSC_ASF_L2	(0x02 << 0)

Modified: projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
==============================================================================
--- projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -20,7 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2013 Steven Hartland. All rights reserved.
  * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
@@ -681,9 +681,16 @@ dsl_pool_sync_done(dsl_pool_t *dp, uint6
 {
 	zilog_t *zilog;
 
-	while (zilog = txg_list_remove(&dp->dp_dirty_zilogs, txg)) {
+	while (zilog = txg_list_head(&dp->dp_dirty_zilogs, txg)) {
 		dsl_dataset_t *ds = dmu_objset_ds(zilog->zl_os);
+		/*
+		 * We don't remove the zilog from the dp_dirty_zilogs
+		 * list until after we've cleaned it. This ensures that
+		 * callers of zilog_is_dirty() receive an accurate
+		 * answer when they are racing with the spa sync thread.
+		 */
 		zil_clean(zilog, txg);
+		(void) txg_list_remove_this(&dp->dp_dirty_zilogs, zilog, txg);
 		ASSERT(!dmu_objset_is_dirty(zilog->zl_os, txg));
 		dmu_buf_rele(ds->ds_dbuf, zilog);
 	}

Modified: projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c
==============================================================================
--- projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -7086,8 +7086,6 @@ spa_sync(spa_t *spa, uint64_t txg)
 		spa->spa_config_syncing = NULL;
 	}
 
-	spa->spa_ubsync = spa->spa_uberblock;
-
 	dsl_pool_sync_done(dp, txg);
 
 	mutex_enter(&spa->spa_alloc_lock);
@@ -7112,6 +7110,13 @@ spa_sync(spa_t *spa, uint64_t txg)
 
 	spa->spa_sync_pass = 0;
 
+	/*
+	 * Update the last synced uberblock here. We want to do this at
+	 * the end of spa_sync() so that consumers of spa_last_synced_txg()
+	 * will be guaranteed that all the processing associated with
+	 * that txg has been completed.
+	 */
+	spa->spa_ubsync = spa->spa_uberblock;
 	spa_config_exit(spa, SCL_CONFIG, FTAG);
 
 	spa_handle_ignored_writes(spa);

Modified: projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c
==============================================================================
--- projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -20,8 +20,7 @@
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2011, 2015 by Delphix. All rights reserved.
- * Copyright (c) 2011, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2011, 2016 by Delphix. All rights reserved.
  * Copyright (c) 2014 Integros [integros.com]
  */
 
@@ -502,6 +501,27 @@ zilog_dirty(zilog_t *zilog, uint64_t txg
 	}
 }
 
+/*
+ * Determine if the zil is dirty in the specified txg. Callers wanting to
+ * ensure that the dirty state does not change must hold the itxg_lock for
+ * the specified txg. Holding the lock will ensure that the zil cannot be
+ * dirtied (zil_itx_assign) or cleaned (zil_clean) while we check its current
+ * state.
+ */
+boolean_t
+zilog_is_dirty_in_txg(zilog_t *zilog, uint64_t txg)
+{
+	dsl_pool_t *dp = zilog->zl_dmu_pool;
+
+	if (txg_list_member(&dp->dp_dirty_zilogs, zilog, txg & TXG_MASK))
+		return (B_TRUE);
+	return (B_FALSE);
+}
+
+/*
+ * Determine if the zil is dirty. The zil is considered dirty if it has
+ * any pending itx records that have not been cleaned by zil_clean().
+ */
 boolean_t
 zilog_is_dirty(zilog_t *zilog)
 {
@@ -1062,8 +1082,6 @@ zil_lwb_commit(zilog_t *zilog, itx_t *it
 		return (NULL);
 
 	ASSERT(lwb->lwb_buf != NULL);
-	ASSERT(zilog_is_dirty(zilog) ||
-	    spa_freeze_txg(zilog->zl_spa) != UINT64_MAX);
 
 	if (lrc->lrc_txtype == TX_WRITE && itx->itx_wr_state == WR_NEED_COPY)
 		dlen = P2ROUNDUP_TYPED(
@@ -1401,6 +1419,11 @@ zil_get_commit_list(zilog_t *zilog)
 	else
 		otxg = spa_last_synced_txg(zilog->zl_spa) + 1;
 
+	/*
+	 * This is inherently racy, since there is nothing to prevent
+	 * the last synced txg from changing. That's okay since we'll
+	 * only commit things in the future.
+	 */
 	for (txg = otxg; txg < (otxg + TXG_CONCURRENT_STATES); txg++) {
 		itxg_t *itxg = &zilog->zl_itxg[txg & TXG_MASK];
 
@@ -1410,6 +1433,16 @@ zil_get_commit_list(zilog_t *zilog)
 			continue;
 		}
 
+		/*
+		 * If we're adding itx records to the zl_itx_commit_list,
+		 * then the zil better be dirty in this "txg". We can assert
+		 * that here since we're holding the itxg_lock which will
+		 * prevent spa_sync from cleaning it. Once we add the itxs
+		 * to the zl_itx_commit_list we must commit it to disk even
+		 * if it's unnecessary (i.e. the txg was synced).
+		 */
+		ASSERT(zilog_is_dirty_in_txg(zilog, txg) ||
+		    spa_freeze_txg(zilog->zl_spa) != UINT64_MAX);
 		list_move_tail(commit_list, &itxg->itxg_itxs->i_sync_list);
 
 		mutex_exit(&itxg->itxg_lock);
@@ -1432,6 +1465,10 @@ zil_async_to_sync(zilog_t *zilog, uint64
 	else
 		otxg = spa_last_synced_txg(zilog->zl_spa) + 1;
 
+	/*
+	 * This is inherently racy, since there is nothing to prevent
+	 * the last synced txg from changing.
+	 */
 	for (txg = otxg; txg < (otxg + TXG_CONCURRENT_STATES); txg++) {
 		itxg_t *itxg = &zilog->zl_itxg[txg & TXG_MASK];
 
@@ -1503,8 +1540,14 @@ zil_commit_writer(zilog_t *zilog)
 	DTRACE_PROBE1(zil__cw1, zilog_t *, zilog);
 	while (itx = list_head(&zilog->zl_itx_commit_list)) {
 		txg = itx->itx_lr.lrc_txg;
-		ASSERT(txg);
+		ASSERT3U(txg, !=, 0);
 
+		/*
+		 * This is inherently racy and may result in us writing
+		 * out a log block for a txg that was just synced. This is
+		 * ok since we'll end cleaning up that log block the next
+		 * time we call zil_sync().
+		 */
 		if (txg > spa_last_synced_txg(spa) || txg > spa_freeze_txg(spa))
 			lwb = zil_lwb_commit(zilog, itx, lwb);
 		list_remove(&zilog->zl_itx_commit_list, itx);
@@ -1821,7 +1864,10 @@ zil_close(zilog_t *zilog)
 	mutex_exit(&zilog->zl_lock);
 	if (txg)
 		txg_wait_synced(zilog->zl_dmu_pool, txg);
-	ASSERT(!zilog_is_dirty(zilog));
+
+	if (zilog_is_dirty(zilog))
+		zfs_dbgmsg("zil (%p) is dirty, txg %llu", zilog, txg);
+	VERIFY(!zilog_is_dirty(zilog));
 
 	taskq_destroy(zilog->zl_clean_taskq);
 	zilog->zl_clean_taskq = NULL;

Modified: projects/clang391-import/sys/dev/ahci/ahci.c
==============================================================================
--- projects/clang391-import/sys/dev/ahci/ahci.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ahci/ahci.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -1169,8 +1169,6 @@ ahci_ch_intr(void *arg)
 
 	/* Read interrupt statuses. */
 	istatus = ATA_INL(ch->r_mem, AHCI_P_IS);
-	if (istatus == 0)
-		return;
 
 	mtx_lock(&ch->mtx);
 	ahci_ch_intr_main(ch, istatus);
@@ -1187,8 +1185,6 @@ ahci_ch_intr_direct(void *arg)
 
 	/* Read interrupt statuses. */
 	istatus = ATA_INL(ch->r_mem, AHCI_P_IS);
-	if (istatus == 0)
-		return;
 
 	mtx_lock(&ch->mtx);
 	ch->batch = 1;

Modified: projects/clang391-import/sys/dev/ahci/ahci_pci.c
==============================================================================
--- projects/clang391-import/sys/dev/ahci/ahci_pci.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ahci/ahci_pci.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -73,8 +73,15 @@ static const struct {
 	{0x78021022, 0x00, "AMD Hudson-2",	0},
 	{0x78031022, 0x00, "AMD Hudson-2",	0},
 	{0x78041022, 0x00, "AMD Hudson-2",	0},
-	{0x06111b21, 0x00, "ASMedia ASM2106",	0},
-	{0x06121b21, 0x00, "ASMedia ASM1061",	0},
+	{0x06011b21, 0x00, "ASMedia ASM1060",	0},
+	{0x06021b21, 0x00, "ASMedia ASM1060",	0},
+	{0x06111b21, 0x00, "ASMedia ASM1061",	0},
+	{0x06121b21, 0x00, "ASMedia ASM1062",	0},
+	{0x06201b21, 0x00, "ASMedia ASM106x",	0},
+	{0x06211b21, 0x00, "ASMedia ASM106x",	0},
+	{0x06221b21, 0x00, "ASMedia ASM106x",	0},
+	{0x06241b21, 0x00, "ASMedia ASM106x",	0},
+	{0x06251b21, 0x00, "ASMedia ASM106x",	0},
 	{0x26528086, 0x00, "Intel ICH6",	AHCI_Q_NOFORCE},
 	{0x26538086, 0x00, "Intel ICH6M",	AHCI_Q_NOFORCE},
 	{0x26818086, 0x00, "Intel ESB2",	0},

Modified: projects/clang391-import/sys/dev/ath/if_ath.c
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -285,22 +285,40 @@ ath_legacy_attach_comp_func(struct ath_s
  * the hardware is being programmed elsewhere, it will
  * simply store it away and update it when all current
  * uses of the hardware are completed.
+ *
+ * If the chip is going into network sleep or power off, then
+ * we will wait until all uses of the chip are done before
+ * going into network sleep or power off.
+ *
+ * If the chip is being programmed full-awake, then immediately
+ * program it full-awake so we can actually stay awake rather than
+ * the chip potentially going to sleep underneath us.
  */
 void
-_ath_power_setpower(struct ath_softc *sc, int power_state, const char *file, int line)
+_ath_power_setpower(struct ath_softc *sc, int power_state, int selfgen,
+    const char *file, int line)
 {
 	ATH_LOCK_ASSERT(sc);
 
-	sc->sc_target_powerstate = power_state;
-
-	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) state=%d, refcnt=%d\n",
+	DPRINTF(sc, ATH_DEBUG_PWRSAVE, "%s: (%s:%d) state=%d, refcnt=%d, target=%d, cur=%d\n",
 	    __func__,
 	    file,
 	    line,
 	    power_state,
-	    sc->sc_powersave_refcnt);
+	    sc->sc_powersave_refcnt,
+	    sc->sc_target_powerstate,
+	    sc->sc_cur_powerstate);
 
-	if (sc->sc_powersave_refcnt == 0 &&
+	sc->sc_target_powerstate = power_state;
+
+	/*
+	 * Don't program the chip into network sleep if the chip
+	 * is being programmed elsewhere.
+	 *
+	 * However, if the chip is being programmed /awake/, force
+	 * the chip awake so we stay awake.
+	 */
+	if ((sc->sc_powersave_refcnt == 0 || power_state == HAL_PM_AWAKE) &&
 	    power_state != sc->sc_cur_powerstate) {
 		sc->sc_cur_powerstate = power_state;
 		ath_hal_setpower(sc->sc_ah, power_state);
@@ -313,7 +331,8 @@ _ath_power_setpower(struct ath_softc *sc
 		 * we let the above call leave the self-gen
 		 * state as "sleep".
 		 */
-		if (sc->sc_cur_powerstate == HAL_PM_AWAKE &&
+		if (selfgen &&
+		    sc->sc_cur_powerstate == HAL_PM_AWAKE &&
 		    sc->sc_target_selfgen_state != HAL_PM_AWAKE) {
 			ath_hal_setselfgenpower(sc->sc_ah,
 			    sc->sc_target_selfgen_state);
@@ -379,10 +398,13 @@ _ath_power_set_power_state(struct ath_so
 
 	sc->sc_powersave_refcnt++;
 
+	/*
+	 * Only do the power state change if we're not programming
+	 * it elsewhere.
+	 */
 	if (power_state != sc->sc_cur_powerstate) {
 		ath_hal_setpower(sc->sc_ah, power_state);
 		sc->sc_cur_powerstate = power_state;
-
 		/*
 		 * Adjust the self-gen powerstate if appropriate.
 		 */
@@ -391,7 +413,6 @@ _ath_power_set_power_state(struct ath_so
 			ath_hal_setselfgenpower(sc->sc_ah,
 			    sc->sc_target_selfgen_state);
 		}
-
 	}
 }
 
@@ -1317,7 +1338,7 @@ ath_attach(u_int16_t devid, struct ath_s
 	 * Put it to sleep for now.
 	 */
 	ATH_LOCK(sc);
-	ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
+	ath_power_setpower(sc, HAL_PM_FULL_SLEEP, 1);
 	ATH_UNLOCK(sc);
 
 	return 0;
@@ -1359,7 +1380,7 @@ ath_detach(struct ath_softc *sc)
 	 */
 	ATH_LOCK(sc);
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_power_setpower(sc, HAL_PM_AWAKE);
+	ath_power_setpower(sc, HAL_PM_AWAKE, 1);
 
 	/*
 	 * Stop things cleanly.
@@ -1942,7 +1963,7 @@ ath_resume(struct ath_softc *sc)
 	ATH_LOCK(sc);
 	ath_power_setselfgen(sc, HAL_PM_AWAKE);
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_power_setpower(sc, HAL_PM_AWAKE);
+	ath_power_setpower(sc, HAL_PM_AWAKE, 1);
 	ATH_UNLOCK(sc);
 
 	ath_hal_reset(ah, sc->sc_opmode,
@@ -2269,8 +2290,13 @@ ath_intr(void *arg)
 			sc->sc_stats.ast_rxorn++;
 		}
 		if (status & HAL_INT_TSFOOR) {
+			/* out of range beacon - wake the chip up,
+			 * but don't modify self-gen frame config */
 			device_printf(sc->sc_dev, "%s: TSFOOR\n", __func__);
 			sc->sc_syncbeacon = 1;
+			ATH_LOCK(sc);
+			ath_power_setpower(sc, HAL_PM_AWAKE, 0);
+			ATH_UNLOCK(sc);
 		}
 		if (status & HAL_INT_MCI) {
 			ath_btcoex_mci_intr(sc);
@@ -2360,12 +2386,22 @@ ath_bmiss_vap(struct ieee80211vap *vap)
 	}
 
 	/*
-	 * There's no need to keep the hardware awake during the call
-	 * to av_bmiss().
+	 * Keep the hardware awake if it's asleep (and leave self-gen
+	 * frame config alone) until the next beacon, so we can resync
+	 * against the next beacon.
+	 *
+	 * This handles three common beacon miss cases in STA powersave mode -
+	 * (a) the beacon TBTT isnt a multiple of bintval;
+	 * (b) the beacon was missed; and
+	 * (c) the beacons are being delayed because the AP is busy and
+	 *     isn't reliably able to meet its TBTT.
 	 */
 	ATH_LOCK(sc);
+	ath_power_setpower(sc, HAL_PM_AWAKE, 0);
 	ath_power_restore_power_state(sc);
 	ATH_UNLOCK(sc);
+	DPRINTF(sc, ATH_DEBUG_BEACON,
+	    "%s: forced awake; force syncbeacon=1\n", __func__);
 
 	/*
 	 * Attempt to force a beacon resync.
@@ -2462,7 +2498,7 @@ ath_init(struct ath_softc *sc)
 	 */
 	ath_power_setselfgen(sc, HAL_PM_AWAKE);
 	ath_power_set_power_state(sc, HAL_PM_AWAKE);
-	ath_power_setpower(sc, HAL_PM_AWAKE);
+	ath_power_setpower(sc, HAL_PM_AWAKE, 1);
 
 	/*
 	 * Stop anything previously setup.  This is safe
@@ -5563,7 +5599,7 @@ ath_newstate(struct ieee80211vap *vap, e
 		/* Ensure we stay awake during scan */
 		ATH_LOCK(sc);
 		ath_power_setselfgen(sc, HAL_PM_AWAKE);
-		ath_power_setpower(sc, HAL_PM_AWAKE);
+		ath_power_setpower(sc, HAL_PM_AWAKE, 1);
 		ATH_UNLOCK(sc);
 
 		ath_hal_intrset(ah,
@@ -5739,7 +5775,7 @@ ath_newstate(struct ieee80211vap *vap, e
 		 */
 		ATH_LOCK(sc);
 		ath_power_setselfgen(sc, HAL_PM_AWAKE);
-		ath_power_setpower(sc, HAL_PM_AWAKE);
+		ath_power_setpower(sc, HAL_PM_AWAKE, 1);
 
 		/*
 		 * Finally, start any timers and the task q thread
@@ -5795,7 +5831,7 @@ ath_newstate(struct ieee80211vap *vap, e
 			 * our beacon timer config may be wrong.
 			 */
 			if (sc->sc_syncbeacon == 0) {
-				ath_power_setpower(sc, HAL_PM_NETWORK_SLEEP);
+				ath_power_setpower(sc, HAL_PM_NETWORK_SLEEP, 1);
 			}
 			ATH_UNLOCK(sc);
 		}
@@ -6177,7 +6213,7 @@ ath_parent(struct ieee80211com *ic)
 	} else {
 		ath_stop(sc);
 		if (!sc->sc_invalid)
-			ath_power_setpower(sc, HAL_PM_FULL_SLEEP);
+			ath_power_setpower(sc, HAL_PM_FULL_SLEEP, 1);
 	}
 	ATH_UNLOCK(sc);
 

Modified: projects/clang391-import/sys/dev/ath/if_ath_beacon.c
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath_beacon.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath_beacon.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -964,10 +964,27 @@ ath_beacon_config(struct ath_softc *sc, 
 		/* NB: the beacon interval is kept internally in TU's */
 		intval = ni->ni_intval & HAL_BEACON_PERIOD;
 	}
+
+	/*
+	 * Note: rounding up to the next intval can cause problems with
+	 * bad APs when we're in powersave mode.
+	 *
+	 * In STA mode with powersave enabled, beacons are only received
+	 * whenever the beacon timer fires to wake up the hardware.
+	 * Now, if this is rounded up to the next intval, it assumes
+	 * that the AP has started transmitting beacons at TSF values that
+	 * are multiples of intval, versus say being 25 TU off.
+	 *
+	 * The specification (802.11-2012 10.1.3.2 - Beacon Generation in
+	 * Infrastructure Networks) requires APs be beaconing at a
+	 * mutiple of intval.  So, if bintval=100, then we shouldn't
+	 * get beacons at intervals other than around multiples of 100.
+	 */
 	if (nexttbtt == 0)		/* e.g. for ap mode */
 		nexttbtt = intval;
-	else if (intval)		/* NB: can be 0 for monitor mode */
+	else
 		nexttbtt = roundup(nexttbtt, intval);
+
 	DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
 		__func__, nexttbtt, intval, ni->ni_intval);
 	if (ic->ic_opmode == IEEE80211_M_STA && !sc->sc_swbmiss) {

Modified: projects/clang391-import/sys/dev/ath/if_ath_ioctl.c
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath_ioctl.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath_ioctl.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -296,6 +296,8 @@ ath_ioctl(struct ieee80211com *ic, u_lon
 		return (ath_ioctl_spectral(sc, data));
 	case SIOCGATHNODERATESTATS:
 		return (ath_ioctl_ratestats(sc, data));
+	case SIOCGATHBTCOEX:
+		return (ath_btcoex_ioctl(sc, data));
 	default:
 		/*
 		 * This signals the net80211 layer that we didn't handle this

Modified: projects/clang391-import/sys/dev/ath/if_ath_misc.h
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath_misc.h	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath_misc.h	Mon Nov 28 20:16:02 2016	(r309263)
@@ -109,15 +109,23 @@ extern void ath_tx_dump(struct ath_softc
 /*
  * Power state tracking.
  */
-extern	void _ath_power_setpower(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_set_selfgen(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_set_power_state(struct ath_softc *sc, int power_state, const char *file, int line);
-extern	void _ath_power_restore_power_state(struct ath_softc *sc, const char *file, int line);
-
-#define	ath_power_setpower(sc, ps) _ath_power_setpower(sc, ps, __FILE__, __LINE__)
-#define	ath_power_setselfgen(sc, ps) _ath_power_set_selfgen(sc, ps, __FILE__, __LINE__)
-#define	ath_power_set_power_state(sc, ps) _ath_power_set_power_state(sc, ps, __FILE__, __LINE__)
-#define	ath_power_restore_power_state(sc) _ath_power_restore_power_state(sc, __FILE__, __LINE__)
+extern	void _ath_power_setpower(struct ath_softc *sc, int power_state,
+	    int selfgen, const char *file, int line);
+extern	void _ath_power_set_selfgen(struct ath_softc *sc,
+	    int power_state, const char *file, int line);
+extern	void _ath_power_set_power_state(struct ath_softc *sc,
+	    int power_state, const char *file, int line);
+extern	void _ath_power_restore_power_state(struct ath_softc *sc,
+	    const char *file, int line);
+
+#define	ath_power_setpower(sc, ps, sg) _ath_power_setpower(sc, ps, sg, \
+	    __FILE__, __LINE__)
+#define	ath_power_setselfgen(sc, ps) _ath_power_set_selfgen(sc, ps, \
+	    __FILE__, __LINE__)
+#define	ath_power_set_power_state(sc, ps) \
+	    _ath_power_set_power_state(sc, ps, __FILE__, __LINE__)
+#define	ath_power_restore_power_state(sc) \
+	    _ath_power_restore_power_state(sc, __FILE__, __LINE__)
 
 /*
  * Kick the frame TX task.

Modified: projects/clang391-import/sys/dev/ath/if_ath_rx.c
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath_rx.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath_rx.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -420,19 +420,24 @@ ath_recv_mgmt(struct ieee80211_node *ni,
 				tsf_remainder = (tsf_beacon - tsf_beacon_old) % tsf_intval;
 			}
 
-			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu, new_tsf=%llu, target_tsf=%llu, delta=%lld, bmiss=%d, remainder=%d\n",
+			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: old_tsf=%llu (%u), new_tsf=%llu (%u), target_tsf=%llu (%u), delta=%lld, bmiss=%d, remainder=%d\n",
 			    __func__,
 			    (unsigned long long) tsf_beacon_old,
+			    (unsigned int) (tsf_beacon_old >> 10),
 			    (unsigned long long) tsf_beacon,
+			    (unsigned int ) (tsf_beacon >> 10),
 			    (unsigned long long) tsf_beacon_target,
+			    (unsigned int) (tsf_beacon_target >> 10),
 			    (long long) tsf_delta,
 			    tsf_delta_bmiss,
 			    tsf_remainder);
 
-			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu, nexttbtt=%llu, delta=%d\n",
+			DPRINTF(sc, ATH_DEBUG_BEACON, "%s: tsf=%llu (%u), nexttbtt=%llu (%u), delta=%d\n",
 			    __func__,
 			    (unsigned long long) tsf_beacon,
+			    (unsigned int) (tsf_beacon >> 10),
 			    (unsigned long long) nexttbtt,
+			    (unsigned int) (nexttbtt >> 10),
 			    (int32_t) tsf_beacon - (int32_t) nexttbtt + tsf_intval);
 
 			/* We only do syncbeacon on STA VAPs; not on IBSS */

Modified: projects/clang391-import/sys/dev/ath/if_ath_tx_edma.c
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_ath_tx_edma.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_ath_tx_edma.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -755,11 +755,30 @@ ath_edma_tx_proc(void *arg, int npending
 {
 	struct ath_softc *sc = (struct ath_softc *) arg;
 
+	ATH_PCU_LOCK(sc);
+	sc->sc_txproc_cnt++;
+	ATH_PCU_UNLOCK(sc);
+
+	ATH_LOCK(sc);
+	ath_power_set_power_state(sc, HAL_PM_AWAKE);
+	ATH_UNLOCK(sc);
+
 #if 0
 	DPRINTF(sc, ATH_DEBUG_TX_PROC, "%s: called, npending=%d\n",
 	    __func__, npending);
 #endif
 	ath_edma_tx_processq(sc, 1);
+
+
+	ATH_PCU_LOCK(sc);
+	sc->sc_txproc_cnt--;
+	ATH_PCU_UNLOCK(sc);
+
+	ATH_LOCK(sc);
+	ath_power_restore_power_state(sc);
+	ATH_UNLOCK(sc);
+
+	ath_tx_kick(sc);
 }
 
 /*

Modified: projects/clang391-import/sys/dev/ath/if_athioctl.h
==============================================================================
--- projects/clang391-import/sys/dev/ath/if_athioctl.h	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/ath/if_athioctl.h	Mon Nov 28 20:16:02 2016	(r309263)
@@ -447,4 +447,9 @@ struct ath_tx_radiotap_header {
 #define	SPECTRAL_CONTROL_ENABLE_AT_RESET	8
 #define	SPECTRAL_CONTROL_DISABLE_AT_RESET	9
 
+/*
+ * Bluetooth coexistence control parameters
+ */
+#define	SIOCGATHBTCOEX		_IOWR('i', 152, struct ath_diag)
+
 #endif /* _DEV_ATH_ATHIOCTL_H */

Modified: projects/clang391-import/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- projects/clang391-import/sys/dev/hyperv/include/vmbus.h	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/hyperv/include/vmbus.h	Mon Nov 28 20:16:02 2016	(r309263)
@@ -116,6 +116,7 @@ struct vmbus_chan_br {
 };
 
 struct vmbus_channel;
+struct vmbus_xact;
 struct vmbus_xact_ctx;
 struct hyperv_guid;
 struct task;
@@ -173,6 +174,8 @@ void		vmbus_chan_run_task(struct vmbus_c
 void		vmbus_chan_set_orphan(struct vmbus_channel *chan,
 		    struct vmbus_xact_ctx *);
 void		vmbus_chan_unset_orphan(struct vmbus_channel *chan);
+const void	*vmbus_chan_xact_wait(const struct vmbus_channel *chan,
+		    struct vmbus_xact *xact, size_t *resp_len, bool can_sleep);
 
 int		vmbus_chan_gpadl_connect(struct vmbus_channel *chan,
 		    bus_addr_t paddr, int size, uint32_t *gpadl);

Modified: projects/clang391-import/sys/dev/hyperv/include/vmbus_xact.h
==============================================================================
--- projects/clang391-import/sys/dev/hyperv/include/vmbus_xact.h	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/hyperv/include/vmbus_xact.h	Mon Nov 28 20:16:02 2016	(r309263)
@@ -55,6 +55,8 @@ const void		*vmbus_xact_wait(struct vmbu
 			    size_t *resp_len);
 const void		*vmbus_xact_busywait(struct vmbus_xact *xact,
 			    size_t *resp_len);
+const void		*vmbus_xact_poll(struct vmbus_xact *xact,
+			    size_t *resp_len);
 void			vmbus_xact_wakeup(struct vmbus_xact *xact,
 			    const void *data, size_t dlen);
 void			vmbus_xact_ctx_wakeup(struct vmbus_xact_ctx *ctx,

Modified: projects/clang391-import/sys/dev/hyperv/netvsc/hn_nvs.c
==============================================================================
--- projects/clang391-import/sys/dev/hyperv/netvsc/hn_nvs.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/hyperv/netvsc/hn_nvs.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -62,8 +62,8 @@ __FBSDID("$FreeBSD$");
 
 static int			hn_nvs_conn_chim(struct hn_softc *);
 static int			hn_nvs_conn_rxbuf(struct hn_softc *);
-static int			hn_nvs_disconn_chim(struct hn_softc *);
-static int			hn_nvs_disconn_rxbuf(struct hn_softc *);
+static void			hn_nvs_disconn_chim(struct hn_softc *);
+static void			hn_nvs_disconn_rxbuf(struct hn_softc *);
 static int			hn_nvs_conf_ndis(struct hn_softc *, int);
 static int			hn_nvs_init_ndis(struct hn_softc *);
 static int			hn_nvs_doinit(struct hn_softc *, uint32_t);
@@ -109,10 +109,8 @@ hn_nvs_xact_execute(struct hn_softc *sc,
 		vmbus_xact_deactivate(xact);
 		return (NULL);
 	}
-	if (HN_CAN_SLEEP(sc))
-		hdr = vmbus_xact_wait(xact, &resplen);
-	else
-		hdr = vmbus_xact_busywait(xact, &resplen);
+	hdr = vmbus_chan_xact_wait(sc->hn_prichan, xact, &resplen,
+	    HN_CAN_SLEEP(sc));
 
 	/*
 	 * Check this NVS response message.
@@ -275,8 +273,14 @@ hn_nvs_conn_chim(struct hn_softc *sc)
 		goto cleanup;
 	}
 	if (sectsz == 0) {
+		/*
+		 * Can't use chimney sending buffer; done!
+		 */
 		if_printf(sc->hn_ifp, "zero chimney sending buffer "
 		    "section size\n");
+		sc->hn_chim_szmax = 0;
+		sc->hn_chim_cnt = 0;
+		sc->hn_flags |= HN_FLAG_CHIM_CONNECTED;
 		return (0);
 	}
 
@@ -310,7 +314,7 @@ cleanup:
 	return (error);
 }
 
-static int
+static void
 hn_nvs_disconn_rxbuf(struct hn_softc *sc)
 {
 	int error;
@@ -330,7 +334,12 @@ hn_nvs_disconn_rxbuf(struct hn_softc *sc
 		if (error) {
 			if_printf(sc->hn_ifp,
 			    "send nvs rxbuf disconn failed: %d\n", error);
-			return (error);
+			/*
+			 * Fine for a revoked channel, since the hypervisor
+			 * does not drain TX bufring for a revoked channel.
+			 */
+			if (!vmbus_chan_is_revoked(sc->hn_prichan))
+				sc->hn_flags |= HN_FLAG_RXBUF_REF;
 		}
 		sc->hn_flags &= ~HN_FLAG_RXBUF_CONNECTED;
 
@@ -359,14 +368,13 @@ hn_nvs_disconn_rxbuf(struct hn_softc *sc
 		if (error) {
 			if_printf(sc->hn_ifp,
 			    "rxbuf gpadl disconn failed: %d\n", error);
-			return (error);
+			sc->hn_flags |= HN_FLAG_RXBUF_REF;
 		}
 		sc->hn_rxbuf_gpadl = 0;
 	}
-	return (0);
 }
 
-static int
+static void
 hn_nvs_disconn_chim(struct hn_softc *sc)
 {
 	int error;
@@ -386,7 +394,12 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
 		if (error) {
 			if_printf(sc->hn_ifp,
 			    "send nvs chim disconn failed: %d\n", error);
-			return (error);
+			/*
+			 * Fine for a revoked channel, since the hypervisor
+			 * does not drain TX bufring for a revoked channel.
+			 */
+			if (!vmbus_chan_is_revoked(sc->hn_prichan))
+				sc->hn_flags |= HN_FLAG_CHIM_REF;
 		}
 		sc->hn_flags &= ~HN_FLAG_CHIM_CONNECTED;
 
@@ -416,7 +429,7 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
 		if (error) {
 			if_printf(sc->hn_ifp,
 			    "chim gpadl disconn failed: %d\n", error);
-			return (error);
+			sc->hn_flags |= HN_FLAG_CHIM_REF;
 		}
 		sc->hn_chim_gpadl = 0;
 	}
@@ -424,8 +437,8 @@ hn_nvs_disconn_chim(struct hn_softc *sc)
 	if (sc->hn_chim_bmap != NULL) {
 		free(sc->hn_chim_bmap, M_DEVBUF);
 		sc->hn_chim_bmap = NULL;
+		sc->hn_chim_bmap_cnt = 0;
 	}
-	return (0);
 }
 
 static int
@@ -614,8 +627,10 @@ hn_nvs_attach(struct hn_softc *sc, int m
 	 * Connect chimney sending buffer.
 	 */
 	error = hn_nvs_conn_chim(sc);
-	if (error)
+	if (error) {
+		hn_nvs_disconn_rxbuf(sc);
 		return (error);
+	}
 	return (0);
 }
 

Modified: projects/clang391-import/sys/dev/hyperv/netvsc/hn_rndis.c
==============================================================================
--- projects/clang391-import/sys/dev/hyperv/netvsc/hn_rndis.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/hyperv/netvsc/hn_rndis.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -232,10 +232,8 @@ hn_rndis_xact_exec1(struct hn_softc *sc,
 		if_printf(sc->hn_ifp, "RNDIS ctrl send failed: %d\n", error);
 		return (NULL);
 	}
-	if (HN_CAN_SLEEP(sc))
-		return (vmbus_xact_wait(xact, comp_len));
-	else
-		return (vmbus_xact_busywait(xact, comp_len));
+	return (vmbus_chan_xact_wait(sc->hn_prichan, xact, comp_len,
+	    HN_CAN_SLEEP(sc)));
 }
 
 static const void *
@@ -981,7 +979,6 @@ hn_rndis_attach(struct hn_softc *sc, int
 
 	/*
 	 * Configure NDIS offload settings.
-	 * XXX no offloading, if error happened?
 	 */
 	hn_rndis_conf_offload(sc, mtu);
 	return (0);

Modified: projects/clang391-import/sys/dev/hyperv/netvsc/if_hn.c
==============================================================================
--- projects/clang391-import/sys/dev/hyperv/netvsc/if_hn.c	Mon Nov 28 20:13:56 2016	(r309262)
+++ projects/clang391-import/sys/dev/hyperv/netvsc/if_hn.c	Mon Nov 28 20:16:02 2016	(r309263)
@@ -296,6 +296,7 @@ static int			hn_synth_attach(struct hn_s
 static void			hn_synth_detach(struct hn_softc *);
 static int			hn_synth_alloc_subchans(struct hn_softc *,
 				    int *);
+static bool			hn_synth_attachable(const struct hn_softc *);
 static void			hn_suspend(struct hn_softc *);
 static void			hn_suspend_data(struct hn_softc *);
 static void			hn_suspend_mgmt(struct hn_softc *);
@@ -318,7 +319,7 @@ static void			hn_destroy_rx_data(struct 
 static int			hn_check_iplen(const struct mbuf *, int);
 static int			hn_set_rxfilter(struct hn_softc *);
 static int			hn_rss_reconfig(struct hn_softc *);
-static void			hn_rss_ind_fixup(struct hn_softc *, int);
+static void			hn_rss_ind_fixup(struct hn_softc *);
 static int			hn_rxpkt(struct hn_rx_ring *, const void *,
 				    int, const struct hn_rxinfo *);
 
@@ -464,7 +465,7 @@ SYSCTL_INT(_hw_hn, OID_AUTO, tx_agg_size
     &hn_tx_agg_size, 0, "Packet transmission aggregation size limit");
 
 /* Packet transmission aggregation count limit */
-static int			hn_tx_agg_pkts = 0;
+static int			hn_tx_agg_pkts = -1;
 SYSCTL_INT(_hw_hn, OID_AUTO, tx_agg_pkts, CTLFLAG_RDTUN,
     &hn_tx_agg_pkts, 0, "Packet transmission aggregation packet limit");
 
@@ -705,6 +706,10 @@ hn_set_txagg(struct hn_softc *sc)
 	if (sc->hn_rndis_agg_size < size)
 		size = sc->hn_rndis_agg_size;
 
+	/* NOTE: We only aggregate packets using chimney sending buffers. */
+	if (size > (uint32_t)sc->hn_chim_szmax)
+		size = sc->hn_chim_szmax;
+
 	if (size <= 2 * HN_PKTSIZE_MIN(sc->hn_rndis_agg_align)) {
 		/* Disable */
 		size = 0;
@@ -716,10 +721,6 @@ hn_set_txagg(struct hn_softc *sc)
 	if (size > INT_MAX)
 		size = INT_MAX;
 
-	/* NOTE: We only aggregate packets using chimney sending buffers. */
-	if (size > (uint32_t)sc->hn_chim_szmax)
-		size = sc->hn_chim_szmax;
-
 	/*
 	 * Setup aggregation packet count.
 	 */
@@ -816,11 +817,12 @@ hn_rss_reconfig(struct hn_softc *sc)
 }
 
 static void
-hn_rss_ind_fixup(struct hn_softc *sc, int nchan)
+hn_rss_ind_fixup(struct hn_softc *sc)
 {
 	struct ndis_rssprm_toeplitz *rss = &sc->hn_rss;
-	int i;
+	int i, nchan;
 
+	nchan = sc->hn_rx_ring_inuse;
 	KASSERT(nchan > 1, ("invalid # of channels %d", nchan));
 
 	/*
@@ -1523,7 +1525,7 @@ hn_txpkt_done(struct hn_nvs_sendctx *snd
 	txr = txd->txr;
 	KASSERT(txr->hn_chan == chan,
 	    ("channel mismatch, on chan%u, should be chan%u",
-	     vmbus_chan_subidx(chan), vmbus_chan_subidx(txr->hn_chan)));
+	     vmbus_chan_id(chan), vmbus_chan_id(txr->hn_chan)));
 
 	txr->hn_has_txeof = 1;
 	hn_txdesc_put(txr, txd);
@@ -2942,7 +2944,7 @@ hn_rss_ind_sysctl(SYSCTL_HANDLER_ARGS)
 		goto back;
 	sc->hn_flags |= HN_FLAG_HAS_RSSIND;
 
-	hn_rss_ind_fixup(sc, sc->hn_rx_ring_inuse);
+	hn_rss_ind_fixup(sc);
 	error = hn_rss_reconfig(sc);
 back:
 	HN_UNLOCK(sc);
@@ -3249,7 +3251,10 @@ hn_destroy_rx_data(struct hn_softc *sc)
 	int i;
 
 	if (sc->hn_rxbuf != NULL) {
-		hyperv_dmamem_free(&sc->hn_rxbuf_dma, sc->hn_rxbuf);
+		if ((sc->hn_flags & HN_FLAG_RXBUF_REF) == 0)
+			hyperv_dmamem_free(&sc->hn_rxbuf_dma, sc->hn_rxbuf);
+		else
+			device_printf(sc->hn_dev, "RXBUF is referenced\n");
 		sc->hn_rxbuf = NULL;
 	}
 
@@ -3261,7 +3266,12 @@ hn_destroy_rx_data(struct hn_softc *sc)
 
 		if (rxr->hn_br == NULL)
 			continue;
-		hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
+		if ((rxr->hn_rx_flags & HN_RX_FLAG_BR_REF) == 0) {
+			hyperv_dmamem_free(&rxr->hn_br_dma, rxr->hn_br);
+		} else {
+			device_printf(sc->hn_dev,
+			    "%dth channel bufring is referenced", i);
+		}
 		rxr->hn_br = NULL;
 
 #if defined(INET) || defined(INET6)
@@ -3730,7 +3740,12 @@ hn_destroy_tx_data(struct hn_softc *sc)
 	int i;

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



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