Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933295AbcJUJSu (ORCPT ); Fri, 21 Oct 2016 05:18:50 -0400 Received: from mail.linuxfoundation.org ([140.211.169.12]:46800 "EHLO mail.linuxfoundation.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753949AbcJUJSj (ORCPT ); Fri, 21 Oct 2016 05:18:39 -0400 From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Dennis Dalessandro , Mike Marciniszyn , Doug Ledford Subject: [PATCH 4.7 15/45] IB/hfi1: Fix defered ack race with qp destroy Date: Fri, 21 Oct 2016 11:17:35 +0200 Message-Id: <20161021091428.095066452@linuxfoundation.org> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161021091427.214431885@linuxfoundation.org> References: <20161021091427.214431885@linuxfoundation.org> User-Agent: quilt/0.64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2089 Lines: 61 4.7-stable review patch. If anyone has any objections, please let me know. ------------------ From: Mike Marciniszyn commit 72f53af2651957b0b9d6dead72a393eaf9a2c3be upstream. There is a a bug in defered ack stuff that causes a race with the destroy of a QP. A packet causes a defered ack to be pended by putting the QP into an rcd queue. A return from the driver interrupt processing will process that rcd queue of QPs and attempt to do a direct send of the ack. At this point no locks are held and the above QP could now be put in the reset state in the qp destroy logic. A refcount protects the QP while it is in the rcd queue so it isn't going anywhere yet. If the direct send fails to allocate a pio buffer, hfi1_schedule_send() is called to trigger sending an ack from the send engine. There is no state test in that code path. The refcount is then dropped from the driver.c caller potentially allowing the qp destroy to continue from its refcount wait in parallel with the workqueue scheduling of the qp. Reviewed-by: Dennis Dalessandro Signed-off-by: Mike Marciniszyn Signed-off-by: Dennis Dalessandro Signed-off-by: Doug Ledford Signed-off-by: Greg Kroah-Hartman --- drivers/infiniband/hw/hfi1/rc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) --- a/drivers/infiniband/hw/hfi1/rc.c +++ b/drivers/infiniband/hw/hfi1/rc.c @@ -889,8 +889,10 @@ void hfi1_send_rc_ack(struct hfi1_ctxtda return; queue_ack: - this_cpu_inc(*ibp->rvp.rc_qacks); spin_lock_irqsave(&qp->s_lock, flags); + if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK)) + goto unlock; + this_cpu_inc(*ibp->rvp.rc_qacks); qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING; qp->s_nak_state = qp->r_nak_state; qp->s_ack_psn = qp->r_ack_psn; @@ -899,6 +901,7 @@ queue_ack: /* Schedule the send tasklet. */ hfi1_schedule_send(qp); +unlock: spin_unlock_irqrestore(&qp->s_lock, flags); }