@@ -319,9 +319,14 @@ void zcomp_compress_end(struct zcomp *comp, struct zcomp_strm *zstrm)
zcomp_strm_release(comp, zstrm);
}
-/* Never return NULL, may sleep */
+/* May return NULL, may sleep */
struct zcomp_strm *zcomp_decompress_begin(struct zcomp *comp)
{
+ struct crypto_comp *tfm = comp->tfm_noctx;
+
+ if (tfm && crypto_tfm_may_share(crypto_comp_tfm(tfm)))
+ return NULL;
+
return zcomp_strm_find(comp);
}
@@ -345,12 +350,18 @@ int zcomp_decompress(struct zcomp *comp, struct zcomp_strm *zstrm,
unsigned int src_len, unsigned char *dst)
{
unsigned int size = PAGE_SIZE;
+ struct crypto_comp *tfm = comp->tfm_noctx;
+
+ if (tfm && crypto_tfm_may_share(crypto_comp_tfm(tfm)))
+ return crypto_comp_decompress(tfm, src, src_len, dst, &size);
- return crypto_comp_decompress(zstrm->tfm, src, src_len, dst, &size);
+ return crypto_comp_decompress(zstrm->tfm, src, src_len, dst, &size);
}
void zcomp_destroy(struct zcomp *comp)
{
+ if (comp->tfm_noctx)
+ crypto_free_comp(comp->tfm_noctx);
comp->destroy(comp);
kfree(comp);
}
@@ -367,6 +378,7 @@ struct zcomp *zcomp_create(const char *compress, int max_strm)
{
struct zcomp *comp;
const char *backend;
+ struct crypto_comp *tfm;
int error;
backend = find_backend(compress);
@@ -386,5 +398,16 @@ struct zcomp *zcomp_create(const char *compress, int max_strm)
kfree(comp);
return ERR_PTR(error);
}
+
+ /*
+ * Prepare to use crypto decompress_noctx API. One tfm is required
+ * to initialize crypto algorithm properly and fetch corresponding
+ * function pointer. But, it is sharable for multiple concurrent
+ * decompress users.
+ */
+ tfm = crypto_alloc_comp(compress, 0, 0);
+ if (!IS_ERR(tfm))
+ comp->tfm_noctx = tfm;
+
return comp;
}
@@ -26,6 +26,7 @@ struct zcomp_strm {
/* dynamic per-device compression frontend */
struct zcomp {
void *stream;
+ struct crypto_comp *tfm_noctx;
const char *backend;
struct zcomp_strm *(*strm_find)(struct zcomp *comp);