Sync up monitor trigger groups handling to the upstream
authormikeb <mikeb@openbsd.org>
Wed, 17 Aug 2016 17:39:41 +0000 (17:39 +0000)
committermikeb <mikeb@openbsd.org>
Wed, 17 Aug 2016 17:39:41 +0000 (17:39 +0000)
Replace hand rolled atomic bit operations and use MI ones from DRM
and convert event matrixes to arrays of longs.

sys/dev/pv/hyperv.c
sys/dev/pv/hypervreg.h
sys/dev/pv/hypervvar.h

index be9bc97..2ebdfe8 100644 (file)
@@ -533,23 +533,24 @@ hv_event_intr(struct hv_softc *sc)
        struct vmbus_evtflags *evt;
        struct cpu_info *ci = curcpu();
        int cpu = CPU_INFO_UNIT(ci);
-       int bit, dword, maxdword, chanid;
+       int bit, row, maxrow, chanid;
        struct hv_channel *ch;
-       uint32_t *revents, pending;
+       u_long *revents, pending;
 
        evt = (struct vmbus_evtflags *)sc->sc_siep[cpu] +
            VMBUS_SINT_MESSAGE;
        if ((sc->sc_proto == VMBUS_VERSION_WS2008) ||
            (sc->sc_proto == VMBUS_VERSION_WIN7)) {
-               if (atomic_clearbit_ptr(&evt->evt_flags[0], 0) == 0)
+               if (!test_bit(0, &evt->evt_flags[0]))
                        return;
-               maxdword = VMBUS_CHAN_MAX_COMPAT >> 5;
+               clear_bit(0, &evt->evt_flags[0]);
+               maxrow = VMBUS_CHAN_MAX_COMPAT / VMBUS_EVTFLAG_LEN;
                /*
                 * receive size is 1/2 page and divide that by 4 bytes
                 */
                revents = sc->sc_revents;
        } else {
-               maxdword = nitems(evt->evt_flags);
+               maxrow = nitems(evt->evt_flags);
                /*
                 * On Host with Win8 or above, the event page can be
                 * checked directly to get the id of the channel
@@ -558,14 +559,14 @@ hv_event_intr(struct hv_softc *sc)
                revents = &evt->evt_flags[0];
        }
 
-       for (dword = 0; dword < maxdword; dword++) {
-               if (revents[dword] == 0)
+       for (row = 0; row < maxrow; row++) {
+               if (revents[row] == 0)
                        continue;
-               pending = atomic_swap_uint(&revents[dword], 0);
+               pending = atomic_swap_ulong(&revents[row], 0);
                for (bit = 0; pending > 0; pending >>= 1, bit++) {
                        if ((pending & 1) == 0)
                                continue;
-                       chanid = (dword << 5) + bit;
+                       chanid = (row * LONG_BIT) + bit;
                        /* vmbus channel protocol message */
                        if (chanid == 0)
                                continue;
@@ -695,9 +696,8 @@ hv_vmbus_connect(struct hv_softc *sc)
                goto errout;
        }
 
-       sc->sc_wevents = (uint32_t *)sc->sc_events;
-       sc->sc_revents = (uint32_t *)((caddr_t)sc->sc_events +
-           (PAGE_SIZE >> 1));
+       sc->sc_wevents = (u_long *)sc->sc_events;
+       sc->sc_revents = (u_long *)((caddr_t)sc->sc_events + (PAGE_SIZE >> 1));
 
        sc->sc_monitor[0] = km_alloc(PAGE_SIZE, &kv_any, &kp_zero, &kd_nowait);
        if (sc->sc_monitor == NULL) {
@@ -1017,8 +1017,8 @@ hv_process_offer(struct hv_softc *sc, struct hv_offer *co)
                nch->ch_monprm.mp_connid = co->co_chan.chm_connid;
 
        if (co->co_chan.chm_flags1 & VMBUS_CHOFFER_FLAG1_HASMNF) {
-               nch->ch_mgroup = co->co_chan.chm_montrig >> 5;
-               nch->ch_mindex = co->co_chan.chm_montrig & 0x1f;
+               nch->ch_mgroup = co->co_chan.chm_montrig / VMBUS_MONTRIG_LEN;
+               nch->ch_mindex = co->co_chan.chm_montrig % VMBUS_MONTRIG_LEN;
                nch->ch_flags |= CHF_MONITOR;
        }
 
@@ -1207,11 +1207,10 @@ hv_channel_setevent(struct hv_softc *sc, struct hv_channel *ch)
        struct vmbus_mon_trig *mtg;
 
        /* Each uint32_t represents 32 channels */
-       atomic_setbit_ptr((uint32_t *)sc->sc_wevents + (ch->ch_id >> 5),
-           ch->ch_id & 31);
+       set_bit(ch->ch_id, sc->sc_wevents);
        if (ch->ch_flags & CHF_MONITOR) {
                mtg = &sc->sc_monitor[1]->mnf_trigs[ch->ch_mgroup];
-               atomic_setbit_ptr((uint32_t *)&mtg->mt_pending, ch->ch_mindex);
+               set_bit(ch->ch_mindex, &mtg->mt_pending);
        } else
                hv_intr_signal(sc, &ch->ch_monprm);
 }
index 93278db..70f1db5 100644 (file)
@@ -302,8 +302,13 @@ struct vmbus_message {
  * Hyper-V SynIC event flags
  */
 
+#define VMBUS_EVTFLAGS_SIZE    256
+#define VMBUS_EVTFLAGS_MAX     ((VMBUS_EVTFLAGS_SIZE / LONG_BIT) * 8)
+#define VMBUS_EVTFLAG_LEN      LONG_BIT
+#define VMBUS_EVTFLAG_MASK     (LONG_BIT - 1)
+
 struct vmbus_evtflags {
-       uint32_t        evt_flags[64];
+       ulong           evt_flags[VMBUS_EVTFLAGS_MAX];
 } __packed;
 
 /*
index ebd23ba..fb0acbe 100644 (file)
@@ -69,13 +69,10 @@ struct hv_channel {
        struct hv_guid                   ch_inst;
        char                             ch_ident[38];
 
-       uint8_t                          ch_mgroup;
-       uint8_t                          ch_mindex;
-
        void                            *ch_ring;
        uint32_t                         ch_ring_gpadl;
        uint32_t                         ch_ring_npg;
-       ulong                            ch_ring_size;
+       u_long                           ch_ring_size;
 
        struct hv_ring_data              ch_wrd;
        struct hv_ring_data              ch_rrd;
@@ -92,6 +89,8 @@ struct hv_channel {
 #define  CHF_BATCHED                     0x0001
 #define  CHF_MONITOR                     0x0002
 
+       uint8_t                          ch_mgroup;
+       uint8_t                          ch_mindex;
        struct hv_mon_param              ch_monprm __attribute__((aligned(8)));
 
        TAILQ_ENTRY(hv_channel)          ch_entry;
@@ -137,8 +136,8 @@ struct hv_softc {
 
        /* Channel port events page */
        void                            *sc_events;
-       uint32_t                        *sc_wevents;    /* Write events */
-       uint32_t                        *sc_revents;    /* Read events */
+       u_long                          *sc_wevents;    /* Write events */
+       u_long                          *sc_revents;    /* Read events */
 
        /* Monitor pages for parent<->child notifications */
        struct vmbus_mnf                *sc_monitor[2];
@@ -165,28 +164,22 @@ struct hv_softc {
        struct ksensor                   sc_sensor;
 };
 
-static inline int
-atomic_setbit_ptr(volatile void *ptr, int bit)
+static __inline void
+clear_bit(u_int b, volatile void *p)
 {
-       int obit;
-
-       __asm__ __volatile__ ("lock btsl %2,%1; sbbl %0,%0" :
-           "=r" (obit), "=m" (*(volatile long *)ptr) : "Ir" (bit) :
-           "memory");
-
-       return (obit);
+       atomic_clearbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
 }
 
-static inline int
-atomic_clearbit_ptr(volatile void *ptr, int bit)
+static __inline void
+set_bit(u_int b, volatile void *p)
 {
-       int obit;
-
-       __asm__ __volatile__ ("lock btrl %2,%1; sbbl %0,%0" :
-           "=r" (obit), "=m" (*(volatile long *)ptr) : "Ir" (bit) :
-           "memory");
+       atomic_setbits_int(((volatile u_int *)p) + (b >> 5), 1 << (b & 0x1f));
+}
 
-       return (obit);
+static __inline int
+test_bit(u_int b, volatile void *p)
+{
+       return !!(((volatile u_int *)p)[b >> 5] & (1 << (b & 0x1f)));
 }
 
 int    hv_handle_alloc(struct hv_channel *, void *, uint32_t, uint32_t *);