diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-10 14:20:45 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-03-10 14:20:45 +0000 |
commit | 564658a323dfcc74589985f7976f99e736f8a89d (patch) | |
tree | 6b86f09c7cd8620e6f3c4ba3acea6de4dc4cbc65 /sys | |
parent | 7e281846cd8f66019ec822cf16beeadfd980b306 (diff) |
Use SMR instead of reference counting for session reclamation.
This reduces the need of atomic operations. The lookup tree still
requires serialization, though.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/octeon/dev/octcrypto.c | 42 |
1 files changed, 25 insertions, 17 deletions
diff --git a/sys/arch/octeon/dev/octcrypto.c b/sys/arch/octeon/dev/octcrypto.c index 15d1aa32482..35f7e77aa47 100644 --- a/sys/arch/octeon/dev/octcrypto.c +++ b/sys/arch/octeon/dev/octcrypto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octcrypto.c,v 1.2 2018/12/16 14:43:38 visa Exp $ */ +/* $OpenBSD: octcrypto.c,v 1.3 2019/03/10 14:20:44 visa Exp $ */ /* * Copyright (c) 2018 Visa Hankala @@ -26,6 +26,7 @@ #include <sys/malloc.h> #include <sys/mbuf.h> #include <sys/pool.h> +#include <sys/smr.h> #include <sys/tree.h> #include <crypto/cryptodev.h> @@ -56,10 +57,10 @@ struct octcrypto_hmac { struct octcrypto_session { uint32_t ses_sid; /* RB key, keep first */ - unsigned int ses_refs; RBT_ENTRY(octrcypto_session) ses_entry; struct octcrypto_softc *ses_sc; + struct smr_entry ses_smr; /* AES parameters */ uint64_t ses_key[4]; @@ -102,7 +103,8 @@ int octcrypto_process(struct cryptop *); struct octcrypto_session * octcrypto_get(struct octcrypto_softc *, uint32_t); -void octcrypto_put(struct octcrypto_session *); +void octcrypto_free(struct octcrypto_session *); +void octcrypto_free_smr(void *); void octcrypto_hmac(struct cryptodesc *, uint8_t *, size_t, struct octcrypto_session *, uint64_t *); @@ -285,24 +287,21 @@ octcrypto_get(struct octcrypto_softc *sc, uint32_t sid) { struct octcrypto_session *ses; + SMR_ASSERT_CRITICAL(); + mtx_enter(&sc->sc_mtx); ses = RBT_FIND(octcrypto_tree, &sc->sc_sessions, (struct octcrypto_session *)&sid); - if (ses != NULL) - atomic_inc_int(&ses->ses_refs); mtx_leave(&sc->sc_mtx); return ses; } void -octcrypto_put(struct octcrypto_session *ses) +octcrypto_free(struct octcrypto_session *ses) { struct auth_hash *axf; struct swcr_data *swd; - if (atomic_dec_int_nv(&ses->ses_refs) > 0) - return; - if (ses->ses_swd != NULL) { swd = ses->ses_swd; axf = swd->sw_axf; @@ -322,6 +321,14 @@ octcrypto_put(struct octcrypto_session *ses) pool_put(&octcryptopl, ses); } +void +octcrypto_free_smr(void *arg) +{ + struct octcrypto_session *ses = arg; + + octcrypto_free(ses); +} + int octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri) { @@ -344,7 +351,7 @@ octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri) if (ses == NULL) return ENOMEM; ses->ses_sc = sc; - ses->ses_refs = 1; + smr_init(&ses->ses_smr); for (c = cri; c != NULL; c = c->cri_next) { switch (c->cri_alg) { @@ -454,7 +461,7 @@ octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri) swd = malloc(sizeof(struct swcr_data), M_CRYPTO_DATA, M_NOWAIT | M_ZERO); if (swd == NULL) { - octcrypto_put(ses); + octcrypto_free(ses); return ENOMEM; } ses->ses_swd = swd; @@ -462,14 +469,14 @@ octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri) swd->sw_ictx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if (swd->sw_ictx == NULL) { - octcrypto_put(ses); + octcrypto_free(ses); return ENOMEM; } swd->sw_octx = malloc(axf->ctxsize, M_CRYPTO_DATA, M_NOWAIT); if (swd->sw_octx == NULL) { - octcrypto_put(ses); + octcrypto_free(ses); return ENOMEM; } @@ -503,7 +510,7 @@ octcrypto_newsession(uint32_t *sidp, struct cryptoini *cri) break; default: - octcrypto_put(ses); + octcrypto_free(ses); return EINVAL; } } @@ -542,7 +549,7 @@ octcrypto_freesession(uint64_t tid) if (ses == NULL) return EINVAL; - octcrypto_put(ses); + smr_call(&ses->ses_smr, octcrypto_free_smr, ses); return 0; } @@ -595,6 +602,7 @@ octcrypto_process(struct cryptop *crp) KASSERT(crp->crp_ndesc >= 1); + smr_read_enter(); ses = octcrypto_get(sc, (uint32_t)crp->crp_sid); if (ses == NULL) { error = EINVAL; @@ -650,8 +658,8 @@ octcrypto_process(struct cryptop *crp) } out: - if (ses != NULL) - octcrypto_put(ses); + smr_read_leave(); + crp->crp_etype = error; crypto_done(crp); return error; |