Date: Tue, 31 May 2016 05:18:56 +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: r301019 - head/sys/dev/hyperv/vmbus Message-ID: <201605310518.u4V5IufJ045757@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201605310518.u4V5IufJ045757>