From owner-svn-src-all@freebsd.org Tue Aug 16 21:20:06 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 5C3B2BBBDE9; Tue, 16 Aug 2016 21:20:06 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 33FF21766; Tue, 16 Aug 2016 21:20:06 +0000 (UTC) (envelope-from landonf@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u7GLK5xM076268; Tue, 16 Aug 2016 21:20:05 GMT (envelope-from landonf@FreeBSD.org) Received: (from landonf@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u7GLK53I076266; Tue, 16 Aug 2016 21:20:05 GMT (envelope-from landonf@FreeBSD.org) Message-Id: <201608162120.u7GLK53I076266@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: landonf set sender to landonf@FreeBSD.org using -f From: "Landon J. Fuller" Date: Tue, 16 Aug 2016 21:20:05 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r304242 - head/sys/dev/bhnd/bhndb X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Aug 2016 21:20:06 -0000 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 +#include #include #include @@ -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 #include +#include #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); } /**