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

Reply via email to