On Wed, Oct 12, 2022 at 04:59:16PM -0500, Robert Elliott wrote: > diff --git a/arch/x86/crypto/sha1_ssse3_glue.c b/arch/x86/crypto/sha1_ssse3_glue.c > index 44340a1139e0..a9f5779b41ca 100644 > --- a/arch/x86/crypto/sha1_ssse3_glue.c > +++ b/arch/x86/crypto/sha1_ssse3_glue.c > @@ -26,6 +26,8 @@ > #include <crypto/sha1_base.h> > #include <asm/simd.h> > > +#define FPU_BYTES 4096U /* avoid kernel_fpu_begin/end scheduler/rcu stalls */ > + > static int sha1_update(struct shash_desc *desc, const u8 *data, > unsigned int len, sha1_block_fn *sha1_xform) > { > @@ -41,9 +43,18 @@ static int sha1_update(struct shash_desc *desc, const u8 *data, > */ > BUILD_BUG_ON(offsetof(struct sha1_state, state) != 0); > > - kernel_fpu_begin(); > - sha1_base_do_update(desc, data, len, sha1_xform); > - kernel_fpu_end(); > + do { > + unsigned int chunk = min(len, FPU_BYTES); > + > + if (chunk) { > + kernel_fpu_begin(); > + sha1_base_do_update(desc, data, chunk, sha1_xform); > + kernel_fpu_end(); > + } > + > + len -= chunk; > + data += chunk; > + } while (len); 'len' can't be 0 at the beginning of this loop, so the 'if (chunk)' check isn't needed. And it wouldn't make sense even if 'len' could be 0, since a while loop could just be used in that case. - Eric