From patchwork Fri Feb 2 14:15:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maurizio Lombardi X-Patchwork-Id: 10196881 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 7C62F60362 for ; Fri, 2 Feb 2018 14:15:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6A1EC28E6E for ; Fri, 2 Feb 2018 14:15:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 5A97228E71; Fri, 2 Feb 2018 14:15:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DDA1C28E6E for ; Fri, 2 Feb 2018 14:15:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751626AbeBBOP5 (ORCPT ); Fri, 2 Feb 2018 09:15:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38852 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751469AbeBBOP5 (ORCPT ); Fri, 2 Feb 2018 09:15:57 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id EA88EA0C3D; Fri, 2 Feb 2018 14:15:56 +0000 (UTC) Received: from manaslu.brq.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id A56296D002; Fri, 2 Feb 2018 14:15:55 +0000 (UTC) From: Maurizio Lombardi To: nab@linux-iscsi.org Cc: target-devel@vger.kernel.org, mchristi@redhat.com Subject: [PATCH] target: move the rx hdr buffer out of the stack Date: Fri, 2 Feb 2018 15:15:54 +0100 Message-Id: <1517580954-3329-1-git-send-email-mlombard@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 02 Feb 2018 14:15:57 +0000 (UTC) Sender: target-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When HeaderDigest is enabled on aarch64 machines target triggers a lot of failed crc checksum errors: example of output in dmesg: [ 154.495031] HeaderDigest CRC32C failed, received 0x60571c8d, computed 0x288c3ab9 [ 154.583821] Got unknown iSCSI OpCode: 0xff [ 162.979857] HeaderDigest CRC32C failed, received 0x0712e57c, computed 0x288c3ab9 ... The problem is that the iscsit_get_rx_pdu() function uses a stack buffer as input for the scatterlist crypto library. This should be avoided on kernels >= 4.9 because stack buffers may not be directly mappable to struct page when the CONFIG_VMAP_STACK option is enabled. This patch modifies the code so the buffer will be allocated on the heap and adds a pointer to it in the iscsi_conn structure. Signed-off-by: Maurizio Lombardi --- drivers/target/iscsi/iscsi_target.c | 4 +++- drivers/target/iscsi/iscsi_target_login.c | 28 +++++++++++++++++++++------- include/target/iscsi/iscsi_target_core.h | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 9eb10d3..a3feb9e 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -3937,10 +3937,12 @@ static bool iscsi_target_check_conn_state(struct iscsi_conn *conn) static void iscsit_get_rx_pdu(struct iscsi_conn *conn) { int ret; - u8 buffer[ISCSI_HDR_LEN], opcode; + u8 *buffer, opcode; u32 checksum = 0, digest = 0; struct kvec iov; + buffer = conn->conn_rx_buf; + while (!kthread_should_stop()) { /* * Ensure that both TX and RX per connection kthreads diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c index 64c5a57..11aadeb 100644 --- a/drivers/target/iscsi/iscsi_target_login.c +++ b/drivers/target/iscsi/iscsi_target_login.c @@ -129,28 +129,41 @@ int iscsi_login_setup_crypto(struct iscsi_conn *conn) tfm = crypto_alloc_ahash("crc32c", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(tfm)) { pr_err("crypto_alloc_ahash() failed\n"); - return -ENOMEM; + goto err_exit; + } + + conn->conn_rx_buf = kmalloc(ISCSI_HDR_LEN, GFP_KERNEL); + if (!conn->conn_rx_buf) { + pr_err("kmalloc() failed for conn_rx_buf\n"); + goto err_free_ahash; } conn->conn_rx_hash = ahash_request_alloc(tfm, GFP_KERNEL); if (!conn->conn_rx_hash) { pr_err("ahash_request_alloc() failed for conn_rx_hash\n"); - crypto_free_ahash(tfm); - return -ENOMEM; + goto err_free_rxbuf; } ahash_request_set_callback(conn->conn_rx_hash, 0, NULL, NULL); conn->conn_tx_hash = ahash_request_alloc(tfm, GFP_KERNEL); if (!conn->conn_tx_hash) { pr_err("ahash_request_alloc() failed for conn_tx_hash\n"); - ahash_request_free(conn->conn_rx_hash); - conn->conn_rx_hash = NULL; - crypto_free_ahash(tfm); - return -ENOMEM; + goto err_free_ahash_req; } ahash_request_set_callback(conn->conn_tx_hash, 0, NULL, NULL); return 0; + +err_free_ahash_req: + ahash_request_free(conn->conn_rx_hash); + conn->conn_rx_hash = NULL; +err_free_rxbuf: + kfree(conn->conn_rx_buf); + conn->conn_rx_buf = NULL; +err_free_ahash: + crypto_free_ahash(tfm); +err_exit: + return -ENOMEM; } static int iscsi_login_check_initiator_version( @@ -1202,6 +1215,7 @@ void iscsi_target_login_sess_out(struct iscsi_conn *conn, ahash_request_free(conn->conn_rx_hash); crypto_free_ahash(tfm); } + kfree(conn->conn_rx_buf); free_cpumask_var(conn->conn_cpumask); diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index cf5f3ff..70ecbb7 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -584,6 +584,7 @@ struct iscsi_conn { /* libcrypto RX and TX contexts for crc32c */ struct ahash_request *conn_rx_hash; struct ahash_request *conn_tx_hash; + u8 *conn_rx_buf; /* Used for scheduling TX and RX connection kthreads */ cpumask_var_t conn_cpumask; unsigned int conn_rx_reset_cpumask:1;