Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 24 Nov 2016 05:18:45 +0000 (UTC)
From:      Sepherosa Ziehau <sephe@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r309081 - in head/sys/dev/hyperv: include vmbus
Message-ID:  <201611240518.uAO5IjGs048445@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Thu Nov 24 05:18:45 2016
New Revision: 309081
URL: https://svnweb.freebsd.org/changeset/base/309081

Log:
  hyperv/vmbus: Fix the primary channel revoking on vmbus side.
  
  Drivers can now use vmbus_chan_{is_revoked,set_orphan,unset_orphan}() and
  vmbus_xact_ctx_orphan() to fix their attach/detach DEVMETHODs for revoked
  primary channels.
  
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D8545

Modified:
  head/sys/dev/hyperv/include/vmbus.h
  head/sys/dev/hyperv/vmbus/vmbus_chan.c
  head/sys/dev/hyperv/vmbus/vmbus_chanvar.h

Modified: head/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- head/sys/dev/hyperv/include/vmbus.h	Thu Nov 24 04:58:13 2016	(r309080)
+++ head/sys/dev/hyperv/include/vmbus.h	Thu Nov 24 05:18:45 2016	(r309081)
@@ -116,6 +116,7 @@ struct vmbus_chan_br {
 };
 
 struct vmbus_channel;
+struct vmbus_xact_ctx;
 struct hyperv_guid;
 struct task;
 struct taskqueue;
@@ -138,6 +139,9 @@ void		vmbus_chan_close(struct vmbus_chan
 void		vmbus_chan_intr_drain(struct vmbus_channel *chan);
 void		vmbus_chan_run_task(struct vmbus_channel *chan,
 		    struct task *task);
+void		vmbus_chan_set_orphan(struct vmbus_channel *chan,
+		    struct vmbus_xact_ctx *);
+void		vmbus_chan_unset_orphan(struct vmbus_channel *chan);
 
 int		vmbus_chan_gpadl_connect(struct vmbus_channel *chan,
 		    bus_addr_t paddr, int size, uint32_t *gpadl);

Modified: head/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chan.c	Thu Nov 24 04:58:13 2016	(r309080)
+++ head/sys/dev/hyperv/vmbus/vmbus_chan.c	Thu Nov 24 05:18:45 2016	(r309081)
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/stdarg.h>
 
 #include <dev/hyperv/include/hyperv_busdma.h>
+#include <dev/hyperv/include/vmbus_xact.h>
 #include <dev/hyperv/vmbus/hyperv_var.h>
 #include <dev/hyperv/vmbus/vmbus_reg.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
@@ -1115,6 +1116,7 @@ vmbus_chan_alloc(struct vmbus_softc *sc)
 
 	chan->ch_vmbus = sc;
 	mtx_init(&chan->ch_subchan_lock, "vmbus subchan", NULL, MTX_DEF);
+	sx_init(&chan->ch_orphan_lock, "vmbus chorphan");
 	TAILQ_INIT(&chan->ch_subchans);
 	vmbus_rxbr_init(&chan->ch_rxbr);
 	vmbus_txbr_init(&chan->ch_txbr);
@@ -1133,8 +1135,12 @@ vmbus_chan_free(struct vmbus_channel *ch
 	     VMBUS_CHAN_ST_ONPRIL |
 	     VMBUS_CHAN_ST_ONSUBL |
 	     VMBUS_CHAN_ST_ONLIST)) == 0, ("free busy channel"));
+	KASSERT(chan->ch_orphan_xact == NULL,
+	    ("still has orphan xact installed"));
+
 	hyperv_dmamem_free(&chan->ch_monprm_dma, chan->ch_monprm);
 	mtx_destroy(&chan->ch_subchan_lock);
+	sx_destroy(&chan->ch_orphan_lock);
 	vmbus_rxbr_deinit(&chan->ch_rxbr);
 	vmbus_txbr_deinit(&chan->ch_txbr);
 	free(chan, M_DEVBUF);
@@ -1403,10 +1409,21 @@ vmbus_chan_msgproc_chrescind(struct vmbu
 		mtx_unlock(&sc->vmbus_prichan_lock);
 	}
 
+	/*
+	 * NOTE:
+	 * The following processing order is critical:
+	 * Set the REVOKED state flag before orphaning the installed xact.
+	 */
+
 	if (atomic_testandset_int(&chan->ch_stflags,
 	    VMBUS_CHAN_ST_REVOKED_SHIFT))
 		panic("channel has already been revoked");
 
+	sx_xlock(&chan->ch_orphan_lock);
+	if (chan->ch_orphan_xact != NULL)
+		vmbus_xact_ctx_orphan(chan->ch_orphan_xact);
+	sx_xunlock(&chan->ch_orphan_lock);
+
 	if (bootverbose)
 		vmbus_chan_printf(chan, "chan%u revoked\n", note->chm_chanid);
 
@@ -1708,3 +1725,21 @@ vmbus_chan_is_revoked(const struct vmbus
 		return (true);
 	return (false);
 }
+
+void
+vmbus_chan_set_orphan(struct vmbus_channel *chan, struct vmbus_xact_ctx *xact)
+{
+
+	sx_xlock(&chan->ch_orphan_lock);
+	chan->ch_orphan_xact = xact;
+	sx_xunlock(&chan->ch_orphan_lock);
+}
+
+void
+vmbus_chan_unset_orphan(struct vmbus_channel *chan)
+{
+
+	sx_xlock(&chan->ch_orphan_lock);
+	chan->ch_orphan_xact = NULL;
+	sx_xunlock(&chan->ch_orphan_lock);
+}

Modified: head/sys/dev/hyperv/vmbus/vmbus_chanvar.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chanvar.h	Thu Nov 24 04:58:13 2016	(r309080)
+++ head/sys/dev/hyperv/vmbus/vmbus_chanvar.h	Thu Nov 24 05:18:45 2016	(r309081)
@@ -33,8 +33,9 @@
 #include <sys/lock.h>
 #include <sys/mutex.h>
 #include <sys/queue.h>
-#include <sys/taskqueue.h>
 #include <sys/sysctl.h>
+#include <sys/sx.h>
+#include <sys/taskqueue.h>
 
 #include <dev/hyperv/include/hyperv.h>
 #include <dev/hyperv/include/hyperv_busdma.h>
@@ -138,6 +139,9 @@ struct vmbus_channel {
 	struct hyperv_guid		ch_guid_type;
 	struct hyperv_guid		ch_guid_inst;
 
+	struct sx			ch_orphan_lock;
+	struct vmbus_xact_ctx		*ch_orphan_xact;
+
 	struct sysctl_ctx_list		ch_sysctl_ctx;
 } __aligned(CACHE_LINE_SIZE);
 



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