Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 28 Nov 2016 05:07:48 +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: r309225 - in head/sys/dev/hyperv: include vmbus
Message-ID:  <201611280507.uAS57mmf081698@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: sephe
Date: Mon Nov 28 05:07:48 2016
New Revision: 309225
URL: https://svnweb.freebsd.org/changeset/base/309225

Log:
  hyperv/vmbus: Add supportive transaction wait function.
  
  This function supports channel revocation properly.
  
  MFC after:	1 week
  Sponsored by:	Microsoft
  Differential Revision:	https://reviews.freebsd.org/D8611

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

Modified: head/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- head/sys/dev/hyperv/include/vmbus.h	Mon Nov 28 04:53:36 2016	(r309224)
+++ head/sys/dev/hyperv/include/vmbus.h	Mon Nov 28 05:07:48 2016	(r309225)
@@ -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: head/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chan.c	Mon Nov 28 04:53:36 2016	(r309224)
+++ head/sys/dev/hyperv/vmbus/vmbus_chan.c	Mon Nov 28 05:07:48 2016	(r309225)
@@ -1927,3 +1927,37 @@ vmbus_chan_unset_orphan(struct vmbus_cha
 	chan->ch_orphan_xact = NULL;
 	sx_xunlock(&chan->ch_orphan_lock);
 }
+
+const void *
+vmbus_chan_xact_wait(const struct vmbus_channel *chan,
+    struct vmbus_xact *xact, size_t *resp_len, bool can_sleep)
+{
+	const void *ret;
+
+	if (can_sleep)
+		ret = vmbus_xact_wait(xact, resp_len);
+	else
+		ret = vmbus_xact_busywait(xact, resp_len);
+	if (vmbus_chan_is_revoked(chan)) {
+		/*
+		 * This xact probably is interrupted, and the
+		 * interruption can race the reply reception,
+		 * so we have to make sure that there are nothing
+		 * left on the RX bufring, i.e. this xact will
+		 * not be touched, once this function returns.
+		 *
+		 * Since the hypervisor will not put more data
+		 * onto the RX bufring once the channel is revoked,
+		 * the following loop will be terminated, once all
+		 * data are drained by the driver's channel
+		 * callback.
+		 */
+		while (!vmbus_chan_rx_empty(chan)) {
+			if (can_sleep)
+				pause("chxact", 1);
+			else
+				DELAY(1000);
+		}
+	}
+	return (ret);
+}



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