Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp4230942ybb; Tue, 7 Apr 2020 03:27:26 -0700 (PDT) X-Google-Smtp-Source: APiQypIdz429+O6whuv8ZOGHaKTElvpFrCyD3RmcKSxYBVMttpT1hzkeCWcJhRqchB1WWVNSsOyx X-Received: by 2002:a9d:69d8:: with SMTP id v24mr955942oto.148.1586255246500; Tue, 07 Apr 2020 03:27:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1586255246; cv=none; d=google.com; s=arc-20160816; b=VyM5T+1+bE5eSmv9CZOT/jHYPKmsYrKBdxzPROQ04jtdFAPspjcW5l6NCbodVmCO4o Z+nhFDaxLJj28sXMaNQIiEc/+18guCs/DM9w6OTXlTzjxW2fNw4P+n6Er4uc3WUADRzZ OB+gw272YAtLWtd92AsJ477XLnKit//fCIV714V/cQBkVpcxpPc2uZ2DILeI5dcf/UJu E7xZZ1nuzSGNulcF9SJeo1V58Nysefg/nloml/J1mFIqYtyxJp1hp2jVvSrg6dTnPt/+ eVEGwVOXyKRkNcaUZDdPX7En+pYIWLSHPEia4SUukpO/D9mTgK/E9lO4foa8KCUfTYnG qaQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=C9v+HjVieGBUR3eFW9eSJsuL48O3YykC35tpLeDBono=; b=WLLAiTMaBiS0INAIgjreyFv88Vo1CiB2TSET8lO6xy4rlkX2RxuPzN+Xok12M3jokd avxvI+kcOpnVRWv8hPSMDjkQEmx8na9Ezn0rROff+FrR585Llxg2h5OXIhx1fCui4eFP PwCIL6gl3Z87TOtZJq/zwi1YhPyhv9pujgMgHi+CekW9CAPP5tT5Hx3bJITOwRs5J+hy VgzuD6mAC2mfM4TVKB7IKJPOb6ANOuQLmLmJLybTLNUOUCZ8g031F8ghk1KYA+dQT3cU 8ngOC595p5lCk7I7w98NA5dMJtzorD2OwtDN3FBtLR5oSUlG9wSb6LQeH2sNyNNP/Vk/ fmBg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=aacAbNXJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l19si1003721otp.119.2020.04.07.03.27.14; Tue, 07 Apr 2020 03:27:26 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=aacAbNXJ; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728998AbgDGKZi (ORCPT + 99 others); Tue, 7 Apr 2020 06:25:38 -0400 Received: from mail.kernel.org ([198.145.29.99]:36296 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728992AbgDGKZi (ORCPT ); Tue, 7 Apr 2020 06:25:38 -0400 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id AB5AA20644; Tue, 7 Apr 2020 10:25:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1586255137; bh=Wh7+AJAc0sRg46fVl7Ybp0b9uAqplY9N7kq8TJFnsXM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aacAbNXJDMifQ1yWwkgoyZ4fjcyzvXsNOhJzm93TDz0gRxTvvyuJ+XTlFS5XqyMAH 53qdDrLQ87POrgl1JmtjYIELAp7nkzV+pYyLvcbRrmZvnPZ9eHnwRCD1LZ0bfbjHEm iBIJ6xCbxN/PFaRvQbZeUpHlHNZPA/mz+u1VQUfA= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Ursula Braun , Karsten Graul , "David S. Miller" Subject: [PATCH 5.5 45/46] net/smc: fix cleanup for linkgroup setup failures Date: Tue, 7 Apr 2020 12:22:16 +0200 Message-Id: <20200407101504.120133480@linuxfoundation.org> X-Mailer: git-send-email 2.26.0 In-Reply-To: <20200407101459.502593074@linuxfoundation.org> References: <20200407101459.502593074@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Ursula Braun commit 51e3dfa8906ace90c809235b3d3afebc166b6433 upstream. If an SMC connection to a certain peer is setup the first time, a new linkgroup is created. In case of setup failures, such a linkgroup is unusable and should disappear. As a first step the linkgroup is removed from the linkgroup list in smc_lgr_forget(). There are 2 problems: smc_listen_decline() might be called before linkgroup creation resulting in a crash due to calling smc_lgr_forget() with parameter NULL. If a setup failure occurs after linkgroup creation, the connection is never unregistered from the linkgroup, preventing linkgroup freeing. This patch introduces an enhanced smc_lgr_cleanup_early() function which * contains a linkgroup check for early smc_listen_decline() invocations * invokes smc_conn_free() to guarantee unregistering of the connection. * schedules fast linkgroup removal of the unusable linkgroup And the unused function smcd_conn_free() is removed from smc_core.h. Fixes: 3b2dec2603d5b ("net/smc: restructure client and server code in af_smc") Fixes: 2a0674fffb6bc ("net/smc: improve abnormal termination of link groups") Signed-off-by: Ursula Braun Signed-off-by: Karsten Graul Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- net/smc/af_smc.c | 25 +++++++++++++++---------- net/smc/smc_core.c | 12 ++++++++++++ net/smc/smc_core.h | 2 +- 3 files changed, 28 insertions(+), 11 deletions(-) --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c @@ -512,15 +512,18 @@ static int smc_connect_decline_fallback( static int smc_connect_abort(struct smc_sock *smc, int reason_code, int local_contact) { + bool is_smcd = smc->conn.lgr->is_smcd; + if (local_contact == SMC_FIRST_CONTACT) - smc_lgr_forget(smc->conn.lgr); - if (smc->conn.lgr->is_smcd) + smc_lgr_cleanup_early(&smc->conn); + else + smc_conn_free(&smc->conn); + if (is_smcd) /* there is only one lgr role for SMC-D; use server lock */ mutex_unlock(&smc_server_lgr_pending); else mutex_unlock(&smc_client_lgr_pending); - smc_conn_free(&smc->conn); smc->connect_nonblock = 0; return reason_code; } @@ -1091,7 +1094,6 @@ static void smc_listen_out_err(struct sm if (newsmcsk->sk_state == SMC_INIT) sock_put(&new_smc->sk); /* passive closing */ newsmcsk->sk_state = SMC_CLOSED; - smc_conn_free(&new_smc->conn); smc_listen_out(new_smc); } @@ -1102,12 +1104,13 @@ static void smc_listen_decline(struct sm { /* RDMA setup failed, switch back to TCP */ if (local_contact == SMC_FIRST_CONTACT) - smc_lgr_forget(new_smc->conn.lgr); + smc_lgr_cleanup_early(&new_smc->conn); + else + smc_conn_free(&new_smc->conn); if (reason_code < 0) { /* error, no fallback possible */ smc_listen_out_err(new_smc); return; } - smc_conn_free(&new_smc->conn); smc_switch_to_fallback(new_smc); new_smc->fallback_rsn = reason_code; if (reason_code && reason_code != SMC_CLC_DECL_PEERDECL) { @@ -1170,16 +1173,18 @@ static int smc_listen_ism_init(struct sm new_smc->conn.lgr->vlan_id, new_smc->conn.lgr->smcd)) { if (ini->cln_first_contact == SMC_FIRST_CONTACT) - smc_lgr_forget(new_smc->conn.lgr); - smc_conn_free(&new_smc->conn); + smc_lgr_cleanup_early(&new_smc->conn); + else + smc_conn_free(&new_smc->conn); return SMC_CLC_DECL_SMCDNOTALK; } /* Create send and receive buffers */ if (smc_buf_create(new_smc, true)) { if (ini->cln_first_contact == SMC_FIRST_CONTACT) - smc_lgr_forget(new_smc->conn.lgr); - smc_conn_free(&new_smc->conn); + smc_lgr_cleanup_early(&new_smc->conn); + else + smc_conn_free(&new_smc->conn); return SMC_CLC_DECL_MEM; } --- a/net/smc/smc_core.c +++ b/net/smc/smc_core.c @@ -162,6 +162,18 @@ static void smc_lgr_unregister_conn(stru conn->lgr = NULL; } +void smc_lgr_cleanup_early(struct smc_connection *conn) +{ + struct smc_link_group *lgr = conn->lgr; + + if (!lgr) + return; + + smc_conn_free(conn); + smc_lgr_forget(lgr); + smc_lgr_schedule_free_work_fast(lgr); +} + /* Send delete link, either as client to request the initiation * of the DELETE LINK sequence from server; or as server to * initiate the delete processing. See smc_llc_rx_delete_link(). --- a/net/smc/smc_core.h +++ b/net/smc/smc_core.h @@ -296,6 +296,7 @@ struct smc_clc_msg_accept_confirm; struct smc_clc_msg_local; void smc_lgr_forget(struct smc_link_group *lgr); +void smc_lgr_cleanup_early(struct smc_connection *conn); void smc_lgr_terminate(struct smc_link_group *lgr, bool soft); void smc_port_terminate(struct smc_ib_device *smcibdev, u8 ibport); void smc_smcd_terminate(struct smcd_dev *dev, u64 peer_gid, @@ -316,7 +317,6 @@ int smc_vlan_by_tcpsk(struct socket *clc void smc_conn_free(struct smc_connection *conn); int smc_conn_create(struct smc_sock *smc, struct smc_init_info *ini); -void smcd_conn_free(struct smc_connection *conn); void smc_lgr_schedule_free_work_fast(struct smc_link_group *lgr); int smc_core_init(void); void smc_core_exit(void);