Skip site navigation (1)Skip section navigation (2)
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>