hyperv/vmbus: Use post message Hypercall APIs for GPA disconnect

MFC after:	1 week
Sponsored by:	Microsoft OSTC
Differential Revision:	https://reviews.freebsd.org/D6912
This commit is contained in:
Sepherosa Ziehau 2016-07-12 03:32:07 +00:00
parent e9bd7c4417
commit e90ec741f9
3 changed files with 40 additions and 83 deletions

View File

@ -427,61 +427,44 @@ hv_vmbus_channel_establish_gpadl(struct hv_vmbus_channel *channel,
return 0;
}
/**
* @brief Teardown the specified GPADL handle
/*
* Disconnect the GPA from the target channel
*/
int
hv_vmbus_channel_teardown_gpdal(
hv_vmbus_channel* channel,
uint32_t gpadl_handle)
hv_vmbus_channel_teardown_gpdal(struct hv_vmbus_channel *chan, uint32_t gpadl)
{
int ret = 0;
hv_vmbus_channel_gpadl_teardown* msg;
hv_vmbus_channel_msg_info* info;
struct vmbus_softc *sc = chan->vmbus_sc;
struct vmbus_msghc *mh;
struct vmbus_chanmsg_gpadl_disconn *req;
int error;
info = (hv_vmbus_channel_msg_info *)
malloc( sizeof(hv_vmbus_channel_msg_info) +
sizeof(hv_vmbus_channel_gpadl_teardown),
M_DEVBUF, M_NOWAIT);
KASSERT(info != NULL,
("Error VMBUS: malloc failed to allocate Gpadl Teardown Msg!"));
if (info == NULL) {
ret = ENOMEM;
goto cleanup;
mh = vmbus_msghc_get(sc, sizeof(*req));
if (mh == NULL) {
device_printf(sc->vmbus_dev,
"can not get msg hypercall for gpa x->chan%u\n",
chan->offer_msg.child_rel_id);
return EBUSY;
}
sema_init(&info->wait_sema, 0, "Open Info Sema");
req = vmbus_msghc_dataptr(mh);
req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_GPADL_DISCONN;
req->chm_chanid = chan->offer_msg.child_rel_id;
req->chm_gpadl = gpadl;
msg = (hv_vmbus_channel_gpadl_teardown*) info->msg;
error = vmbus_msghc_exec(sc, mh);
if (error) {
device_printf(sc->vmbus_dev,
"gpa x->chan%u msg hypercall exec failed: %d\n",
chan->offer_msg.child_rel_id, error);
vmbus_msghc_put(sc, mh);
return error;
}
msg->header.message_type = HV_CHANNEL_MESSAGE_GPADL_TEARDOWN;
msg->child_rel_id = channel->offer_msg.child_rel_id;
msg->gpadl = gpadl_handle;
vmbus_msghc_wait_result(sc, mh);
/* Discard result; no useful information */
vmbus_msghc_put(sc, mh);
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
TAILQ_INSERT_TAIL(&hv_vmbus_g_connection.channel_msg_anchor,
info, msg_list_entry);
mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
ret = hv_vmbus_post_message(msg,
sizeof(hv_vmbus_channel_gpadl_teardown));
if (ret != 0)
goto cleanup;
ret = sema_timedwait(&info->wait_sema, 5 * hz); /* KYS 5 seconds */
cleanup:
/*
* Received a torndown response
*/
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
TAILQ_REMOVE(&hv_vmbus_g_connection.channel_msg_anchor,
info, msg_list_entry);
mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
sema_destroy(&info->wait_sema);
free(info, M_DEVBUF);
return (ret);
return 0;
}
static void

View File

@ -452,42 +452,7 @@ static void
vmbus_channel_on_gpadl_torndown(struct vmbus_softc *sc,
const struct vmbus_message *msg)
{
const hv_vmbus_channel_msg_header *hdr =
(const hv_vmbus_channel_msg_header *)msg->msg_data;
const hv_vmbus_channel_gpadl_torndown *gpadl_torndown;
hv_vmbus_channel_msg_info* msg_info;
hv_vmbus_channel_msg_header* requestHeader;
hv_vmbus_channel_gpadl_teardown* gpadlTeardown;
gpadl_torndown = (const hv_vmbus_channel_gpadl_torndown *)hdr;
/*
* Find the open msg, copy the result and signal/unblock the
* wait event.
*/
mtx_lock(&hv_vmbus_g_connection.channel_msg_lock);
TAILQ_FOREACH(msg_info, &hv_vmbus_g_connection.channel_msg_anchor,
msg_list_entry) {
requestHeader = (hv_vmbus_channel_msg_header*) msg_info->msg;
if (requestHeader->message_type
== HV_CHANNEL_MESSAGE_GPADL_TEARDOWN) {
gpadlTeardown =
(hv_vmbus_channel_gpadl_teardown*) requestHeader;
if (gpadl_torndown->gpadl == gpadlTeardown->gpadl) {
memcpy(&msg_info->response.gpadl_torndown,
gpadl_torndown,
sizeof(hv_vmbus_channel_gpadl_torndown));
sema_post(&msg_info->wait_sema);
break;
}
}
}
mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock);
vmbus_msghc_wakeup(sc, msg);
}
static void

View File

@ -99,7 +99,9 @@ struct vmbus_gpa_range {
#define VMBUS_CHANMSG_TYPE_CHCLOSE 7 /* REQ */
#define VMBUS_CHANMSG_TYPE_GPADL_CONN 8 /* REQ */
#define VMBUS_CHANMSG_TYPE_GPADL_SUBCONN 9 /* REQ */
#define VMBUS_CHANMSG_TYPE_GPADP_CONNRESP 10 /* RESP */
#define VMBUS_CHANMSG_TYPE_GPADL_CONNRESP 10 /* RESP */
#define VMBUS_CHANMSG_TYPE_GPADL_DISCONN 11 /* REQ */
#define VMBUS_CHANMSG_TYPE_GPADL_DISCONNRESP 12 /* RESP */
#define VMBUS_CHANMSG_TYPE_INIT_CONTACT 14 /* REQ */
#define VMBUS_CHANMSG_TYPE_VERSION_RESP 15 /* RESP */
#define VMBUS_CHANMSG_TYPE_UNLOAD 16 /* REQ */
@ -197,4 +199,11 @@ struct vmbus_chanmsg_chclose {
uint32_t chm_chanid;
} __packed;
/* VMBUS_CHANMSG_TYPE_GPADL_DISCONN */
struct vmbus_chanmsg_gpadl_disconn {
struct vmbus_chanmsg_hdr chm_hdr;
uint32_t chm_chanid;
uint32_t chm_gpadl;
} __packed;
#endif /* !_VMBUS_REG_H_ */