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_ */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to