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