Page MenuHomeFreeBSD

D7495.diff
No OneTemporary

D7495.diff

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

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)

Event Timeline