Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F173403489
D7495.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D7495.diff
View Options
Index: head/sys/dev/bhnd/bhndb/bhndb_private.h
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_private.h
+++ head/sys/dev/bhnd/bhndb/bhndb_private.h
@@ -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_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 @@
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 @@
{
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);
Index: head/sys/dev/bhnd/bhndb/bhndb_subr.c
===================================================================
--- head/sys/dev/bhnd/bhndb/bhndb_subr.c
+++ head/sys/dev/bhnd/bhndb/bhndb_subr.c
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/limits.h>
#include "bhndb_private.h"
#include "bhndbvar.h"
@@ -264,7 +265,7 @@
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 @@
}
/* 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 @@
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 @@
goto failed;
}
- /* Add to freelist */
- r->dwa_freelist |= (1 << rnid);
-
rnid++;
}
@@ -473,6 +475,9 @@
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 @@
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 @@
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 @@
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 @@
/* 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);
}
/**
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Sep 26, 6:00 PM (7 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39682002
Default Alt Text
D7495.diff (4 KB)
Attached To
Mode
D7495: [bhndb] Drop MIPS-incompatible __builtin_ctz dependency.
Attached
Detach File
Event Timeline
Log In to Comment