svn commit: r301019 - head/sys/dev/hyperv/vmbus

Sepherosa Ziehau sephe at FreeBSD.org
Tue May 31 05:18:57 UTC 2016


Author: sephe
Date: Tue May 31 05:18:55 2016
New Revision: 301019
URL: https://svnweb.freebsd.org/changeset/base/301019

Log:
  hyperv/vmbus: Redefine SynIC message.
  
  - Avoid unnecessary indirection.
  - Avoid bit fields.
  - Use __packed.
  
  Reviewed by:	Jun Su <junsu microsoft com>
  MFC after:	1 week
  Sponsored by:	Microsoft OSTC
  Differential Revision:	https://reviews.freebsd.org/D6636

Added:
  head/sys/dev/hyperv/vmbus/vmbus_reg.h   (contents, props changed)
Modified:
  head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
  head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue May 31 05:10:20 2016	(r301018)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_drv_freebsd.c	Tue May 31 05:18:55 2016	(r301019)
@@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/hyperv/vmbus/hv_vmbus_priv.h>
 #include <dev/hyperv/vmbus/hyperv_reg.h>
 #include <dev/hyperv/vmbus/hyperv_var.h>
+#include <dev/hyperv/vmbus/vmbus_reg.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
 #include <contrib/dev/acpica/include/acpi.h>
@@ -76,7 +77,7 @@ static void
 vmbus_msg_task(void *xsc, int pending __unused)
 {
 	struct vmbus_softc *sc = xsc;
-	hv_vmbus_message *msg;
+	volatile struct vmbus_message *msg;
 
 	msg = VMBUS_PCPU_GET(sc, message, curcpu) + VMBUS_SINT_MESSAGE;
 	for (;;) {
@@ -84,10 +85,12 @@ vmbus_msg_task(void *xsc, int pending __
 		hv_vmbus_channel_msg_header *hdr;
 		hv_vmbus_channel_msg_type msg_type;
 
-		if (msg->header.message_type == HV_MESSAGE_TYPE_NONE)
+		if (msg->msg_type == VMBUS_MSGTYPE_NONE)
 			break; /* no message */
 
-		hdr = (hv_vmbus_channel_msg_header *)msg->u.payload;
+		/* XXX: update messageHandler interface */
+		hdr = __DEVOLATILE(hv_vmbus_channel_msg_header *,
+		    msg->msg_data);
 		msg_type = hdr->message_type;
 
 		if (msg_type >= HV_CHANNEL_MESSAGE_COUNT) {
@@ -99,20 +102,20 @@ vmbus_msg_task(void *xsc, int pending __
 		if (entry->messageHandler)
 			entry->messageHandler(hdr);
 handled:
-		msg->header.message_type = HV_MESSAGE_TYPE_NONE;
+		msg->msg_type = VMBUS_MSGTYPE_NONE;
 		/*
-		 * Make sure the write to message_type (ie set to
-		 * HV_MESSAGE_TYPE_NONE) happens before we read the
-		 * message_pending and EOMing. Otherwise, the EOMing will
-		 * not deliver any more messages
-		 * since there is no empty slot
+		 * Make sure the write to msg_type (i.e. set to
+		 * VMBUS_MSGTYPE_NONE) happens before we read the
+		 * msg_flags and EOMing. Otherwise, the EOMing will
+		 * not deliver any more messages since there is no
+		 * empty slot
 		 *
 		 * NOTE:
 		 * mb() is used here, since atomic_thread_fence_seq_cst()
 		 * will become compiler fence on UP kernel.
 		 */
 		mb();
-		if (msg->header.message_flags.u.message_pending) {
+		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
 			/*
 			 * This will cause message queue rescan to possibly
 			 * deliver another msg from the hypervisor
@@ -125,7 +128,8 @@ handled:
 static __inline int
 vmbus_handle_intr1(struct vmbus_softc *sc, struct trapframe *frame, int cpu)
 {
-	hv_vmbus_message *msg, *msg_base;
+	volatile struct vmbus_message *msg;
+	struct vmbus_message *msg_base;
 
 	msg_base = VMBUS_PCPU_GET(sc, message, cpu);
 
@@ -135,25 +139,24 @@ vmbus_handle_intr1(struct vmbus_softc *s
 	 * TODO: move this to independent IDT vector.
 	 */
 	msg = msg_base + VMBUS_SINT_TIMER;
-	if (msg->header.message_type == HV_MESSAGE_TIMER_EXPIRED) {
-		msg->header.message_type = HV_MESSAGE_TYPE_NONE;
+	if (msg->msg_type == VMBUS_MSGTYPE_TIMER_EXPIRED) {
+		msg->msg_type = VMBUS_MSGTYPE_NONE;
 
 		vmbus_et_intr(frame);
 
 		/*
-		 * Make sure the write to message_type (ie set to
-		 * HV_MESSAGE_TYPE_NONE) happens before we read the
-		 * message_pending and EOMing. Otherwise, the EOMing will
-		 * not deliver any more messages
-		 * since there is no empty slot
+		 * Make sure the write to msg_type (i.e. set to
+		 * VMBUS_MSGTYPE_NONE) happens before we read the
+		 * msg_flags and EOMing. Otherwise, the EOMing will
+		 * not deliver any more messages since there is no
+		 * empty slot
 		 *
 		 * NOTE:
 		 * mb() is used here, since atomic_thread_fence_seq_cst()
 		 * will become compiler fence on UP kernel.
 		 */
 		mb();
-
-		if (msg->header.message_flags.u.message_pending) {
+		if (msg->msg_flags & VMBUS_MSGFLAG_PENDING) {
 			/*
 			 * This will cause message queue rescan to possibly
 			 * deliver another msg from the hypervisor
@@ -175,7 +178,7 @@ vmbus_handle_intr1(struct vmbus_softc *s
 	 * Check messages.  Mainly management stuffs; ultra low rate.
 	 */
 	msg = msg_base + VMBUS_SINT_MESSAGE;
-	if (__predict_false(msg->header.message_type != HV_MESSAGE_TYPE_NONE)) {
+	if (__predict_false(msg->msg_type != VMBUS_MSGTYPE_NONE)) {
 		taskqueue_enqueue(VMBUS_PCPU_GET(sc, message_tq, cpu),
 		    VMBUS_PCPU_PTR(sc, message_task, cpu));
 	}

Modified: head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue May 31 05:10:20 2016	(r301018)
+++ head/sys/dev/hyperv/vmbus/hv_vmbus_priv.h	Tue May 31 05:18:55 2016	(r301019)
@@ -251,44 +251,9 @@ typedef union _hv_vmbus_port_id {
 	} u ;
 } hv_vmbus_port_id;
 
-/*
- * Define synthetic interrupt controller message flag
- */
-typedef union {
-	uint8_t	as_uint8_t;
-	struct {
-		uint8_t	message_pending:1;
-		uint8_t	reserved:7;
-	} u;
-} hv_vmbus_msg_flags;
-
 typedef uint64_t hv_vmbus_partition_id;
 
 /*
- * Define synthetic interrupt controller message header
- */
-typedef struct {
-	hv_vmbus_msg_type	message_type;
-	uint8_t			payload_size;
-	hv_vmbus_msg_flags	message_flags;
-	uint8_t			reserved[2];
-	union {
-		hv_vmbus_partition_id	sender;
-		hv_vmbus_port_id	port;
-	} u;
-} hv_vmbus_msg_header;
-
-/*
- *  Define synthetic interrupt controller message format
- */
-typedef struct vmbus_message {
-	hv_vmbus_msg_header	header;
-	union {
-		uint64_t	payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
-	} u ;
-} hv_vmbus_message;
-
-/*
  *  Maximum channels is determined by the size of the interrupt
  *  page which is PAGE_SIZE. 1/2 of PAGE_SIZE is for
  *  send endpoint interrupt and the other is receive

Added: head/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/dev/hyperv/vmbus/vmbus_reg.h	Tue May 31 05:18:55 2016	(r301019)
@@ -0,0 +1,56 @@
+/*-
+ * Copyright (c) 2016 Microsoft Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _VMBUS_REG_H_
+#define _VMBUS_REG_H_
+
+#include <sys/param.h>
+
+/*
+ * Hyper-V SynIC message format.
+ */
+
+#define VMBUS_MSG_DSIZE_MAX		240
+#define VMBUS_MSG_SIZE			256
+
+struct vmbus_message {
+	uint32_t	msg_type;	/* VMBUS_MSGTYPE_ */
+	uint8_t		msg_dsize;	/* data size */
+	uint8_t		msg_flags;	/* VMBUS_MSGFLAG_ */
+	uint16_t	msg_rsvd;
+	uint64_t	msg_id;
+	uint8_t		msg_data[VMBUS_MSG_DSIZE_MAX];
+} __packed;
+CTASSERT(sizeof(struct vmbus_message) == VMBUS_MSG_SIZE);
+
+#define VMBUS_MSGTYPE_NONE		0
+#define VMBUS_MSGTYPE_TIMER_EXPIRED	0x80000010
+
+#define VMBUS_MSGFLAG_PENDING		0x01
+
+#endif	/* !_VMBUS_REG_H_ */


More information about the svn-src-all mailing list