diff --git a/crypto/benchmark/Makefile b/crypto/benchmark/Makefile
index 5244178e14c4..f638535442ba 100644
--- a/crypto/benchmark/Makefile
+++ b/crypto/benchmark/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_CRYPTO_BENCHMARK) += crypto_benchmark.o
-crypto_benchmark-objs += benchmark.o
+crypto_benchmark-objs += benchmark.o bm_comp.o
diff --git a/crypto/benchmark/benchmark.c b/crypto/benchmark/benchmark.c
index 9a833b277d87..b5dcf5829b22 100644
--- a/crypto/benchmark/benchmark.c
+++ b/crypto/benchmark/benchmark.c
@@ -11,6 +11,7 @@
 #include <linux/wait.h>

 #include "benchmark.h"
+#include "bm_comp.h"

 enum crypto_bm_status {
 	CRYPTO_BM_STOP,
@@ -18,6 +19,7 @@ enum crypto_bm_status {
 };

 enum crypto_bm_alg {
+	CRYPTO_BM_COMP,
 	CRYPTO_BM_ALG_MAX,
 };

@@ -65,6 +67,15 @@ static struct task_struct *test_thread;

 static struct crypto_bm_alg_ops benchmark_ops[] = {
 	{
+		.alg		= "CRYPTO_COMPRESS",
+		.init		= crypto_bm_init_comp,
+		.uninit		= crypto_bm_uninit_comp,
+		.create_tfm	= crypto_bm_create_tfm_comp,
+		.release_tfm	= crypto_bm_release_tfm_comp,
+		.create_req	= crypto_bm_create_req_comp,
+		.release_req	= crypto_bm_release_req_comp,
+		.perf		= crypto_bm_perf_comp,
+	}, {
 		/* sentinel */
 	}
 };
diff --git a/crypto/benchmark/bm_comp.c b/crypto/benchmark/bm_comp.c
new file mode 100644
index 000000000000..2772a8e86e2e
--- /dev/null
+++ b/crypto/benchmark/bm_comp.c
@@ -0,0 +1,425 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 HiSilicon Limited.
+ */
+#include <linux/scatterlist.h>
+#include <crypto/acompress.h>
+
+#include "benchmark.h"
+#include "bm_comp.h"
+
+#define COMP_BUF_SIZE		1024
+#define REQ_NUM			1024
+#define DATAPERREQ		4
+
+enum crypto_bm_comp_optype {
+	CRYPTO_BM_COMPRESS,
+	CRYPTO_BM_DECOMPRESS,
+	CRYPTO_BM_OPS_MAX,
+};
+
+struct crypto_bm_comp_buffer {
+	void *input;
+	void *output;
+	struct scatterlist *src;
+	struct scatterlist *dst;
+};
+
+struct crypto_bm_comp_cb_data {
+	atomic_t is_used;
+	struct crypto_bm_thread_data *tdata;
+};
+
+struct crypto_bm_comp_data {
+	u32 input_size;
+	u32 output_size;
+	u32 last_used;
+	struct crypto_bm_comp_buffer *buffers;
+	struct crypto_bm_comp_cb_data *cb_datas;
+};
+
+struct crypto_bm_comp_testvec {
+	int inlen;
+	int outlen;
+	char input[COMP_BUF_SIZE];
+	char output[COMP_BUF_SIZE];
+};
+
+struct crypto_bm_comp_test_func {
+	int (*testfun)(struct acomp_req *req);
+};
+
+static int dataperreq;
+
+static int totalreq;
+
+static struct crypto_bm_comp_data *data_array;
+
+static const struct crypto_bm_comp_testvec comp_compress_tv = {
+	.inlen	= 70,
+	.input	= "Join us now and share the software "
+		"Join us now and share the software ",
+};
+
+static const struct crypto_bm_comp_test_func testfunc[] = {
+	{
+		.testfun = crypto_acomp_compress,
+	}, {
+		.testfun = crypto_acomp_decompress,
+	}, {
+		/* sentinel */
+	}
+};
+
+static void crypto_bm_comp_cb(struct crypto_async_request *base, int err);
+
+int crypto_bm_init_comp(struct crypto_bm_base *base)
+{
+	struct crypto_bm_attrs *attrs = base->attrs;
+
+	if (attrs->optype >= CRYPTO_BM_OPS_MAX) {
+		pr_err("Optype should be 0 for compression or 1 for decompression!\n");
+		return -ENOMEM;
+	}
+
+	if (attrs->reqnum * DATAPERREQ >= REQ_NUM)
+		totalreq = attrs->reqnum * DATAPERREQ;
+	else
+		totalreq = REQ_NUM;
+
+	dataperreq = totalreq / attrs->reqnum;
+
+	data_array = kcalloc(attrs->threadnum, sizeof(*data_array), GFP_KERNEL);
+	if (!data_array)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void crypto_bm_uninit_comp(struct crypto_bm_base *base)
+{
+	kfree(data_array);
+}
+
+int crypto_bm_create_tfm_comp(struct crypto_bm_base *base, u32 idx)
+{
+	char *alg = base->attrs->algorithm;
+	int node = base->gthread[idx].node;
+	int ret = 0;
+
+	base->gthread[idx].tfm = crypto_alloc_acomp_node(alg, 0, 0, node);
+	if (IS_ERR(base->gthread[idx].tfm)) {
+		ret = PTR_ERR(base->gthread[idx].tfm);
+		pr_err("failed to alloc %dth acomp, ret = %d\n", idx, ret);
+	}
+
+	return ret;
+}
+
+void crypto_bm_release_tfm_comp(struct crypto_bm_base *base, u32 idx)
+{
+	crypto_free_acomp(base->gthread[idx].tfm);
+}
+
+static void crypto_bm_comp_copy_data_compress(u32 idx)
+{
+	struct crypto_bm_comp_data *data = &data_array[idx];
+	u32 block, inlen, inputsize = data->input_size;
+	void *buffer;
+	int i, j;
+
+	block = DIV_ROUND_UP(inputsize, comp_compress_tv.inlen);
+	for (i = 0; i < totalreq; i++) {
+		inlen = inputsize;
+		buffer = data->buffers[i].input;
+		for (j = 0; j < block; j++) {
+			memcpy(buffer, comp_compress_tv.input,
+			       j == block - 1 ? inlen : comp_compress_tv.inlen);
+			buffer += comp_compress_tv.inlen;
+			inlen -= comp_compress_tv.inlen;
+		}
+	}
+}
+
+static int crypto_bm_comp_copy_data_decompress(struct crypto_bm_base *base, u32 idx)
+{
+	struct crypto_bm_comp_data *data = &data_array[idx];
+	struct crypto_acomp *acomp = base->gthread[idx].tfm;
+	struct crypto_wait wait;
+	struct acomp_req *req;
+	u32 block, inlen;
+	void *buffer;
+	int i, ret;
+
+	req = acomp_request_alloc(acomp);
+	if (!req)
+		return -ENOMEM;
+
+	inlen = data->input_size;
+	block = DIV_ROUND_UP(inlen, comp_compress_tv.inlen);
+	buffer = data->buffers[0].input;
+	for (i = 0; i < block; i++) {
+		memcpy(buffer, comp_compress_tv.input,
+		       i == block - 1 ? inlen : comp_compress_tv.inlen);
+		buffer += comp_compress_tv.inlen;
+		inlen -= comp_compress_tv.inlen;
+	}
+
+	/*
+	 * For decompression, the tool need to prepare compressed data according
+	 * to crypto_bm_attrs.inputsize. And here it is hard to make the compressed
+	 * data length equal to 'inputsize' value, so make the origin data length
+	 * equal to 'inputsize' value.
+	 */
+	crypto_init_wait(&wait);
+	acomp_request_set_callback(req, 0, crypto_req_done, &wait);
+	acomp_request_set_params(req, data->buffers[0].src, data->buffers[0].dst,
+				 data->input_size, data->output_size);
+
+	ret = crypto_wait_req(crypto_acomp_compress(req), &wait);
+	if (ret) {
+		pr_err("failed to prepare decompression data.\n");
+		goto out_free_req;
+	}
+
+	for (i = 0; i < totalreq; i++)
+		memcpy(data->buffers[i].input, data->buffers[0].output, req->dlen);
+
+out_free_req:
+	acomp_request_free(req);
+
+	return ret;
+}
+
+static int crypto_bm_comp_init_data(struct crypto_bm_base *base, u32 idx)
+{
+	struct crypto_bm_comp_data *data = &data_array[idx];
+	int i, ret, node = base->gthread[idx].node;
+	struct crypto_bm_comp_buffer *buffer;
+	u32 reqnum = base->attrs->reqnum;
+	u32 optype = base->attrs->optype;
+
+	data->input_size = base->attrs->inputsize;
+	data->output_size = base->attrs->inputsize;
+
+	data->buffers = kcalloc_node(1, sizeof(*data->buffers) * totalreq, GFP_KERNEL, node);
+	if (!data->buffers)
+		return -ENOMEM;
+
+	data->cb_datas = kcalloc_node(1, sizeof(*data->cb_datas) * reqnum, GFP_KERNEL, node);
+	if (!data->cb_datas) {
+		ret = -ENOMEM;
+		goto out_free_buffers;
+	}
+
+	for (i = 0; i < totalreq; i++) {
+		buffer = &data->buffers[i];
+		buffer->src = kcalloc_node(1, sizeof(struct scatterlist), GFP_KERNEL, node);
+		if (!buffer->src) {
+			ret = -ENOMEM;
+			goto out_free_src;
+		}
+
+		buffer->dst = kcalloc_node(1, sizeof(struct scatterlist), GFP_KERNEL, node);
+		if (!buffer->dst) {
+			ret = -ENOMEM;
+			goto out_free_dst;
+		}
+
+		buffer->input = kcalloc_node(1, data->input_size, GFP_KERNEL, node);
+		if (!buffer->input) {
+			ret = -ENOMEM;
+			goto out_free_input;
+		}
+
+		buffer->output = kcalloc_node(1, data->output_size, GFP_KERNEL, node);
+		if (!buffer->output) {
+			ret = -ENOMEM;
+			goto out_free_output;
+		}
+
+		sg_init_one(buffer->src, buffer->input, data->input_size);
+		sg_init_one(buffer->dst, buffer->output, data->output_size);
+	}
+
+	if (optype == CRYPTO_BM_COMPRESS) {
+		crypto_bm_comp_copy_data_compress(idx);
+	} else {
+		ret = crypto_bm_comp_copy_data_decompress(base, idx);
+		if (ret) {
+			i--;
+			goto out_free_output;
+		}
+	}
+
+	return 0;
+
+out_free_output:
+	kfree(buffer->input);
+
+out_free_input:
+	kfree(buffer->dst);
+
+out_free_dst:
+	kfree(buffer->src);
+
+out_free_src:
+	for (i--; i >= 0; i--) {
+		buffer = &data->buffers[i];
+		kfree(buffer->src);
+		kfree(buffer->dst);
+		kfree(buffer->input);
+		kfree(buffer->output);
+	}
+
+	kfree(data->cb_datas);
+
+out_free_buffers:
+	kfree(data->buffers);
+
+	return ret;
+}
+
+static void crypto_bm_comp_uninit_data(struct crypto_bm_base *base, u32 idx)
+{
+	struct crypto_bm_comp_data *data = &data_array[idx];
+	struct crypto_bm_comp_buffer *buffer;
+	int i;
+
+	for (i = 0; i < totalreq; i++) {
+		buffer = &data->buffers[i];
+		kfree(buffer->src);
+		kfree(buffer->dst);
+		kfree(buffer->input);
+		kfree(buffer->output);
+	}
+
+	kfree(data->cb_datas);
+	kfree(data->buffers);
+}
+
+static int crypto_bm_comp_alloc_req(struct crypto_bm_base *base, u32 idx)
+{
+	struct crypto_bm_comp_data *data = &data_array[idx];
+	int node = base->gthread[idx].node;
+	u32 reqnum = base->attrs->reqnum;
+	struct acomp_req *req;
+	int i;
+
+	base->gthread[idx].req = kcalloc_node(reqnum, sizeof(struct acomp_req *), GFP_KERNEL, node);
+	if (!base->gthread[idx].req)
+		return -ENOMEM;
+
+	for (i = 0; i < reqnum; i++) {
+		req = acomp_request_alloc(base->gthread[idx].tfm);
+		if (!req) {
+			pr_err("failed to allocate acomp request\n");
+			goto out_free_req;
+		}
+
+		acomp_request_set_callback(req, 0, crypto_bm_comp_cb, &data->cb_datas[i]);
+		base->gthread[idx].req[i] = req;
+	}
+
+	return 0;
+
+out_free_req:
+	for (i--; i >= 0; i--)
+		acomp_request_free(base->gthread[idx].req[i]);
+
+	kfree(base->gthread[idx].req);
+
+	return -EINVAL;
+}
+
+static void crypto_bm_comp_free_req(struct crypto_bm_base *base, u32 idx)
+{
+	u32 reqnum = base->attrs->reqnum;
+	int i;
+
+	for (i = 0; i < reqnum; i++)
+		acomp_request_free(base->gthread[idx].req[i]);
+}
+
+int crypto_bm_create_req_comp(struct crypto_bm_base *base, u32 idx)
+{
+	int ret;
+
+	ret = crypto_bm_comp_init_data(base, idx);
+	if (ret)
+		return ret;
+
+	ret = crypto_bm_comp_alloc_req(base, idx);
+	if (ret)
+		goto out_free_buf;
+
+	return 0;
+
+out_free_buf:
+	crypto_bm_comp_uninit_data(base, idx);
+
+	return ret;
+}
+
+void crypto_bm_release_req_comp(struct crypto_bm_base *base, u32 idx)
+{
+	crypto_bm_comp_free_req(base, idx);
+	crypto_bm_comp_uninit_data(base, idx);
+}
+
+static void crypto_bm_comp_cb(struct crypto_async_request *base, int err)
+{
+	struct crypto_bm_comp_cb_data *data = base->data;
+
+	atomic_inc(&data->tdata->count.recv_req);
+	atomic_set(&data->is_used, 0);
+}
+
+int crypto_bm_perf_comp(struct crypto_bm_thread_data *data)
+{
+	struct crypto_bm_base *base = data->base;
+	int i, j, ret, last_used, send_req = 0;
+	u32 loop = base->attrs->loop * 1000;
+	u32 reqnum = base->attrs->reqnum;
+	u32 threadid = data->threadid;
+	struct crypto_bm_comp_data *comp_data = &data_array[threadid];
+	struct crypto_bm_comp_buffer *buffer;
+	struct acomp_req *req;
+
+	for (i = 0; i < reqnum; i++)
+		comp_data->cb_datas[i].tdata = data;
+
+	for (i = 0; i < loop; i++) {
+		for (j = 0; j < reqnum; j++) {
+			if (atomic_read(&comp_data->cb_datas[j].is_used))
+				continue;
+			req = base->gthread[threadid].req[j];
+			last_used = comp_data->last_used;
+			buffer = &comp_data->buffers[last_used + j * dataperreq];
+			acomp_request_set_params(req, buffer->src, buffer->dst,
+						 comp_data->input_size, comp_data->output_size);
+			atomic_set(&comp_data->cb_datas[j].is_used, 1);
+			ret = testfunc[base->attrs->optype].testfun(req);
+			if (!ret) {
+				atomic_inc(&data->count.recv_req);
+				atomic_set(&comp_data->cb_datas[j].is_used, 0);
+			}
+			if (unlikely(ret && ret != -EINPROGRESS && ret != -EBUSY)) {
+				pr_err("failed to compress req, ret %d\n", ret);
+				atomic_set(&comp_data->cb_datas[j].is_used, 0);
+				break;
+			}
+			ret = 0;
+			comp_data->last_used = (last_used + 1) % dataperreq;
+			send_req++;
+		}
+	}
+
+	atomic_add(send_req, &data->count.send_req);
+	send_req = atomic_read(&data->count.send_req);
+
+	while (atomic_read(&data->count.recv_req) != send_req)
+		;
+
+	return ret;
+}
diff --git a/crypto/benchmark/bm_comp.h b/crypto/benchmark/bm_comp.h
new file mode 100644
index 000000000000..78b45f8b22a6
--- /dev/null
+++ b/crypto/benchmark/bm_comp.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022 HiSilicon Limited.
+ */
+#ifndef CRYPTO_BM_COMP_H
+#define CRYPTO_BM_COMP_H
+
+#include <linux/types.h>
+
+int crypto_bm_init_comp(struct crypto_bm_base *base);
+void crypto_bm_uninit_comp(struct crypto_bm_base *base);
+int crypto_bm_create_tfm_comp(struct crypto_bm_base *base, u32 idx);
+void crypto_bm_release_tfm_comp(struct crypto_bm_base *base, u32 idx);
+int crypto_bm_create_req_comp(struct crypto_bm_base *base, u32 idx);
+void crypto_bm_release_req_comp(struct crypto_bm_base *base, u32 idx);
+int crypto_bm_perf_comp(struct crypto_bm_thread_data *data);
+
+#endif
