Skip to content

Commit 41bd3d3

Browse files
committed
acomp-dpusm: add initial implementation
Add initial implementation of acomp-dpusm plug-in. Signed-off-by: Giovanni Cabiddu <[email protected]>
1 parent a4c90dd commit 41bd3d3

File tree

4 files changed

+542
-0
lines changed

4 files changed

+542
-0
lines changed

Makefile

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# SPDX-License-Identifier: GPL-2.0-only
2+
# Copyright (C) 2025 Intel Corporation
3+
# These contents may have been developed with support from one or more
4+
# Intel-operated generative artificial intelligence solutions.
5+
6+
# Define the kernel source directory
7+
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
8+
9+
# Define the module name
10+
MODULE_NAME := acomp-dpusm
11+
12+
# Define the home path for the DPUSM and ZFS source directories
13+
HOME_PATH ?= /devel/zfs
14+
15+
# Define the include paths for DPUSM
16+
DPUSM_INCLUDE := $(HOME_PATH)/dpusm/include
17+
18+
# Define the include paths for ZFS
19+
ZFS_INCLUDE := $(HOME_PATH)/zfs/include
20+
21+
# Define the source files for the module
22+
SRC_FILES := provider.c compress.c
23+
24+
# Define the object files for the module
25+
OBJ_FILES := $(SRC_FILES:.c=.o)
26+
27+
# Define the location of the module symvers file for DPUSM
28+
KBUILD_EXTRA_SYMBOLS := $(HOME_PATH)/dpusm/Module.symvers
29+
30+
ifneq ($(KERNELRELEASE),)
31+
ccflags-y := -I$(DPUSM_INCLUDE) -I$(ZFS_INCLUDE)
32+
obj-m := $(MODULE_NAME).o
33+
$(MODULE_NAME)-y := $(OBJ_FILES)
34+
else
35+
PWD := $(shell pwd)
36+
37+
default:
38+
$(MAKE) -C $(KERNELDIR) M=$(PWD) C=2 W=1 modules
39+
40+
clean:
41+
$(MAKE) -C $(KERNELDIR) M=$(PWD) clean
42+
endif
43+
44+
.PHONY: clean

compress.c

Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (C) 2025 Intel Corporation
4+
* These contents may have been developed with support from one or more
5+
* Intel-operated generative artificial intelligence solutions.
6+
*/
7+
#include "compress.h"
8+
9+
#include <crypto/acompress.h>
10+
#include <linux/completion.h>
11+
#include <linux/pagemap.h>
12+
#include <linux/scatterlist.h>
13+
#include <linux/slab.h>
14+
#include <linux/types.h>
15+
#include <linux/vmalloc.h>
16+
17+
static struct crypto_acomp *acomp_tfm;
18+
static bool acomp_init_done;
19+
20+
int acomp_init(int *dev_count)
21+
{
22+
acomp_tfm = crypto_alloc_acomp("zlib-deflate", 0, 0);
23+
if (IS_ERR(acomp_tfm)) {
24+
pr_err("Failed to allocate zlib-deflate acomp transform\n");
25+
return PTR_ERR(acomp_tfm);
26+
}
27+
28+
acomp_init_done = true;
29+
if (dev_count)
30+
*dev_count = 1;
31+
32+
return 0;
33+
}
34+
35+
void acomp_exit(void)
36+
{
37+
if (!acomp_init_done)
38+
return;
39+
40+
if (acomp_tfm) {
41+
crypto_free_acomp(acomp_tfm);
42+
acomp_tfm = NULL;
43+
}
44+
acomp_init_done = false;
45+
}
46+
47+
enum comp_dir {
48+
DECOMPRESS = 0,
49+
COMPRESS = 1,
50+
};
51+
52+
static int acomp_comp_decomp_sg(enum comp_dir dir, struct scatterlist *src, int src_len,
53+
struct scatterlist *dst, int dst_len, size_t *c_len)
54+
{
55+
struct crypto_wait wait;
56+
struct acomp_req *req;
57+
int ret;
58+
59+
pr_debug("[%s] dir: %s, src_len: %d, dst_len: %d\n", __func__,
60+
dir == COMPRESS ? "COMPRESS" : "DECOMPRESS", src_len, dst_len);
61+
62+
req = acomp_request_alloc(acomp_tfm);
63+
if (!req) {
64+
pr_err("Failed to allocate acomp request\n");
65+
return -ENOMEM;
66+
}
67+
68+
crypto_init_wait(&wait);
69+
acomp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
70+
crypto_req_done, &wait);
71+
72+
acomp_request_set_params(req, src, dst, src_len, dst_len);
73+
74+
if (dir == COMPRESS)
75+
ret = crypto_acomp_compress(req);
76+
else
77+
ret = crypto_acomp_decompress(req);
78+
79+
ret = crypto_wait_req(ret, &wait);
80+
if (ret)
81+
goto out;
82+
83+
*c_len = req->dlen;
84+
85+
out:
86+
acomp_request_free(req);
87+
pr_debug("[%s] ret: %d, dlen=%zu\n", __func__, ret, *c_len);
88+
89+
return ret;
90+
}
91+
92+
static int vmalloc_to_sg(const void *vmem, size_t size, struct scatterlist *sgl, int nents)
93+
{
94+
unsigned long vaddr = (unsigned long)vmem;
95+
unsigned long offset;
96+
size_t remaining = size;
97+
struct page *page;
98+
int sg_count = 0;
99+
100+
sg_init_table(sgl, nents);
101+
102+
while (remaining > 0) {
103+
page = vmalloc_to_page((void *)vaddr);
104+
if (!page) {
105+
pr_err("Failed to retrieve page for vaddr: 0x%lx\n", vaddr);
106+
return -EINVAL;
107+
}
108+
109+
offset = vaddr & (PAGE_SIZE - 1);
110+
size_t len = min((size_t)(PAGE_SIZE - offset), remaining);
111+
112+
sg_set_page(&sgl[sg_count], page, len, offset);
113+
114+
vaddr += len;
115+
remaining -= len;
116+
sg_count++;
117+
118+
if (sg_count >= nents && remaining > 0) {
119+
pr_err("Not enough scatterlist entries for memory size: %zu\n", size);
120+
return -ENOMEM;
121+
}
122+
}
123+
124+
sg_mark_end(&sgl[sg_count - 1]);
125+
126+
return 0;
127+
}
128+
129+
static int count_pages(const void *vmem, size_t size)
130+
{
131+
unsigned long vaddr = (unsigned long)vmem;
132+
size_t remaining = size;
133+
int page_count = 0;
134+
135+
while (remaining > 0) {
136+
size_t len = min((size_t)(PAGE_SIZE - (vaddr & (PAGE_SIZE - 1))), remaining);
137+
138+
vaddr += len;
139+
remaining -= len;
140+
page_count++;
141+
}
142+
143+
return page_count;
144+
}
145+
146+
static int alloc_scatterlist(const void *vmem, size_t size, struct scatterlist **sgl)
147+
{
148+
struct scatterlist *sg = NULL;
149+
int ret = 0;
150+
int pages;
151+
152+
if (!is_vmalloc_addr(vmem)) {
153+
sg = kmalloc(sizeof(*sg), GFP_KERNEL);
154+
if (!sg) {
155+
*sgl = NULL;
156+
return -ENOMEM;
157+
}
158+
159+
sg_init_one(sg, vmem, size);
160+
161+
*sgl = sg;
162+
return 0;
163+
}
164+
165+
pages = count_pages(vmem, size);
166+
if (pages <= 0) {
167+
pr_err("Failed to count pages for memory\n");
168+
return -EINVAL;
169+
}
170+
171+
sg = kmalloc_array(pages, sizeof(struct scatterlist), GFP_KERNEL);
172+
if (!sg)
173+
return -ENOMEM;
174+
175+
memset(sg, 0, sizeof(struct scatterlist) * pages);
176+
177+
ret = vmalloc_to_sg(vmem, size, sg, pages);
178+
if (ret) {
179+
pr_err("Failed to map vmalloc memory to scatterlist\n");
180+
kfree(sg);
181+
*sgl = NULL;
182+
return ret;
183+
}
184+
185+
*sgl = sg;
186+
return ret;
187+
}
188+
189+
static int acomp_comp_decomp(enum comp_dir dir, void *src, int src_len,
190+
void *dst, int dst_len, size_t *c_len)
191+
{
192+
struct scatterlist *src_sg, *dst_sg;
193+
int ret;
194+
195+
ret = alloc_scatterlist(src, src_len, &src_sg);
196+
if (ret) {
197+
pr_err("Failed to allocate scatterlist for SRC memory\n");
198+
return ret;
199+
}
200+
201+
ret = alloc_scatterlist(dst, dst_len, &dst_sg);
202+
if (ret) {
203+
pr_err("Failed to allocate scatterlist for DST memory\n");
204+
kfree(src_sg);
205+
return ret;
206+
}
207+
208+
ret = acomp_comp_decomp_sg(dir, src_sg, src_len, dst_sg, dst_len, c_len);
209+
210+
kfree(src_sg);
211+
kfree(dst_sg);
212+
213+
return ret;
214+
}
215+
216+
int acomp_compress(void *src, int src_len, void *dst, int dst_len, size_t *c_len)
217+
{
218+
return acomp_comp_decomp(COMPRESS, src, src_len, dst, dst_len, c_len);
219+
}
220+
221+
int acomp_decompress(void *src, int src_len, void *dst, int dst_len, size_t *c_len)
222+
{
223+
return acomp_comp_decomp(DECOMPRESS, src, src_len, dst, dst_len, c_len);
224+
}

compress.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2025 Intel Corporation
4+
* These contents may have been developed with support from one or more
5+
* Intel-operated generative artificial intelligence solutions.
6+
*/
7+
#ifndef _ACOMP_COMPRESS_H
8+
#define _ACOMP_COMPRESS_H
9+
10+
#include <linux/types.h>
11+
12+
int acomp_init(int *dev_count);
13+
void acomp_exit(void);
14+
int acomp_compress(void *src, int src_len, void *dst, int dst_len, size_t *c_len);
15+
int acomp_decompress(void *src, int src_len, void *dst, int dst_len, size_t *c_len);
16+
17+
#endif /* _ACOMP_COMPRESS_H */

0 commit comments

Comments
 (0)