crypto: deflate - Make the acomp walk atomic
authorHerbert Xu <herbert@gondor.apana.org.au>
Tue, 15 Apr 2025 09:23:19 +0000 (17:23 +0800)
committerHerbert Xu <herbert@gondor.apana.org.au>
Thu, 17 Apr 2025 02:41:47 +0000 (10:41 +0800)
Add an atomic flag to the acomp walk and use that in deflate.
Due to the use of a per-cpu context, it is impossible to sleep
during the walk in deflate.

Reported-by: kernel test robot <oliver.sang@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202504151654.4c3b6393-lkp@intel.com
Fixes: 08cabc7d3c86 ("crypto: deflate - Convert to acomp")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
crypto/acompress.c
crypto/deflate.c
include/crypto/internal/acompress.h

index 606d09a7fbfd246be9042bb172ec85e52621a0b7..b0f9192f6b2eb47200b06ff87744a8d22ef17a29 100644 (file)
@@ -536,7 +536,7 @@ int acomp_walk_next_dst(struct acomp_walk *walk)
 EXPORT_SYMBOL_GPL(acomp_walk_next_dst);
 
 int acomp_walk_virt(struct acomp_walk *__restrict walk,
-                   struct acomp_req *__restrict req)
+                   struct acomp_req *__restrict req, bool atomic)
 {
        struct scatterlist *src = req->src;
        struct scatterlist *dst = req->dst;
@@ -548,7 +548,7 @@ int acomp_walk_virt(struct acomp_walk *__restrict walk,
                return -EINVAL;
 
        walk->flags = 0;
-       if ((req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP))
+       if ((req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) && !atomic)
                walk->flags |= ACOMP_WALK_SLEEP;
        if ((req->base.flags & CRYPTO_ACOMP_REQ_SRC_VIRT))
                walk->flags |= ACOMP_WALK_SRC_LINEAR;
index 57d7af4dfdfbcf217b4f0e7fa6566cf5f093d4c5..0d2b64d96d6ea23409272d72a7f974229a2ab86a 100644 (file)
@@ -60,7 +60,7 @@ static int deflate_compress_one(struct acomp_req *req,
        struct acomp_walk walk;
        int ret;
 
-       ret = acomp_walk_virt(&walk, req);
+       ret = acomp_walk_virt(&walk, req, true);
        if (ret)
                return ret;
 
@@ -140,7 +140,7 @@ static int deflate_decompress_one(struct acomp_req *req,
        struct acomp_walk walk;
        int ret;
 
-       ret = acomp_walk_virt(&walk, req);
+       ret = acomp_walk_virt(&walk, req, true);
        if (ret)
                return ret;
 
index 0f3ad65be2d9fea91b60ec0baf631c1603a19b99..7eda3261902444180fdafc3a7a35d9da73784318 100644 (file)
@@ -208,7 +208,7 @@ void acomp_walk_done_dst(struct acomp_walk *walk, int used);
 int acomp_walk_next_src(struct acomp_walk *walk);
 int acomp_walk_next_dst(struct acomp_walk *walk);
 int acomp_walk_virt(struct acomp_walk *__restrict walk,
-                   struct acomp_req *__restrict req);
+                   struct acomp_req *__restrict req, bool atomic);
 
 static inline bool acomp_walk_more_src(const struct acomp_walk *walk, int cur)
 {