Message ID | 20240222081135.173040-3-21cnbao@gmail.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | zswap: remove the memcpy if acomp is not sleepable | expand |
Acked-by: Chris Li <chrisl@kernel.org> Chris On Thu, Feb 22, 2024 at 12:12 AM Barry Song <21cnbao@gmail.com> wrote: > > From: Barry Song <v-songbaohua@oppo.com> > > Most compressors are actually CPU-based and won't sleep during > compression and decompression. We should remove the redundant > memcpy for them. > This patch checks if the algorithm is sleepable by testing the > CRYPTO_ALG_ASYNC algorithm flag. > Generally speaking, async and sleepable are semantically similar > but not equal. But for compress drivers, they are basically equal > at least due to the below facts. > Firstly, scompress drivers - crypto/deflate.c, lz4.c, zstd.c, > lzo.c etc have no sleep. Secondly, zRAM has been using these > scompress drivers for years in atomic contexts, and never > worried those drivers going to sleep. > One exception is that an async driver can sometimes still return > synchronously per Herbert's clarification. In this case, we are > still having a redundant memcpy. But we can't know if one > particular acomp request will sleep or not unless crypto can > expose more details for each specific request from offload > drivers. > > Signed-off-by: Barry Song <v-songbaohua@oppo.com> > Tested-by: Chengming Zhou <zhouchengming@bytedance.com> > Reviewed-by: Nhat Pham <nphamcs@gmail.com> > Acked-by: Yosry Ahmed <yosryahmed@google.com> > Reviewed-by: Chengming Zhou <zhouchengming@bytedance.com> > --- > mm/zswap.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > > diff --git a/mm/zswap.c b/mm/zswap.c > index 011e068eb355..de3c9e30bed7 100644 > --- a/mm/zswap.c > +++ b/mm/zswap.c > @@ -162,6 +162,7 @@ struct crypto_acomp_ctx { > struct crypto_wait wait; > u8 *buffer; > struct mutex mutex; > + bool is_sleepable; > }; > > /* > @@ -950,6 +951,7 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node) > goto acomp_fail; > } > acomp_ctx->acomp = acomp; > + acomp_ctx->is_sleepable = acomp_is_async(acomp); > > req = acomp_request_alloc(acomp_ctx->acomp); > if (!req) { > @@ -1077,7 +1079,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page) > mutex_lock(&acomp_ctx->mutex); > > src = zpool_map_handle(zpool, entry->handle, ZPOOL_MM_RO); > - if (!zpool_can_sleep_mapped(zpool)) { > + if (acomp_ctx->is_sleepable && !zpool_can_sleep_mapped(zpool)) { > memcpy(acomp_ctx->buffer, src, entry->length); > src = acomp_ctx->buffer; > zpool_unmap_handle(zpool, entry->handle); > @@ -1091,7 +1093,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page) > BUG_ON(acomp_ctx->req->dlen != PAGE_SIZE); > mutex_unlock(&acomp_ctx->mutex); > > - if (zpool_can_sleep_mapped(zpool)) > + if (!acomp_ctx->is_sleepable || zpool_can_sleep_mapped(zpool)) > zpool_unmap_handle(zpool, entry->handle); > } > > -- > 2.34.1 >
diff --git a/mm/zswap.c b/mm/zswap.c index 011e068eb355..de3c9e30bed7 100644 --- a/mm/zswap.c +++ b/mm/zswap.c @@ -162,6 +162,7 @@ struct crypto_acomp_ctx { struct crypto_wait wait; u8 *buffer; struct mutex mutex; + bool is_sleepable; }; /* @@ -950,6 +951,7 @@ static int zswap_cpu_comp_prepare(unsigned int cpu, struct hlist_node *node) goto acomp_fail; } acomp_ctx->acomp = acomp; + acomp_ctx->is_sleepable = acomp_is_async(acomp); req = acomp_request_alloc(acomp_ctx->acomp); if (!req) { @@ -1077,7 +1079,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page) mutex_lock(&acomp_ctx->mutex); src = zpool_map_handle(zpool, entry->handle, ZPOOL_MM_RO); - if (!zpool_can_sleep_mapped(zpool)) { + if (acomp_ctx->is_sleepable && !zpool_can_sleep_mapped(zpool)) { memcpy(acomp_ctx->buffer, src, entry->length); src = acomp_ctx->buffer; zpool_unmap_handle(zpool, entry->handle); @@ -1091,7 +1093,7 @@ static void zswap_decompress(struct zswap_entry *entry, struct page *page) BUG_ON(acomp_ctx->req->dlen != PAGE_SIZE); mutex_unlock(&acomp_ctx->mutex); - if (zpool_can_sleep_mapped(zpool)) + if (!acomp_ctx->is_sleepable || zpool_can_sleep_mapped(zpool)) zpool_unmap_handle(zpool, entry->handle); }