svn commit: r309245 - head/sys/dev/hyperv/vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Mon Nov 28 07:56:04 UTC 2016
Author: sephe
Date: Mon Nov 28 07:56:03 2016
New Revision: 309245
URL: https://svnweb.freebsd.org/changeset/base/309245
Log:
hyperv/vmbus: Use poll/cancel APIs to wait for the CHOPEN response.
Since hypervisor does not respond CHOPEN to a revoked channel.
MFC after: 1 week
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8636
Modified:
head/sys/dev/hyperv/vmbus/vmbus_chan.c
Modified: head/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Nov 28 07:44:50 2016 (r309244)
+++ head/sys/dev/hyperv/vmbus/vmbus_chan.c Mon Nov 28 07:56:03 2016 (r309245)
@@ -349,7 +349,6 @@ vmbus_chan_open_br(struct vmbus_channel
const void *udata, int udlen, vmbus_chan_callback_t cb, void *cbarg)
{
struct vmbus_softc *sc = chan->ch_vmbus;
- const struct vmbus_chanmsg_chopen_resp *resp;
const struct vmbus_message *msg;
struct vmbus_chanmsg_chopen *req;
struct vmbus_msghc *mh;
@@ -453,9 +452,50 @@ vmbus_chan_open_br(struct vmbus_channel
goto failed;
}
- msg = vmbus_msghc_wait_result(sc, mh);
- resp = (const struct vmbus_chanmsg_chopen_resp *)msg->msg_data;
- status = resp->chm_status;
+ for (;;) {
+ msg = vmbus_msghc_poll_result(sc, mh);
+ if (msg != NULL)
+ break;
+ if (vmbus_chan_is_revoked(chan)) {
+ int i;
+
+ /*
+ * NOTE:
+ * Hypervisor does _not_ send response CHOPEN to
+ * a revoked channel.
+ */
+ vmbus_chan_printf(chan,
+ "chan%u is revoked, when it is being opened\n",
+ chan->ch_id);
+
+ /*
+ * XXX
+ * Add extra delay before cancel the hypercall
+ * execution; mainly to close any possible
+ * CHRESCIND and CHOPEN_RESP races on the
+ * hypervisor side.
+ */
+#define REVOKE_LINGER 100
+ for (i = 0; i < REVOKE_LINGER; ++i) {
+ msg = vmbus_msghc_poll_result(sc, mh);
+ if (msg != NULL)
+ break;
+ DELAY(1000);
+ }
+#undef REVOKE_LINGER
+ if (msg == NULL)
+ vmbus_msghc_exec_cancel(sc, mh);
+ break;
+ }
+ DELAY(1000);
+ }
+ if (msg != NULL) {
+ status = ((const struct vmbus_chanmsg_chopen_resp *)
+ msg->msg_data)->chm_status;
+ } else {
+ /* XXX any non-0 value is ok here. */
+ status = 0xff;
+ }
vmbus_msghc_put(sc, mh);
More information about the svn-src-head
mailing list