Date: Tue, 12 Jul 2016 03:09:11 +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: r302607 - head/sys/dev/hyperv/vmbus Message-ID: <201607120309.u6C39BGY010116@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sephe Date: Tue Jul 12 03:09:10 2016 New Revision: 302607 URL: https://svnweb.freebsd.org/changeset/base/302607 Log: hyperv/vmbus: Use post message Hypercall APIs for channel open MFC after: 1 week Sponsored by: Microsoft OSTC Differential Revision: https://reviews.freebsd.org/D6876 Modified: head/sys/dev/hyperv/vmbus/hv_channel.c head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c head/sys/dev/hyperv/vmbus/vmbus_reg.h Modified: head/sys/dev/hyperv/vmbus/hv_channel.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_channel.c Tue Jul 12 03:03:17 2016 (r302606) +++ head/sys/dev/hyperv/vmbus/hv_channel.c Tue Jul 12 03:09:10 2016 (r302607) @@ -182,11 +182,21 @@ hv_vmbus_channel_open( hv_vmbus_pfn_channel_callback pfn_on_channel_callback, void* context) { - + struct vmbus_softc *sc = new_channel->vmbus_sc; + const struct vmbus_chanmsg_chopen_resp *resp; + const struct vmbus_message *msg; + struct vmbus_chanmsg_chopen *req; + struct vmbus_msghc *mh; + uint32_t status; int ret = 0; void *in, *out; - hv_vmbus_channel_open_channel* open_msg; - hv_vmbus_channel_msg_info* open_info; + + if (user_data_len > VMBUS_CHANMSG_CHOPEN_UDATA_SIZE) { + device_printf(sc->vmbus_dev, + "invalid udata len %u for chan%u\n", + user_data_len, new_channel->offer_msg.child_rel_id); + return EINVAL; + } mtx_lock(&new_channel->sc_lock); if (new_channel->state == HV_CHANNEL_OPEN_STATE) { @@ -248,76 +258,53 @@ hv_vmbus_channel_open( send_ring_buffer_size + recv_ring_buffer_size, &new_channel->ring_buffer_gpadl_handle); - /** - * Create and init the channel open message + /* + * Open channel w/ the bufring GPADL on the target CPU. */ - open_info = (hv_vmbus_channel_msg_info*) malloc( - sizeof(hv_vmbus_channel_msg_info) + - sizeof(hv_vmbus_channel_open_channel), - M_DEVBUF, - M_NOWAIT); - KASSERT(open_info != NULL, - ("Error VMBUS: malloc failed to allocate Open Channel message!")); - - if (open_info == NULL) - return (ENOMEM); - - sema_init(&open_info->wait_sema, 0, "Open Info Sema"); - - open_msg = (hv_vmbus_channel_open_channel*) open_info->msg; - open_msg->header.message_type = HV_CHANNEL_MESSAGE_OPEN_CHANNEL; - open_msg->open_id = new_channel->offer_msg.child_rel_id; - open_msg->child_rel_id = new_channel->offer_msg.child_rel_id; - open_msg->ring_buffer_gpadl_handle = - new_channel->ring_buffer_gpadl_handle; - open_msg->downstream_ring_buffer_page_offset = send_ring_buffer_size - >> PAGE_SHIFT; - open_msg->target_vcpu = new_channel->target_vcpu; - + mh = vmbus_msghc_get(sc, sizeof(*req)); + if (mh == NULL) { + device_printf(sc->vmbus_dev, + "can not get msg hypercall for chopen(chan%u)\n", + new_channel->offer_msg.child_rel_id); + return ENXIO; + } + + req = vmbus_msghc_dataptr(mh); + req->chm_hdr.chm_type = VMBUS_CHANMSG_TYPE_CHOPEN; + req->chm_chanid = new_channel->offer_msg.child_rel_id; + req->chm_openid = new_channel->offer_msg.child_rel_id; + req->chm_gpadl = new_channel->ring_buffer_gpadl_handle; + req->chm_vcpuid = new_channel->target_vcpu; + req->chm_rxbr_pgofs = send_ring_buffer_size >> PAGE_SHIFT; if (user_data_len) - memcpy(open_msg->user_data, user_data, user_data_len); - - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_INSERT_TAIL( - &hv_vmbus_g_connection.channel_msg_anchor, - open_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - - ret = hv_vmbus_post_message( - open_msg, sizeof(hv_vmbus_channel_open_channel)); - - if (ret != 0) - goto cleanup; - - ret = sema_timedwait(&open_info->wait_sema, 5 * hz); /* KYS 5 seconds */ + memcpy(req->chm_udata, user_data, user_data_len); - if (ret) { - if(bootverbose) - printf("VMBUS: channel <%p> open timeout.\n", new_channel); - goto cleanup; + ret = vmbus_msghc_exec(sc, mh); + if (ret != 0) { + device_printf(sc->vmbus_dev, + "chopen(chan%u) msg hypercall exec failed: %d\n", + new_channel->offer_msg.child_rel_id, ret); + vmbus_msghc_put(sc, mh); + return ret; } - if (open_info->response.open_result.status == 0) { - new_channel->state = HV_CHANNEL_OPENED_STATE; - if(bootverbose) - printf("VMBUS: channel <%p> open success.\n", new_channel); + msg = vmbus_msghc_wait_result(sc, mh); + resp = (const struct vmbus_chanmsg_chopen_resp *)msg->msg_data; + status = resp->chm_status; + + vmbus_msghc_put(sc, mh); + + if (status == 0) { + new_channel->state = HV_CHANNEL_OPENED_STATE; + if (bootverbose) { + device_printf(sc->vmbus_dev, "chan%u opened\n", + new_channel->offer_msg.child_rel_id); + } } else { - if(bootverbose) - printf("Error VMBUS: channel <%p> open failed - %d!\n", - new_channel, open_info->response.open_result.status); + device_printf(sc->vmbus_dev, "failed to open chan%u\n", + new_channel->offer_msg.child_rel_id); + ret = ENXIO; } - - cleanup: - mtx_lock(&hv_vmbus_g_connection.channel_msg_lock); - TAILQ_REMOVE( - &hv_vmbus_g_connection.channel_msg_anchor, - open_info, - msg_list_entry); - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - sema_destroy(&open_info->wait_sema); - free(open_info, M_DEVBUF); - return (ret); } Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c ============================================================================== --- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 03:03:17 2016 (r302606) +++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Tue Jul 12 03:09:10 2016 (r302607) @@ -418,46 +418,13 @@ vmbus_channel_on_offers_delivered(struct * @brief Open result handler. * * This is invoked when we received a response - * to our channel open request. Find the matching request, copy the - * response and signal the requesting thread. + * to our channel open request. */ static void vmbus_channel_on_open_result(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_open_result *result; - hv_vmbus_channel_msg_info* msg_info; - hv_vmbus_channel_msg_header* requestHeader; - hv_vmbus_channel_open_channel* openMsg; - - result = (const hv_vmbus_channel_open_result *)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_OPEN_CHANNEL) { - openMsg = (hv_vmbus_channel_open_channel*) msg_info->msg; - if (openMsg->child_rel_id == result->child_rel_id - && openMsg->open_id == result->open_id) { - memcpy(&msg_info->response.open_result, result, - sizeof(hv_vmbus_channel_open_result)); - sema_post(&msg_info->wait_sema); - break; - } - } - } - mtx_unlock(&hv_vmbus_g_connection.channel_msg_lock); - + vmbus_msghc_wakeup(sc, msg); } /** Modified: head/sys/dev/hyperv/vmbus/vmbus_reg.h ============================================================================== --- head/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Jul 12 03:03:17 2016 (r302606) +++ head/sys/dev/hyperv/vmbus/vmbus_reg.h Tue Jul 12 03:09:10 2016 (r302607) @@ -84,6 +84,8 @@ CTASSERT(sizeof(struct vmbus_evtflags) = */ #define VMBUS_CHANMSG_TYPE_CHANNEL_REQ 3 /* REQ */ +#define VMBUS_CHANMSG_TYPE_CHOPEN 5 /* REQ */ +#define VMBUS_CHANMSG_TYPE_CHOPEN_RESP 6 /* RESP */ #define VMBUS_CHANMSG_TYPE_INIT_CONTACT 14 /* REQ */ #define VMBUS_CHANMSG_TYPE_VERSION_RESP 15 /* RESP */ #define VMBUS_CHANMSG_TYPE_UNLOAD 16 /* REQ */ @@ -119,4 +121,24 @@ struct vmbus_chanmsg_unload { struct vmbus_chanmsg_hdr chm_hdr; } __packed; +/* VMBUS_CHANMSG_TYPE_CHOPEN */ +struct vmbus_chanmsg_chopen { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_openid; + uint32_t chm_gpadl; + uint32_t chm_vcpuid; + uint32_t chm_rxbr_pgofs; +#define VMBUS_CHANMSG_CHOPEN_UDATA_SIZE 120 + uint8_t chm_udata[VMBUS_CHANMSG_CHOPEN_UDATA_SIZE]; +} __packed; + +/* VMBUS_CHANMSG_TYPE_CHOPEN_RESP */ +struct vmbus_chanmsg_chopen_resp { + struct vmbus_chanmsg_hdr chm_hdr; + uint32_t chm_chanid; + uint32_t chm_openid; + uint32_t chm_status; +} __packed; + #endif /* !_VMBUS_REG_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607120309.u6C39BGY010116>