svn commit: r311367 - in stable/11/sys/dev/hyperv: include vmbus
Sepherosa Ziehau
sephe at FreeBSD.org
Thu Jan 5 05:46:08 UTC 2017
Author: sephe
Date: Thu Jan 5 05:46:06 2017
New Revision: 311367
URL: https://svnweb.freebsd.org/changeset/base/311367
Log:
MFC 309240,309242,309244,309245,309670
309240
hyperv/vmbus: Add result polling support for xact API.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8633
309242
hyperv/vmbus: Add result polling support for message Hypercall API.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8634
309244
hyperv/vmbus: Add exec cancel support for message Hypercall API.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8635
309245
hyperv/vmbus: Use poll/cancel APIs to wait for the CHOPEN response.
Since hypervisor does not respond CHOPEN to a revoked channel.
Sponsored by: Microsoft
Differential Revision: https://reviews.freebsd.org/D8636
309670
hyperv/vmbus: Use pause if possible.
This makes booting on Hyper-V w/ small # of vCPUs work properly.
Reported by: Hongxiong Xian <v-hoxian microsoft com>, Hongjiang Zhang <honzhan microsoft com>
Sponsored by: Microsoft
Modified:
stable/11/sys/dev/hyperv/include/vmbus_xact.h
stable/11/sys/dev/hyperv/vmbus/vmbus.c
stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
stable/11/sys/dev/hyperv/vmbus/vmbus_var.h
stable/11/sys/dev/hyperv/vmbus/vmbus_xact.c
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/sys/dev/hyperv/include/vmbus_xact.h
==============================================================================
--- stable/11/sys/dev/hyperv/include/vmbus_xact.h Thu Jan 5 05:41:33 2017 (r311366)
+++ stable/11/sys/dev/hyperv/include/vmbus_xact.h Thu Jan 5 05:46:06 2017 (r311367)
@@ -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: stable/11/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus.c Thu Jan 5 05:41:33 2017 (r311366)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus.c Thu Jan 5 05:46:06 2017 (r311367)
@@ -310,6 +310,13 @@ vmbus_msghc_exec(struct vmbus_softc *sc
return error;
}
+void
+vmbus_msghc_exec_cancel(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
+{
+
+ vmbus_xact_deactivate(mh->mh_xact);
+}
+
const struct vmbus_message *
vmbus_msghc_wait_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
{
@@ -318,6 +325,14 @@ vmbus_msghc_wait_result(struct vmbus_sof
return (vmbus_xact_wait(mh->mh_xact, &resp_len));
}
+const struct vmbus_message *
+vmbus_msghc_poll_result(struct vmbus_softc *sc __unused, struct vmbus_msghc *mh)
+{
+ size_t resp_len;
+
+ return (vmbus_xact_poll(mh->mh_xact, &resp_len));
+}
+
void
vmbus_msghc_wakeup(struct vmbus_softc *sc, const struct vmbus_message *msg)
{
Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Jan 5 05:41:33 2017 (r311366)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_chan.c Thu Jan 5 05:46:06 2017 (r311367)
@@ -67,7 +67,7 @@ static void vmbus_chan_set_chmap(struc
static void vmbus_chan_clear_chmap(struct vmbus_channel *);
static void vmbus_chan_detach(struct vmbus_channel *);
static bool vmbus_chan_wait_revoke(
- const struct vmbus_channel *);
+ const struct vmbus_channel *, bool);
static void vmbus_chan_ins_prilist(struct vmbus_softc *,
struct vmbus_channel *);
@@ -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;
+ pause("rchopen", 1);
+ }
+#undef REVOKE_LINGER
+ if (msg == NULL)
+ vmbus_msghc_exec_cancel(sc, mh);
+ break;
+ }
+ pause("chopen", 1);
+ }
+ 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);
@@ -620,7 +660,7 @@ vmbus_chan_gpadl_connect(struct vmbus_ch
}
static bool
-vmbus_chan_wait_revoke(const struct vmbus_channel *chan)
+vmbus_chan_wait_revoke(const struct vmbus_channel *chan, bool can_sleep)
{
#define WAIT_COUNT 200 /* 200ms */
@@ -629,8 +669,10 @@ vmbus_chan_wait_revoke(const struct vmbu
for (i = 0; i < WAIT_COUNT; ++i) {
if (vmbus_chan_is_revoked(chan))
return (true);
- /* Not sure about the context; use busy-wait. */
- DELAY(1000);
+ if (can_sleep)
+ pause("wchrev", 1);
+ else
+ DELAY(1000);
}
return (false);
@@ -667,7 +709,7 @@ vmbus_chan_gpadl_disconnect(struct vmbus
if (error) {
vmbus_msghc_put(sc, mh);
- if (vmbus_chan_wait_revoke(chan)) {
+ if (vmbus_chan_wait_revoke(chan, true)) {
/*
* Error is benign; this channel is revoked,
* so this GPADL will not be touched anymore.
Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jan 5 05:41:33 2017 (r311366)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_var.h Thu Jan 5 05:46:06 2017 (r311367)
@@ -160,9 +160,14 @@ void vmbus_msghc_put(struct vmbus_softc
void *vmbus_msghc_dataptr(struct vmbus_msghc *);
int vmbus_msghc_exec_noresult(struct vmbus_msghc *);
int vmbus_msghc_exec(struct vmbus_softc *, struct vmbus_msghc *);
+void vmbus_msghc_exec_cancel(struct vmbus_softc *,
+ struct vmbus_msghc *);
const struct vmbus_message *
vmbus_msghc_wait_result(struct vmbus_softc *,
struct vmbus_msghc *);
+const struct vmbus_message *
+ vmbus_msghc_poll_result(struct vmbus_softc *,
+ struct vmbus_msghc *);
void vmbus_msghc_wakeup(struct vmbus_softc *,
const struct vmbus_message *);
void vmbus_msghc_reset(struct vmbus_msghc *, size_t);
Modified: stable/11/sys/dev/hyperv/vmbus/vmbus_xact.c
==============================================================================
--- stable/11/sys/dev/hyperv/vmbus/vmbus_xact.c Thu Jan 5 05:41:33 2017 (r311366)
+++ stable/11/sys/dev/hyperv/vmbus/vmbus_xact.c Thu Jan 5 05:46:06 2017 (r311367)
@@ -71,8 +71,10 @@ static struct vmbus_xact *vmbus_xact_all
static void vmbus_xact_free(struct vmbus_xact *);
static struct vmbus_xact *vmbus_xact_get1(struct vmbus_xact_ctx *,
uint32_t);
-const void *vmbus_xact_wait1(struct vmbus_xact *, size_t *,
+static const void *vmbus_xact_wait1(struct vmbus_xact *, size_t *,
bool);
+static const void *vmbus_xact_return(struct vmbus_xact *,
+ size_t *);
static void vmbus_xact_save_resp(struct vmbus_xact *,
const void *, size_t);
static void vmbus_xact_ctx_free(struct vmbus_xact_ctx *);
@@ -277,27 +279,13 @@ vmbus_xact_deactivate(struct vmbus_xact
mtx_unlock(&ctx->xc_lock);
}
-const void *
-vmbus_xact_wait1(struct vmbus_xact *xact, size_t *resp_len,
- bool can_sleep)
+static const void *
+vmbus_xact_return(struct vmbus_xact *xact, size_t *resp_len)
{
struct vmbus_xact_ctx *ctx = xact->x_ctx;
const void *resp;
- mtx_lock(&ctx->xc_lock);
-
- KASSERT(ctx->xc_active == xact, ("xact mismatch"));
- while (xact->x_resp == NULL &&
- (ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) == 0) {
- if (can_sleep) {
- mtx_sleep(&ctx->xc_active, &ctx->xc_lock, 0,
- "wxact", 0);
- } else {
- mtx_unlock(&ctx->xc_lock);
- DELAY(1000);
- mtx_lock(&ctx->xc_lock);
- }
- }
+ mtx_assert(&ctx->xc_lock, MA_OWNED);
KASSERT(ctx->xc_active == xact, ("xact trashed"));
if ((ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) && xact->x_resp == NULL) {
@@ -317,6 +305,32 @@ vmbus_xact_wait1(struct vmbus_xact *xact
resp = xact->x_resp;
*resp_len = xact->x_resp_len;
+ return (resp);
+}
+
+static const void *
+vmbus_xact_wait1(struct vmbus_xact *xact, size_t *resp_len,
+ bool can_sleep)
+{
+ struct vmbus_xact_ctx *ctx = xact->x_ctx;
+ const void *resp;
+
+ mtx_lock(&ctx->xc_lock);
+
+ KASSERT(ctx->xc_active == xact, ("xact mismatch"));
+ while (xact->x_resp == NULL &&
+ (ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) == 0) {
+ if (can_sleep) {
+ mtx_sleep(&ctx->xc_active, &ctx->xc_lock, 0,
+ "wxact", 0);
+ } else {
+ mtx_unlock(&ctx->xc_lock);
+ DELAY(1000);
+ mtx_lock(&ctx->xc_lock);
+ }
+ }
+ resp = vmbus_xact_return(xact, resp_len);
+
mtx_unlock(&ctx->xc_lock);
return (resp);
@@ -336,6 +350,28 @@ vmbus_xact_busywait(struct vmbus_xact *x
return (vmbus_xact_wait1(xact, resp_len, false /* can't sleep */));
}
+const void *
+vmbus_xact_poll(struct vmbus_xact *xact, size_t *resp_len)
+{
+ struct vmbus_xact_ctx *ctx = xact->x_ctx;
+ const void *resp;
+
+ mtx_lock(&ctx->xc_lock);
+
+ KASSERT(ctx->xc_active == xact, ("xact mismatch"));
+ if (xact->x_resp == NULL &&
+ (ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) == 0) {
+ mtx_unlock(&ctx->xc_lock);
+ *resp_len = 0;
+ return (NULL);
+ }
+ resp = vmbus_xact_return(xact, resp_len);
+
+ mtx_unlock(&ctx->xc_lock);
+
+ return (resp);
+}
+
static void
vmbus_xact_save_resp(struct vmbus_xact *xact, const void *data, size_t dlen)
{
More information about the svn-src-stable
mailing list