summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2016-08-17 17:39:41 +0000
committermikeb <mikeb@openbsd.org>2016-08-17 17:39:41 +0000
commit9027aab0fb539636a6ae5e8deedab7fb6bf3d2fa (patch)
treeda8f89fc711e6a6593d29aa00d5e45bad557a566
parentReplace hand rolled atomic bit operations and use MI ones from DRM (diff)
downloadwireguard-openbsd-9027aab0fb539636a6ae5e8deedab7fb6bf3d2fa.tar.xz
wireguard-openbsd-9027aab0fb539636a6ae5e8deedab7fb6bf3d2fa.zip
Sync up monitor trigger groups handling to the upstream
Replace hand rolled atomic bit operations and use MI ones from DRM and convert event matrixes to arrays of longs.
-rw-r--r--sys/dev/pv/hyperv.c33
-rw-r--r--sys/dev/pv/hypervreg.h7
-rw-r--r--sys/dev/pv/hypervvar.h39
3 files changed, 38 insertions, 41 deletions
diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c
index be9bc9747f2..2ebdfe83897 100644
--- a/sys/dev/pv/hyperv.c
+++ b/sys/dev/pv/hyperv.c
@@ -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);
}
diff --git a/sys/dev/pv/hypervreg.h b/sys/dev/pv/hypervreg.h
index 93278db266c..70f1db5a17c 100644
--- a/sys/dev/pv/hypervreg.h
+++ b/sys/dev/pv/hypervreg.h
@@ -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;
/*
diff --git a/sys/dev/pv/hypervvar.h b/sys/dev/pv/hypervvar.h
index ebd23ba3ee5..fb0acbe591e 100644
--- a/sys/dev/pv/hypervvar.h
+++ b/sys/dev/pv/hypervvar.h
@@ -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 *);