Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F164690714
D8525.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D8525.diff
View Options
Index: head/sys/dev/hyperv/include/vmbus_xact.h
===================================================================
--- head/sys/dev/hyperv/include/vmbus_xact.h
+++ head/sys/dev/hyperv/include/vmbus_xact.h
@@ -39,6 +39,8 @@
size_t req_size, size_t resp_size,
size_t priv_size);
void vmbus_xact_ctx_destroy(struct vmbus_xact_ctx *ctx);
+bool vmbus_xact_ctx_orphan(struct vmbus_xact_ctx *ctx);
+
struct vmbus_xact *vmbus_xact_get(struct vmbus_xact_ctx *ctx,
size_t req_len);
void vmbus_xact_put(struct vmbus_xact *xact);
Index: head/sys/dev/hyperv/vmbus/vmbus_xact.c
===================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_xact.c
+++ head/sys/dev/hyperv/vmbus/vmbus_xact.c
@@ -61,6 +61,7 @@
uint32_t xc_flags; /* VMBUS_XACT_CTXF_ */
struct vmbus_xact *xc_free;
struct vmbus_xact *xc_active;
+ struct vmbus_xact *xc_orphan;
};
#define VMBUS_XACT_CTXF_DESTROY 0x0001
@@ -72,6 +73,9 @@
uint32_t);
const void *vmbus_xact_wait1(struct vmbus_xact *, size_t *,
bool);
+static void vmbus_xact_save_resp(struct vmbus_xact *,
+ const void *, size_t);
+static void vmbus_xact_ctx_free(struct vmbus_xact_ctx *);
static struct vmbus_xact *
vmbus_xact_alloc(struct vmbus_xact_ctx *ctx, bus_dma_tag_t parent_dtag)
@@ -136,6 +140,9 @@
{
struct vmbus_xact_ctx *ctx;
+ KASSERT(req_size > 0, ("request size is 0"));
+ KASSERT(resp_size > 0, ("response size is 0"));
+
ctx = malloc(sizeof(*ctx), M_DEVBUF, M_WAITOK | M_ZERO);
ctx->xc_req_size = req_size;
ctx->xc_resp_size = resp_size;
@@ -152,25 +159,46 @@
return (ctx);
}
-void
-vmbus_xact_ctx_destroy(struct vmbus_xact_ctx *ctx)
+bool
+vmbus_xact_ctx_orphan(struct vmbus_xact_ctx *ctx)
{
- struct vmbus_xact *xact;
-
mtx_lock(&ctx->xc_lock);
+ if (ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) {
+ mtx_unlock(&ctx->xc_lock);
+ return (false);
+ }
ctx->xc_flags |= VMBUS_XACT_CTXF_DESTROY;
mtx_unlock(&ctx->xc_lock);
+
wakeup(&ctx->xc_free);
+ wakeup(&ctx->xc_active);
- xact = vmbus_xact_get1(ctx, 0);
- if (xact == NULL)
+ ctx->xc_orphan = vmbus_xact_get1(ctx, 0);
+ if (ctx->xc_orphan == NULL)
panic("can't get xact");
+ return (true);
+}
- vmbus_xact_free(xact);
+static void
+vmbus_xact_ctx_free(struct vmbus_xact_ctx *ctx)
+{
+ KASSERT(ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY,
+ ("xact ctx was not orphaned"));
+ KASSERT(ctx->xc_orphan != NULL, ("no orphaned xact"));
+
+ vmbus_xact_free(ctx->xc_orphan);
mtx_destroy(&ctx->xc_lock);
free(ctx, M_DEVBUF);
}
+void
+vmbus_xact_ctx_destroy(struct vmbus_xact_ctx *ctx)
+{
+
+ vmbus_xact_ctx_orphan(ctx);
+ vmbus_xact_ctx_free(ctx);
+}
+
struct vmbus_xact *
vmbus_xact_get(struct vmbus_xact_ctx *ctx, size_t req_len)
{
@@ -259,7 +287,8 @@
mtx_lock(&ctx->xc_lock);
KASSERT(ctx->xc_active == xact, ("xact mismatch"));
- while (xact->x_resp == NULL) {
+ 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);
@@ -269,6 +298,20 @@
mtx_lock(&ctx->xc_lock);
}
}
+ KASSERT(ctx->xc_active == xact, ("xact trashed"));
+
+ if ((ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY) && xact->x_resp == NULL) {
+ uint8_t b = 0;
+
+ /*
+ * Orphaned and no response was received yet; fake up
+ * an one byte response.
+ */
+ printf("vmbus: xact ctx was orphaned w/ pending xact\n");
+ vmbus_xact_save_resp(ctx->xc_active, &b, sizeof(b));
+ }
+ KASSERT(xact->x_resp != NULL, ("no response"));
+
ctx->xc_active = NULL;
resp = xact->x_resp;
@@ -317,19 +360,47 @@
vmbus_xact_wakeup(struct vmbus_xact *xact, const void *data, size_t dlen)
{
struct vmbus_xact_ctx *ctx = xact->x_ctx;
+ int do_wakeup = 0;
mtx_lock(&ctx->xc_lock);
- vmbus_xact_save_resp(xact, data, dlen);
+ /*
+ * NOTE:
+ * xc_active could be NULL, if the ctx has been orphaned.
+ */
+ if (ctx->xc_active != NULL) {
+ vmbus_xact_save_resp(xact, data, dlen);
+ do_wakeup = 1;
+ } else {
+ KASSERT(ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY,
+ ("no active xact pending"));
+ printf("vmbus: drop xact response\n");
+ }
mtx_unlock(&ctx->xc_lock);
- wakeup(&ctx->xc_active);
+
+ if (do_wakeup)
+ wakeup(&ctx->xc_active);
}
void
vmbus_xact_ctx_wakeup(struct vmbus_xact_ctx *ctx, const void *data, size_t dlen)
{
+ int do_wakeup = 0;
+
mtx_lock(&ctx->xc_lock);
- KASSERT(ctx->xc_active != NULL, ("no pending xact"));
- vmbus_xact_save_resp(ctx->xc_active, data, dlen);
+ /*
+ * NOTE:
+ * xc_active could be NULL, if the ctx has been orphaned.
+ */
+ if (ctx->xc_active != NULL) {
+ vmbus_xact_save_resp(ctx->xc_active, data, dlen);
+ do_wakeup = 1;
+ } else {
+ KASSERT(ctx->xc_flags & VMBUS_XACT_CTXF_DESTROY,
+ ("no active xact pending"));
+ printf("vmbus: drop xact response\n");
+ }
mtx_unlock(&ctx->xc_lock);
- wakeup(&ctx->xc_active);
+
+ if (do_wakeup)
+ wakeup(&ctx->xc_active);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Aug 4, 5:02 AM (3 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35938371
Default Alt Text
D8525.diff (4 KB)
Attached To
Mode
D8525: hyperv/vmbus: Implement orphan support for transaction API
Attached
Detach File
Event Timeline
Log In to Comment