From abbee944d54fce28c21e5ff5ae62eff40a24758b Mon Sep 17 00:00:00 2001 From: Mike Belopuhov Date: Fri, 5 Aug 2016 18:16:05 +0000 Subject: Switch pending event clearing to an atomic swap operation Rather than performing an atomic bit clearing for every encountered event bit set we can adjust the code to perform an atomic swap of a single row of the events array and decrease the amount of expensive atomic operations. From FreeBSD. --- sys/dev/pv/hyperv.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'sys/dev/pv') diff --git a/sys/dev/pv/hyperv.c b/sys/dev/pv/hyperv.c index 1aba89795e1..7a8e22cca19 100644 --- a/sys/dev/pv/hyperv.c +++ b/sys/dev/pv/hyperv.c @@ -534,7 +534,7 @@ hv_event_intr(struct hv_softc *sc) int cpu = CPU_INFO_UNIT(ci); int bit, dword, maxdword, relid; struct hv_channel *ch; - uint32_t *revents; + uint32_t *revents, pending; evt = (struct hv_synic_event_flags *)sc->sc_siep[cpu] + HV_MESSAGE_SINT; if ((sc->sc_proto == HV_VMBUS_VERSION_WS2008) || @@ -559,8 +559,9 @@ hv_event_intr(struct hv_softc *sc) for (dword = 0; dword < maxdword; dword++) { if (revents[dword] == 0) continue; - for (bit = 0; bit < 32; bit++) { - if (!atomic_clearbit_ptr(&revents[dword], bit)) + pending = atomic_swap_uint(&revents[dword], 0); + for (bit = 0; pending > 0; pending >>= 1, bit++) { + if ((pending & 1) == 0) continue; relid = (dword << 5) + bit; /* vmbus channel protocol message */ -- cgit v1.2.3