svn commit: r304242 - head/sys/dev/bhnd/bhndb
Landon J. Fuller
landonf at FreeBSD.org
Tue Aug 16 21:20:06 UTC 2016
Author: landonf
Date: Tue Aug 16 21:20:05 2016
New Revision: 304242
URL: https://svnweb.freebsd.org/changeset/base/304242
Log:
bhndb(4): Drop MIPS-incompatible __builtin_ctz dependency.
This replaces the bitfield representation of the bhndb register window
freelist with the bitstring API, eliminating a dependency on
(MIPS-unsupported) __builtin_ctz().
Approved by: adrian (mentor)
Differential Revision: https://reviews.freebsd.org/D7495
Modified:
head/sys/dev/bhnd/bhndb/bhndb_private.h
head/sys/dev/bhnd/bhndb/bhndb_subr.c
Modified: head/sys/dev/bhnd/bhndb/bhndb_private.h
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_private.h Tue Aug 16 21:17:51 2016 (r304241)
+++ head/sys/dev/bhnd/bhndb/bhndb_private.h Tue Aug 16 21:20:05 2016 (r304242)
@@ -33,6 +33,7 @@
#define _BHND_BHNDB_PRIVATE_H_
#include <sys/param.h>
+#include <sys/bitstring.h>
#include <sys/bus.h>
#include <sys/systm.h>
@@ -184,21 +185,23 @@ struct bhndb_resources {
struct bhndb_dw_alloc *dw_alloc; /**< dynamic window allocation records */
size_t dwa_count; /**< number of dynamic windows available. */
- uint32_t dwa_freelist; /**< dynamic window free list */
+ bitstr_t *dwa_freelist; /**< dynamic window free list */
bhndb_priority_t min_prio; /**< minimum resource priority required to
allocate a dynamic window */
};
/**
- * Returns true if the all dynamic windows have been exhausted, false
+ * Returns true if the all dynamic windows are marked free, false
* otherwise.
*
* @param br The resource state to check.
*/
static inline bool
-bhndb_dw_exhausted(struct bhndb_resources *br)
+bhndb_dw_all_free(struct bhndb_resources *br)
{
- return (br->dwa_freelist == 0);
+ int bit;
+ bit_ffs(br->dwa_freelist, br->dwa_count, &bit);
+ return (bit == -1);
}
/**
@@ -209,12 +212,14 @@ bhndb_dw_exhausted(struct bhndb_resource
static inline struct bhndb_dw_alloc *
bhndb_dw_next_free(struct bhndb_resources *br)
{
- struct bhndb_dw_alloc *dw_free;
+ struct bhndb_dw_alloc *dw_free;
+ int bit;
- if (bhndb_dw_exhausted(br))
+ bit_ffc(br->dwa_freelist, br->dwa_count, &bit);
+ if (bit == -1)
return (NULL);
- dw_free = &br->dw_alloc[__builtin_ctz(br->dwa_freelist)];
+ dw_free = &br->dw_alloc[bit];
KASSERT(LIST_EMPTY(&dw_free->refs),
("free list out of sync with refs"));
@@ -233,7 +238,7 @@ bhndb_dw_is_free(struct bhndb_resources
{
bool is_free = LIST_EMPTY(&dwa->refs);
- KASSERT(is_free == ((br->dwa_freelist & (1 << dwa->rnid)) != 0),
+ KASSERT(is_free == !bit_test(br->dwa_freelist, dwa->rnid),
("refs out of sync with free list"));
return (is_free);
Modified: head/sys/dev/bhnd/bhndb/bhndb_subr.c
==============================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_subr.c Tue Aug 16 21:17:51 2016 (r304241)
+++ head/sys/dev/bhnd/bhndb/bhndb_subr.c Tue Aug 16 21:20:05 2016 (r304242)
@@ -32,6 +32,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include "bhndb_private.h"
#include "bhndbvar.h"
@@ -264,7 +265,7 @@ bhndb_alloc_resources(device_t dev, devi
const struct bhndb_regwin *win;
bus_size_t last_window_size;
size_t res_num;
- u_int rnid;
+ int rnid;
int error;
bool free_parent_res;
bool free_ht_mem, free_br_mem;
@@ -371,10 +372,10 @@ bhndb_alloc_resources(device_t dev, devi
}
/* Fetch the dynamic regwin count and verify that it does not exceed
- * what is representable via our freelist bitmask. */
+ * what is representable via our freelist bitstring. */
r->dwa_count = bhndb_regwin_count(cfg->register_windows,
BHNDB_REGWIN_T_DYN);
- if (r->dwa_count >= (8 * sizeof(r->dwa_freelist))) {
+ if (r->dwa_count >= INT_MAX) {
device_printf(r->dev, "max dynamic regwin count exceeded\n");
goto failed;
}
@@ -385,8 +386,12 @@ bhndb_alloc_resources(device_t dev, devi
if (r->dw_alloc == NULL)
goto failed;
- /* Initialize the dynamic window table and freelist. */
- r->dwa_freelist = 0;
+ /* Allocate the dynamic window allocation freelist */
+ r->dwa_freelist = bit_alloc(r->dwa_count, M_BHND, M_NOWAIT);
+ if (r->dwa_freelist == NULL)
+ goto failed;
+
+ /* Initialize the dynamic window table */
rnid = 0;
last_window_size = 0;
for (win = cfg->register_windows;
@@ -446,9 +451,6 @@ bhndb_alloc_resources(device_t dev, devi
goto failed;
}
- /* Add to freelist */
- r->dwa_freelist |= (1 << rnid);
-
rnid++;
}
@@ -473,6 +475,9 @@ failed:
if (r->dw_alloc != NULL)
free(r->dw_alloc, M_BHND);
+ if (r->dwa_freelist != NULL)
+ free(r->dwa_freelist, M_BHND);
+
free (r, M_BHND);
return (NULL);
@@ -491,9 +496,17 @@ bhndb_free_resources(struct bhndb_resour
struct bhndb_dw_rentry *dwr, *dwr_next;
/* No window regions may still be held */
- if (__builtin_popcount(br->dwa_freelist) != br->dwa_count) {
- device_printf(br->dev, "leaked %llu dynamic register regions\n",
- (unsigned long long) br->dwa_count - br->dwa_freelist);
+ if (!bhndb_dw_all_free(br)) {
+ for (int i = 0; i < br->dwa_count; i++) {
+ dwa = &br->dw_alloc[i];
+
+ /* Skip free dynamic windows */
+ if (bhndb_dw_is_free(br, dwa))
+ continue;
+
+ device_printf(br->dev,
+ "leaked dynamic register window %d\n", dwa->rnid);
+ }
}
/* Release resources allocated through our parent. */
@@ -523,6 +536,7 @@ bhndb_free_resources(struct bhndb_resour
free(br->res, M_BHND);
free(br->res_spec, M_BHND);
free(br->dw_alloc, M_BHND);
+ free(br->dwa_freelist, M_BHND);
}
/**
@@ -765,7 +779,7 @@ bhndb_dw_retain(struct bhndb_resources *
LIST_INSERT_HEAD(&dwa->refs, rentry, dw_link);
/* Update the free list */
- br->dwa_freelist &= ~(1 << (dwa->rnid));
+ bit_set(br->dwa_freelist, dwa->rnid);
return (0);
}
@@ -794,7 +808,7 @@ bhndb_dw_release(struct bhndb_resources
/* If this was the last reference, update the free list */
if (LIST_EMPTY(&dwa->refs))
- br->dwa_freelist |= (1 << (dwa->rnid));
+ bit_clear(br->dwa_freelist, dwa->rnid);
}
/**
More information about the svn-src-head
mailing list