Hi Herbert, The error can be triggered with the following test. Invoking that test in a while [ 1 ] loop shows that no memory is leaked. #include <stdio.h> #include <kcapi.h> int main(int argc, char *argv[]) { char buf[8192]; struct kcapi_handle *handle; struct iovec iov; int ret; (void)argc; (void)argv; iov.iov_base = buf; ret = kcapi_cipher_init(&handle, "ctr(aes)", 0); if (ret) return ret; ret = kcapi_cipher_setkey(handle, (unsigned char *)"0123456789abcdef", 16); if (ret) return ret; ret = kcapi_cipher_stream_init_enc(handle, (unsigned char *)"0123456789abcdef", NULL, 0); if (ret < 0) return ret; iov.iov_len = 4152; ret = kcapi_cipher_stream_update(handle, &iov, 1); if (ret < 0) return ret; iov.iov_len = 4096; ret = kcapi_cipher_stream_op(handle, &iov, 1); if (ret < 0) return ret; kcapi_cipher_destroy(handle); return 0; } ---8<--- When a page is assigned to a TX SGL, call get_page to increment the reference counter. It is possible that one page is referenced in multiple SGLs: - in the global TX SGL in case a previous af_alg_pull_tsgl only reassigned parts of a page to a per-request TX SGL - in the per-request TX SGL as assigned by af_alg_pull_tsgl Note, multiple requests can be active at the same time whose TX SGLs all point to different parts of the same page. Signed-off-by: Stephan Mueller <smueller@xxxxxxxxxx> --- crypto/af_alg.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index d6936c0e08d9..ffa9f4ccd9b4 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -641,9 +641,9 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, if (dst_offset >= plen) { /* discard page before offset */ dst_offset -= plen; - put_page(page); } else { /* reassign page to dst after offset */ + get_page(page); sg_set_page(dst + j, page, plen - dst_offset, sg[i].offset + dst_offset); @@ -661,9 +661,7 @@ void af_alg_pull_tsgl(struct sock *sk, size_t used, struct scatterlist *dst, if (sg[i].length) return; - if (!dst) - put_page(page); - + put_page(page); sg_assign_page(sg + i, NULL); } -- 2.13.4