Author: sephe
Date: Wed Jul 13 09:28:46 2016
New Revision: 302731
URL: https://svnweb.freebsd.org/changeset/base/302731

Log:
  hyperv/vmbus: Reorganize MNF event sending.
  
  MFC after:    1 week
  Sponsored by: Microsoft OSTC
  Differential Revision:        https://reviews.freebsd.org/D7088

Modified:
  head/sys/dev/hyperv/include/hyperv.h
  head/sys/dev/hyperv/vmbus/hv_channel.c
  head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
  head/sys/dev/hyperv/vmbus/vmbus.c
  head/sys/dev/hyperv/vmbus/vmbus_reg.h
  head/sys/dev/hyperv/vmbus/vmbus_var.h

Modified: head/sys/dev/hyperv/include/hyperv.h
==============================================================================
--- head/sys/dev/hyperv/include/hyperv.h        Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/include/hyperv.h        Wed Jul 13 09:28:46 2016        
(r302731)
@@ -523,12 +523,13 @@ typedef struct hv_vmbus_channel {
        hv_vmbus_channel_state          state;
        uint32_t                        ch_flags;       /* VMBUS_CHAN_FLAG_ */
        uint32_t                        ch_id;          /* channel id */
+
        /*
         * These are based on the offer_msg.monitor_id.
         * Save it here for easy access.
         */
-       uint8_t                         monitor_group;
-       uint8_t                         monitor_bit;
+       int                             ch_montrig_idx; /* MNF trig index */
+       uint32_t                        ch_montrig_mask;/* MNF trig mask */
 
        uint32_t                        ring_buffer_gpadl_handle;
        /*

Modified: head/sys/dev/hyperv/vmbus/hv_channel.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel.c      Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/vmbus/hv_channel.c      Wed Jul 13 09:28:46 2016        
(r302731)
@@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/hyperv/vmbus/vmbus_reg.h>
 #include <dev/hyperv/vmbus/vmbus_var.h>
 
-static void    vmbus_channel_set_event(hv_vmbus_channel* channel);
+static void    vmbus_chan_send_event(hv_vmbus_channel* channel);
 static void    vmbus_chan_update_evtflagcnt(struct vmbus_softc *,
                    const struct hv_vmbus_channel *);
 static void    vmbus_chan_task(void *, int);
@@ -60,7 +60,7 @@ static void   vmbus_chan_task_nobatch(void
  *  @brief Trigger an event notification on the specified channel
  */
 static void
-vmbus_channel_set_event(hv_vmbus_channel *channel)
+vmbus_chan_send_event(hv_vmbus_channel *channel)
 {
        struct vmbus_softc *sc = channel->vmbus_sc;
        uint32_t chanid = channel->ch_id;
@@ -69,16 +69,12 @@ vmbus_channel_set_event(hv_vmbus_channel
            1UL << (chanid & VMBUS_EVTFLAG_MASK));
 
        if (channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) {
-               hv_vmbus_monitor_page *monitor_page;
-
-               monitor_page = sc->vmbus_mnf2;
-               synch_set_bit(channel->monitor_bit,
-                       (uint32_t *)&monitor_page->
-                               
trigger_group[channel->monitor_group].u.pending);
+               atomic_set_int(
+               &sc->vmbus_mnf2->mnf_trigs[channel->ch_montrig_idx].mt_pending,
+               channel->ch_montrig_mask);
        } else {
                hypercall_signal_event(channel->ch_monprm_dma.hv_paddr);
        }
-
 }
 
 static int
@@ -622,9 +618,8 @@ hv_vmbus_channel_send_packet(
            &need_sig);
 
        /* TODO: We should determine if this is optional */
-       if (ret == 0 && need_sig) {
-               vmbus_channel_set_event(channel);
-       }
+       if (ret == 0 && need_sig)
+               vmbus_chan_send_event(channel);
 
        return (ret);
 }
@@ -690,9 +685,8 @@ hv_vmbus_channel_send_packet_pagebuffer(
            &need_sig);
 
        /* TODO: We should determine if this is optional */
-       if (ret == 0 && need_sig) {
-               vmbus_channel_set_event(channel);
-       }
+       if (ret == 0 && need_sig)
+               vmbus_chan_send_event(channel);
 
        return (ret);
 }
@@ -766,9 +760,8 @@ hv_vmbus_channel_send_packet_multipagebu
            &need_sig);
 
        /* TODO: We should determine if this is optional */
-       if (ret == 0 && need_sig) {
-           vmbus_channel_set_event(channel);
-       }
+       if (ret == 0 && need_sig)
+               vmbus_chan_send_event(channel);
 
        return (ret);
 }

Modified: head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/vmbus/hv_channel_mgmt.c Wed Jul 13 09:28:46 2016        
(r302731)
@@ -311,8 +311,14 @@ vmbus_channel_on_offer_internal(struct v
        if (sc->vmbus_version != VMBUS_VERSION_WS2008)
                new_channel->ch_monprm->mp_connid = offer->connection_id;
 
-       new_channel->monitor_group = (uint8_t) offer->monitor_id / 32;
-       new_channel->monitor_bit = (uint8_t) offer->monitor_id % 32;
+       if (new_channel->ch_flags & VMBUS_CHAN_FLAG_HASMNF) {
+               new_channel->ch_montrig_idx =
+                   offer->monitor_id / VMBUS_MONTRIG_LEN;
+               if (new_channel->ch_montrig_idx >= VMBUS_MONTRIGS_MAX)
+                       panic("invalid monitor id %u", offer->monitor_id);
+               new_channel->ch_montrig_mask =
+                   1 << (offer->monitor_id % VMBUS_MONTRIG_LEN);
+       }
 
        /* Select default cpu for this channel. */
        vmbus_channel_select_defcpu(new_channel);

Modified: head/sys/dev/hyperv/vmbus/vmbus.c
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus.c   Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/vmbus/vmbus.c   Wed Jul 13 09:28:46 2016        
(r302731)
@@ -835,7 +835,8 @@ vmbus_dma_alloc(struct vmbus_softc *sc)
                return ENOMEM;
 
        sc->vmbus_mnf2 = hyperv_dmamem_alloc(parent_dtag, PAGE_SIZE, 0,
-           PAGE_SIZE, &sc->vmbus_mnf2_dma, BUS_DMA_WAITOK | BUS_DMA_ZERO);
+           sizeof(struct vmbus_mnf), &sc->vmbus_mnf2_dma,
+           BUS_DMA_WAITOK | BUS_DMA_ZERO);
        if (sc->vmbus_mnf2 == NULL)
                return ENOMEM;
 

Modified: head/sys/dev/hyperv/vmbus/vmbus_reg.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_reg.h       Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/vmbus/vmbus_reg.h       Wed Jul 13 09:28:46 2016        
(r302731)
@@ -72,6 +72,34 @@ struct vmbus_evtflags {
 CTASSERT(sizeof(struct vmbus_evtflags) == VMBUS_EVTFLAGS_SIZE);
 
 /*
+ * Hyper-V Monitor Notification Facility
+ */
+
+struct vmbus_mon_trig {
+       uint32_t        mt_pending;
+       uint32_t        mt_armed;
+} __packed;
+
+#define VMBUS_MONTRIGS_MAX     4
+#define VMBUS_MONTRIG_LEN      32
+
+struct vmbus_mnf {
+       uint32_t        mnf_state;
+       uint32_t        mnf_rsvd1;
+
+       struct vmbus_mon_trig mnf_trigs[VMBUS_MONTRIGS_MAX];
+       uint8_t         mnf_rsvd2[536];
+
+       uint16_t        mnf_lat[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
+       uint8_t         mnf_rsvd3[256];
+
+       struct hyperv_mon_param
+                       mnf_param[VMBUS_MONTRIGS_MAX][VMBUS_MONTRIG_LEN];
+       uint8_t         mnf_rsvd4[1984];
+} __packed;
+CTASSERT(sizeof(struct vmbus_mnf) == PAGE_SIZE);
+
+/*
  * Channel
  */
 

Modified: head/sys/dev/hyperv/vmbus/vmbus_var.h
==============================================================================
--- head/sys/dev/hyperv/vmbus/vmbus_var.h       Wed Jul 13 09:26:33 2016        
(r302730)
+++ head/sys/dev/hyperv/vmbus/vmbus_var.h       Wed Jul 13 09:28:46 2016        
(r302731)
@@ -71,7 +71,7 @@ struct vmbus_softc {
        void                    (*vmbus_event_proc)(struct vmbus_softc *, int);
        u_long                  *vmbus_tx_evtflags;
                                                /* event flags to host */
-       void                    *vmbus_mnf2;    /* monitored by host */
+       struct vmbus_mnf        *vmbus_mnf2;    /* monitored by host */
 
        u_long                  *vmbus_rx_evtflags;
                                                /* compat evtflgs from host */
_______________________________________________
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