Date: Thu, 13 Dec 2018 04:40:53 +0000 (UTC) From: Matt Macy <mmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r342024 - in head/sys: crypto/aesni opencrypto Message-ID: <201812130440.wBD4erR3014211@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mmacy Date: Thu Dec 13 04:40:53 2018 New Revision: 342024 URL: https://svnweb.freebsd.org/changeset/base/342024 Log: Generalize AES iov optimization Right now, aesni_cipher_alloc does a bit of special-casing for CRYPTO_F_IOV, to not do any allocation if the first uio is large enough for the requested size. While working on ZFS crypto port, I ran into horrible performance because the code uses scatter-gather, and many of the times the data to encrypt was in the second entry. This code looks through the list, and tries to see if there is a single uio that can contain the requested data, and, if so, uses that. This has a slight impact on the current consumers, in that the check is a little more complicated for the ones that use CRYPTO_F_IOV -- but none of them meet the criteria for testing more than one. Submitted by: sef at ixsystems.com Reviewed by: cem@ MFC after: 3 days Sponsored by: iX Systems Differential Revision: https://reviews.freebsd.org/D18522 Modified: head/sys/crypto/aesni/aesni.c head/sys/opencrypto/criov.c head/sys/opencrypto/cryptodev.h Modified: head/sys/crypto/aesni/aesni.c ============================================================================== --- head/sys/crypto/aesni/aesni.c Thu Dec 13 03:12:15 2018 (r342023) +++ head/sys/crypto/aesni/aesni.c Thu Dec 13 04:40:53 2018 (r342024) @@ -403,29 +403,14 @@ static uint8_t * aesni_cipher_alloc(struct cryptodesc *enccrd, struct cryptop *crp, bool *allocated) { - struct mbuf *m; - struct uio *uio; - struct iovec *iov; uint8_t *addr; - if (crp->crp_flags & CRYPTO_F_IMBUF) { - m = (struct mbuf *)crp->crp_buf; - if (m->m_next != NULL) - goto alloc; - addr = mtod(m, uint8_t *); - } else if (crp->crp_flags & CRYPTO_F_IOV) { - uio = (struct uio *)crp->crp_buf; - if (uio->uio_iovcnt != 1) - goto alloc; - iov = uio->uio_iov; - addr = (uint8_t *)iov->iov_base; - } else - addr = (uint8_t *)crp->crp_buf; - *allocated = false; - addr += enccrd->crd_skip; - return (addr); - -alloc: + addr = crypto_contiguous_subsegment(crp->crp_flags, + crp->crp_buf, enccrd->crd_skip, enccrd->crd_len); + if (addr != NULL) { + *allocated = false; + return (addr); + } addr = malloc(enccrd->crd_len, M_AESNI, M_NOWAIT); if (addr != NULL) { *allocated = true; Modified: head/sys/opencrypto/criov.c ============================================================================== --- head/sys/opencrypto/criov.c Thu Dec 13 03:12:15 2018 (r342023) +++ head/sys/opencrypto/criov.c Thu Dec 13 04:40:53 2018 (r342024) @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$"); #include <sys/kernel.h> #include <sys/mbuf.h> #include <sys/uio.h> +#include <sys/limits.h> +#include <sys/lock.h> #include <opencrypto/cryptodev.h> @@ -239,3 +241,55 @@ crypto_mbuftoiov(struct mbuf *mbuf, struct iovec **iov *cnt = i; return 0; } + +static inline void * +m_contiguous_subsegment(struct mbuf *m, size_t skip, size_t len) +{ + int rel_off; + + MPASS(skip <= INT_MAX); + + m = m_getptr(m, (int)skip, &rel_off); + if (m == NULL) + return (NULL); + + MPASS(rel_off >= 0); + skip = rel_off; + if (skip + len > m->m_len) + return (NULL); + + return (mtod(m, char*) + skip); +} + +static inline void * +cuio_contiguous_segment(struct uio *uio, size_t skip, size_t len) +{ + int rel_off, idx; + + MPASS(skip <= INT_MAX); + idx = cuio_getptr(uio, (int)skip, &rel_off); + if (idx < 0) + return (NULL); + + MPASS(rel_off >= 0); + skip = rel_off; + if (skip + len > uio->uio_iov[idx].iov_len) + return (NULL); + return ((char *)uio->uio_iov[idx].iov_base + skip); +} + +void * +crypto_contiguous_subsegment(int crp_flags, void *crpbuf, + size_t skip, size_t len) +{ + if ((crp_flags & CRYPTO_F_IMBUF) != 0) + return (m_contiguous_subsegment(crpbuf, skip, len)); + else if ((crp_flags & CRYPTO_F_IOV) != 0) + return (cuio_contiguous_segment(crpbuf, skip, len)); + else { + MPASS((crp_flags & (CRYPTO_F_IMBUF | CRYPTO_F_IOV)) != + (CRYPTO_F_IMBUF | CRYPTO_F_IOV)); + return ((char*)crpbuf + skip); + } +} + Modified: head/sys/opencrypto/cryptodev.h ============================================================================== --- head/sys/opencrypto/cryptodev.h Thu Dec 13 03:12:15 2018 (r342023) +++ head/sys/opencrypto/cryptodev.h Thu Dec 13 04:40:53 2018 (r342024) @@ -564,5 +564,7 @@ extern void crypto_copydata(int flags, caddr_t buf, in extern int crypto_apply(int flags, caddr_t buf, int off, int len, int (*f)(void *, void *, u_int), void *arg); +extern void *crypto_contiguous_subsegment(int, void *, size_t, size_t); + #endif /* _KERNEL */ #endif /* _CRYPTO_CRYPTO_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812130440.wBD4erR3014211>