diff options
author | pjd <pjd@FreeBSD.org> | 2011-04-21 13:35:20 +0000 |
---|---|---|
committer | pjd <pjd@FreeBSD.org> | 2011-04-21 13:35:20 +0000 |
commit | 4e8487e9df27d60a7b93c0a6e97e352d205c8249 (patch) | |
tree | 84596a30433f9374b92927319239e1df471d0a47 | |
parent | 7e657fb243221cb5e19b84eea2d3c3fbb33872f2 (diff) | |
download | FreeBSD-src-4e8487e9df27d60a7b93c0a6e97e352d205c8249.zip FreeBSD-src-4e8487e9df27d60a7b93c0a6e97e352d205c8249.tar.gz |
If number of keys for the given provider doesn't exceed the limit,
allocate all of them at attach time. This allows to avoid moving
keys around in the most-recently-used queue and needs no mutex
synchronization nor refcounting.
MFC after: 2 weeks
-rw-r--r-- | sys/geom/eli/g_eli_key_cache.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/sys/geom/eli/g_eli_key_cache.c b/sys/geom/eli/g_eli_key_cache.c index eab45ac..8c2c400 100644 --- a/sys/geom/eli/g_eli_key_cache.c +++ b/sys/geom/eli/g_eli_key_cache.c @@ -217,6 +217,16 @@ g_eli_key_init(struct g_eli_softc *sc) sc->sc_ekeys_allocated = 0; TAILQ_INIT(&sc->sc_ekeys_queue); RB_INIT(&sc->sc_ekeys_tree); + if (sc->sc_ekeys_total <= g_eli_key_cache_limit) { + uint64_t keyno; + + for (keyno = 0; keyno < sc->sc_ekeys_total; keyno++) + (void)g_eli_key_allocate(sc, keyno); + KASSERT(sc->sc_ekeys_total == sc->sc_ekeys_allocated, + ("sc_ekeys_total=%ju != sc_ekeys_allocated=%ju", + (uintmax_t)sc->sc_ekeys_total, + (uintmax_t)sc->sc_ekeys_allocated)); + } } mtx_unlock(&sc->sc_ekeys_lock); } @@ -268,6 +278,13 @@ g_eli_key_hold(struct g_eli_softc *sc, off_t offset, size_t blocksize) keysearch.gek_keyno = keyno; + if (sc->sc_ekeys_total == sc->sc_ekeys_allocated) { + /* We have all the keys, so avoid some overhead. */ + key = RB_FIND(g_eli_key_tree, &sc->sc_ekeys_tree, &keysearch); + KASSERT(key != NULL, ("No key %ju found.", (uintmax_t)keyno)); + return (key->gek_key); + } + mtx_lock(&sc->sc_ekeys_lock); key = RB_FIND(g_eli_key_tree, &sc->sc_ekeys_tree, &keysearch); if (key != NULL) { @@ -306,6 +323,9 @@ g_eli_key_drop(struct g_eli_softc *sc, uint8_t *rawkey) if ((sc->sc_flags & G_ELI_FLAG_SINGLE_KEY) != 0) return; + if (sc->sc_ekeys_total == sc->sc_ekeys_allocated) + return; + mtx_lock(&sc->sc_ekeys_lock); KASSERT(key->gek_count > 0, ("key->gek_count=%d", key->gek_count)); key->gek_count--; |