hrev52050 adds 2 changesets to branch 'master'
old head: dc26a6655443f7f2f5ade0fff203beb0bcdfd8fe
new head: 6a138e1704fd5dc12e4eef88e3c18c5b1af7d414
overview:
https://git.haiku-os.org/haiku/log/?qt=range&q=6a138e1704fd+%5Edc26a6655443
----------------------------------------------------------------------------
7a41fb91374b: freebsd11_network: Implement counter(9) using atomics.
See inline comment.
6a138e1704fd: freebsd11_network: Enable previously-disabled uses of counter(9).
Tested and verified this doesn't break anything.
[ Augustin Cavalier <waddlesplash@xxxxxxxxx> ]
----------------------------------------------------------------------------
4 files changed, 75 insertions(+), 19 deletions(-)
.../network/wlan/iprowifi3945/dev/wpi/if_wpi.c | 3 -
.../network/wlan/iprowifi4965/dev/iwn/if_iwn.c | 8 --
.../freebsd11_network/compat/sys/counter.h | 77 +++++++++++++++++++-
.../compat/freebsd11_wlan/net80211/ieee80211.c | 6 --
############################################################################
Commit: 7a41fb91374bd6873a982e614d7954386928177e
URL: https://git.haiku-os.org/haiku/commit/?id=7a41fb91374b
Author: Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date: Sat Jun 30 03:17:31 2018 UTC
freebsd11_network: Implement counter(9) using atomics.
See inline comment.
----------------------------------------------------------------------------
diff --git a/src/libs/compat/freebsd11_network/compat/sys/counter.h
b/src/libs/compat/freebsd11_network/compat/sys/counter.h
index d4133a46e3..3f0dd04701 100644
--- a/src/libs/compat/freebsd11_network/compat/sys/counter.h
+++ b/src/libs/compat/freebsd11_network/compat/sys/counter.h
@@ -1,12 +1,85 @@
/*
- * Copyright 2017 Haiku Inc. All rights reserved.
+ * Copyright 2017-2018, Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _FBSD_COMPAT_SYS_COUNTER_H_
#define _FBSD_COMPAT_SYS_COUNTER_H_
+#include <machine/atomic.h>
+#include <sys/malloc.h>
-typedef uint64_t *counter_u64_t;
+
+/* FreeBSD does not use atomics: it has a per-CPU data storage structure
+ * that it adds to whenever someone calls add(), and then only locks and
+ * coalesces it whenever fetch() is called. This means that on some
+ * architectures (e.g. x86_64), adding to the counter is one instruction.
+ *
+ * However, this seems to be for the most part overengineering, as its
+ * only uses seem to be statistical counting in semi-performance-critical
paths.
+ * Axel noted in #12328 that there's a potential way to implement FreeBSD's
+ * method on Haiku using cpu_ent, but that atomics were "perfectly fine",
+ * so we will go with that for now.
+ */
+
+
+typedef uint64_t* counter_u64_t;
+
+
+static inline counter_u64_t
+counter_u64_alloc(int wait)
+{
+ return (counter_u64_t)_kernel_malloc(sizeof(uint64_t), wait | M_ZERO);
+}
+
+
+static inline void
+counter_u64_free(counter_u64_t c)
+{
+ _kernel_free(c);
+}
+
+
+static inline void
+counter_u64_add(counter_u64_t c, int64_t v)
+{
+ atomic_add64((int64*)c, v);
+}
+
+
+static inline uint64_t
+counter_u64_fetch(counter_u64_t c)
+{
+ return atomic_get64((int64*)c);
+}
+
+
+static inline void
+counter_u64_zero(counter_u64_t c)
+{
+ atomic_set64((int64*)c, 0);
+}
+
+
+static inline void
+counter_enter()
+{
+ // unneeded; counters are atomic
+}
+
+
+static inline void
+counter_exit()
+{
+ // unneeded; counters are atomic
+}
+
+
+static inline void
+counter_u64_add_protected(counter_u64_t c, int64_t v)
+{
+ // counters are atomic
+ counter_u64_add(c, v);
+}
#endif
############################################################################
Revision: hrev52050
Commit: 6a138e1704fd5dc12e4eef88e3c18c5b1af7d414
URL: https://git.haiku-os.org/haiku/commit/?id=6a138e1704fd
Author: Augustin Cavalier <waddlesplash@xxxxxxxxx>
Date: Sat Jun 30 03:40:29 2018 UTC
freebsd11_network: Enable previously-disabled uses of counter(9).
Tested and verified this doesn't break anything.
----------------------------------------------------------------------------
diff --git
a/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c
b/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c
index 4b316409fe..826ba36158 100644
--- a/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c
+++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi3945/dev/wpi/if_wpi.c
@@ -2036,10 +2036,7 @@ wpi_rx_done(struct wpi_softc *sc, struct wpi_rx_desc
*desc,
fail2: m_freem(m);
fail1:
- return;
-#ifndef __HAIKU__
counter_u64_add(ic->ic_ierrors, 1);
-#endif
}
static void
diff --git
a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
index 69be8a2244..0ce78aa065 100644
--- a/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
+++ b/src/add-ons/kernel/drivers/network/wlan/iprowifi4965/dev/iwn/if_iwn.c
@@ -3016,18 +3016,14 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc
*desc,
if ((flags & IWN_RX_NOERROR) != IWN_RX_NOERROR) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: RX flags error %x\n",
__func__, flags);
-#ifndef __HAIKU__
counter_u64_add(ic->ic_ierrors, 1);
-#endif
return;
}
/* Discard frames that are too short. */
if (len < sizeof (struct ieee80211_frame_ack)) {
DPRINTF(sc, IWN_DEBUG_RECV, "%s: frame too short: %d\n",
__func__, len);
-#ifndef __HAIKU__
counter_u64_add(ic->ic_ierrors, 1);
-#endif
return;
}
@@ -3035,9 +3031,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc
*desc,
if (m1 == NULL) {
DPRINTF(sc, IWN_DEBUG_ANY, "%s: no mbuf to restock ring\n",
__func__);
-#ifndef __HAIKU__
counter_u64_add(ic->ic_ierrors, 1);
-#endif
return;
}
bus_dmamap_unload(ring->data_dmat, data->map);
@@ -3062,9 +3056,7 @@ iwn_rx_done(struct iwn_softc *sc, struct iwn_rx_desc
*desc,
ring->desc[ring->cur] = htole32(paddr >> 8);
bus_dmamap_sync(ring->desc_dma.tag, ring->desc_dma.map,
BUS_DMASYNC_PREWRITE);
-#ifndef __HAIKU__
counter_u64_add(ic->ic_ierrors, 1);
-#endif
return;
}
diff --git a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
index 4b1aec43fc..858b90612d 100644
--- a/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
+++ b/src/libs/compat/freebsd11_wlan/net80211/ieee80211.c
@@ -311,10 +311,8 @@ ieee80211_ifattach(struct ieee80211com *ic)
taskqueue_thread_enqueue, &ic->ic_tq);
taskqueue_start_threads(&ic->ic_tq, 1, PI_NET, "%s net80211 taskq",
ic->ic_name);
-#ifndef __HAIKU__
ic->ic_ierrors = counter_u64_alloc(M_WAITOK);
ic->ic_oerrors = counter_u64_alloc(M_WAITOK);
-#endif
/*
* Fill in 802.11 available channel set, mark all
* available channels as active, and pick a default
@@ -395,10 +393,8 @@ ieee80211_ifdetach(struct ieee80211com *ic)
ieee80211_power_detach(ic);
ieee80211_node_detach(ic);
-#ifndef __HAIKU__
counter_u64_free(ic->ic_ierrors);
counter_u64_free(ic->ic_oerrors);
-#endif
taskqueue_free(ic->ic_tq);
IEEE80211_TX_LOCK_DESTROY(ic);
@@ -457,14 +453,12 @@ ieee80211_get_counter(struct ifnet *ifp, ift_counter cnt)
rv = if_get_counter_default(ifp, cnt);
switch (cnt) {
-#ifndef __HAIKU__
case IFCOUNTER_OERRORS:
rv += counter_u64_fetch(ic->ic_oerrors);
break;
case IFCOUNTER_IERRORS:
rv += counter_u64_fetch(ic->ic_ierrors);
break;
-#endif
default:
break;
}