From patchwork Wed Sep 28 17:30:49 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Dupuis, Chad" X-Patchwork-Id: 9354431 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 8748D60757 for ; Wed, 28 Sep 2016 18:15:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6FCCD2979C for ; Wed, 28 Sep 2016 18:15:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 63D802979E; Wed, 28 Sep 2016 18:15:54 +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 BBDB92979C for ; Wed, 28 Sep 2016 18:15:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752476AbcI1SPu (ORCPT ); Wed, 28 Sep 2016 14:15:50 -0400 Received: from mx0b-0016ce01.pphosted.com ([67.231.156.153]:53115 "EHLO mx0b-0016ce01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750714AbcI1SPu (ORCPT ); Wed, 28 Sep 2016 14:15:50 -0400 Received: from pps.filterd (m0085408.ppops.net [127.0.0.1]) by mx0b-0016ce01.pphosted.com (8.16.0.17/8.16.0.17) with SMTP id u8SIDPRj028588; Wed, 28 Sep 2016 11:15:38 -0700 Received: from avcashub1.qlogic.com ([198.186.0.116]) by mx0b-0016ce01.pphosted.com with ESMTP id 25nrfpk7r4-2 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Wed, 28 Sep 2016 11:15:38 -0700 Received: from dut6217.mv.qlogic.com (172.29.56.217) by qlc.com (10.1.4.191) with Microsoft SMTP Server id 14.3.235.1; Wed, 28 Sep 2016 11:15:37 -0700 Received: by dut6217.mv.qlogic.com (Postfix, from userid 0) id 0F1B45220E8; Wed, 28 Sep 2016 13:30:50 -0400 (EDT) From: Chad Dupuis To: , CC: , , Subject: [PATCH 2/2] libfc: Do not take rdata->rp_mutex when processing a -FC_EX_CLOSED ELS response. Date: Wed, 28 Sep 2016 13:30:49 -0400 Message-ID: <1475083849-13478-3-git-send-email-chad.dupuis@cavium.com> X-Mailer: git-send-email 2.7.2 In-Reply-To: <1475083849-13478-1-git-send-email-chad.dupuis@cavium.com> References: <1475083849-13478-1-git-send-email-chad.dupuis@cavium.com> MIME-Version: 1.0 disclaimer: bypass X-Proofpoint-Virus-Version: vendor=nai engine=5800 definitions=8302 signatures=670710 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 priorityscore=1501 malwarescore=0 suspectscore=2 phishscore=0 bulkscore=0 spamscore=0 clxscore=1034 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1609020000 definitions=main-1609280317 Sender: linux-scsi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-scsi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When an ELS response handler receives a -FC_EX_CLOSED, the rdata->rp_mutex is already held which can lead to a deadlock condition like the following stack trace: [] fc_rport_plogi_resp+0x28/0x200 [libfc] [] fc_invoke_resp+0x6a/0xe0 [libfc] [] fc_exch_mgr_reset+0x1b8/0x280 [libfc] [] fc_rport_logoff+0x43/0xd0 [libfc] [] fc_disc_stop+0x6d/0xf0 [libfc] [] fc_disc_stop_final+0xe/0x20 [libfc] [] fc_fabric_logoff+0x17/0x70 [libfc] The other ELS handlers need to follow the FLOGI response handler and simply do a kref_put against the fc_rport_priv struct and exit when receving a -FC_EX_CLOSED response. Signed-off-by: Chad Dupuis --- drivers/scsi/libfc/fc_rport.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/scsi/libfc/fc_rport.c b/drivers/scsi/libfc/fc_rport.c index 93f5961..6f19c12 100644 --- a/drivers/scsi/libfc/fc_rport.c +++ b/drivers/scsi/libfc/fc_rport.c @@ -884,10 +884,13 @@ static void fc_rport_plogi_resp(struct fc_seq *sp, struct fc_frame *fp, u16 cssp_seq; u8 op; - mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rdata, "Received a PLOGI %s\n", fc_els_resp_type(fp)); + if (fp == ERR_PTR(-FC_EX_CLOSED)) + goto put; + + mutex_lock(&rdata->rp_mutex); + if (rdata->rp_state != RPORT_ST_PLOGI) { FC_RPORT_DBG(rdata, "Received a PLOGI response, but in state " "%s\n", fc_rport_state(rdata)); @@ -926,6 +929,7 @@ out: fc_frame_free(fp); err: mutex_unlock(&rdata->rp_mutex); +put: kref_put(&rdata->kref, lport->tt.rport_destroy); } @@ -1008,10 +1012,13 @@ static void fc_rport_prli_resp(struct fc_seq *sp, struct fc_frame *fp, u8 op; u8 resp_code = 0; - mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rdata, "Received a PRLI %s\n", fc_els_resp_type(fp)); + if (fp == ERR_PTR(-FC_EX_CLOSED)) + goto put; + + mutex_lock(&rdata->rp_mutex); + if (rdata->rp_state != RPORT_ST_PRLI) { FC_RPORT_DBG(rdata, "Received a PRLI response, but in state " "%s\n", fc_rport_state(rdata)); @@ -1079,6 +1086,7 @@ out: fc_frame_free(fp); err: mutex_unlock(&rdata->rp_mutex); +put: kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); } @@ -1156,10 +1164,13 @@ static void fc_rport_rtv_resp(struct fc_seq *sp, struct fc_frame *fp, struct fc_rport_priv *rdata = rdata_arg; u8 op; - mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rdata, "Received a RTV %s\n", fc_els_resp_type(fp)); + if (fp == ERR_PTR(-FC_EX_CLOSED)) + goto put; + + mutex_lock(&rdata->rp_mutex); + if (rdata->rp_state != RPORT_ST_RTV) { FC_RPORT_DBG(rdata, "Received a RTV response, but in state " "%s\n", fc_rport_state(rdata)); @@ -1201,6 +1212,7 @@ out: fc_frame_free(fp); err: mutex_unlock(&rdata->rp_mutex); +put: kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); } @@ -1292,10 +1304,13 @@ static void fc_rport_adisc_resp(struct fc_seq *sp, struct fc_frame *fp, struct fc_els_adisc *adisc; u8 op; - mutex_lock(&rdata->rp_mutex); - FC_RPORT_DBG(rdata, "Received a ADISC response\n"); + if (fp == ERR_PTR(-FC_EX_CLOSED)) + goto put; + + mutex_lock(&rdata->rp_mutex); + if (rdata->rp_state != RPORT_ST_ADISC) { FC_RPORT_DBG(rdata, "Received a ADISC resp but in state %s\n", fc_rport_state(rdata)); @@ -1330,6 +1345,7 @@ out: fc_frame_free(fp); err: mutex_unlock(&rdata->rp_mutex); +put: kref_put(&rdata->kref, rdata->local_port->tt.rport_destroy); }