Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp775625imu; Thu, 20 Dec 2018 05:15:58 -0800 (PST) X-Google-Smtp-Source: AFSGD/W8lu0ER7LiOROk8wMq6OQql5tIpnN92YAM/d/LWntZ48BV9XeVNYk5+jxNbHBMyWZkJEt6 X-Received: by 2002:a63:960a:: with SMTP id c10mr22788069pge.106.1545311758798; Thu, 20 Dec 2018 05:15:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545311758; cv=none; d=google.com; s=arc-20160816; b=yc3zjqtHsYPQ0BxmmCsymRh1Ub28lW4ZNRcqb5sAUQupQPBqP+eCRk2GvRuqLh9vA5 p9kGyIHgiCP08vorPqGeCoCnx08H/9OKs5XWh8lby/XSP7G/k6AAI3vbSHaFrfEwod9S BsuaAXx8/vSBaPVRlacwWU9bX4BuYGpj5jaTErlJsLOHFIp8lPjtpqpBuJNu7fTqu5FJ j3sPV8ow4kjDZlwdZOzMjYdduJEcyw6oQV4hDdictBOPheklqYFyhObkWBo7xOMb2ddS eFOTGIk9GHxXq5qPcDlL4flnLylsFw79Pv6wDnQ7jMPPbrA6wnNWS1mQ92X8eLz6sl1P nHHw== 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=R7Vb1KH8CHGh0G0NZUSkeHkiBxEKZLZ4vE725RkAHOA=; b=vH5ubE9Zid+Z4ZEFcKsIEpgxJzkByDHvOcUTp2QtXsqk178Rbf/qprARZj9CKHYtoG fwO4DtdCmAGOCO2K5cEnt4+D0tvWwrT1N3W9KUUYdnHhFxSTTvFwDi2+0gnYzAvpL9hI TwMpJXR/t4puQpGDSpfMGeZQ311toYRBTF//x+P8tQOU6TSf7c6NjVC3x+PfmCOFLjEY rniN01YkJBhUU3EP5O4iHf2O/eyWX0A15tS4dMM0WFY0UJtuFXFQH9S19bifiT0LvXP4 aCGK8DUgZG1bno3dAlqiFPLYDFrrgUp9ErWidqRePb5WjvhEFf2VibDtSCsHvljGkLJ3 KLqA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=gMyyvFEE; 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 t12si17781137plr.311.2018.12.20.05.15.41; Thu, 20 Dec 2018 05:15:58 -0800 (PST) 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=gMyyvFEE; 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 S1732486AbeLTJ2X (ORCPT + 99 others); Thu, 20 Dec 2018 04:28:23 -0500 Received: from mail.kernel.org ([198.145.29.99]:45300 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732463AbeLTJ2U (ORCPT ); Thu, 20 Dec 2018 04:28:20 -0500 Received: from localhost (5356596B.cm-6-7b.dynamic.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 CCDFD20989; Thu, 20 Dec 2018 09:28:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1545298099; bh=+RrqGmZz7aew2GY6efOMTn5wOYn9Ds9yHoIPVWVgHog=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gMyyvFEE1Xx/T2/Q6Wm3fWkB/eCkos3lgJP+Hc+ifI6DTgtbn2JTQuBnT/afxwPqD dg0dJP009BrXYLVCj2OOSKU3p/GnOZMUtW9rBUaOnohb0MFs7SanVlyV2MK2uypsOd zxpFl8NRYdHGBTdCfbdF6x1DWUeKpf1Vqmw9mTm0= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Mitko Haralanov , Mike Marciniszyn , "Michael J. Ruhl" , Sasha Levin Subject: [PATCH 4.14 34/72] IB/hfi1: Remove race conditions in user_sdma send path Date: Thu, 20 Dec 2018 10:18:33 +0100 Message-Id: <20181220085923.683529406@linuxfoundation.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20181220085922.332225035@linuxfoundation.org> References: <20181220085922.332225035@linuxfoundation.org> User-Agent: quilt/0.65 X-stable: review X-Patchwork-Hint: ignore 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 4.14-stable review patch. If anyone has any objections, please let me know. ------------------ commit 28a9a9e83ceae2cee25b9af9ad20d53aaa9ab951 upstream Packet queue state is over used to determine SDMA descriptor availablitity and packet queue request state. cpu 0 ret = user_sdma_send_pkts(req, pcount); cpu 0 if (atomic_read(&pq->n_reqs)) cpu 1 IRQ user_sdma_txreq_cb calls pq_update() (state to _INACTIVE) cpu 0 xchg(&pq->state, SDMA_PKT_Q_ACTIVE); At this point pq->n_reqs == 0 and pq->state is incorrectly SDMA_PKT_Q_ACTIVE. The close path will hang waiting for the state to return to _INACTIVE. This can also change the state from _DEFERRED to _ACTIVE. However, this is a mostly benign race. Remove the racy code path. Use n_reqs to determine if a packet queue is active or not. Cc: # 4.14.0> Reviewed-by: Mitko Haralanov Reviewed-by: Mike Marciniszyn Signed-off-by: Michael J. Ruhl Signed-off-by: Sasha Levin --- drivers/infiniband/hw/hfi1/user_sdma.c | 24 ++++++++++-------------- drivers/infiniband/hw/hfi1/user_sdma.h | 9 +++++---- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c index c14ec04f2a89..cbe5ab26d95b 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.c +++ b/drivers/infiniband/hw/hfi1/user_sdma.c @@ -187,7 +187,6 @@ int hfi1_user_sdma_alloc_queues(struct hfi1_ctxtdata *uctxt, pq->ctxt = uctxt->ctxt; pq->subctxt = fd->subctxt; pq->n_max_reqs = hfi1_sdma_comp_ring_size; - pq->state = SDMA_PKT_Q_INACTIVE; atomic_set(&pq->n_reqs, 0); init_waitqueue_head(&pq->wait); atomic_set(&pq->n_locked, 0); @@ -276,7 +275,7 @@ int hfi1_user_sdma_free_queues(struct hfi1_filedata *fd, /* Wait until all requests have been freed. */ wait_event_interruptible( pq->wait, - (ACCESS_ONCE(pq->state) == SDMA_PKT_Q_INACTIVE)); + !atomic_read(&pq->n_reqs)); kfree(pq->reqs); kfree(pq->req_in_use); kmem_cache_destroy(pq->txreq_cache); @@ -312,6 +311,13 @@ static u8 dlid_to_selector(u16 dlid) return mapping[hash]; } +/** + * hfi1_user_sdma_process_request() - Process and start a user sdma request + * @fd: valid file descriptor + * @iovec: array of io vectors to process + * @dim: overall iovec array size + * @count: number of io vector array entries processed + */ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, struct iovec *iovec, unsigned long dim, unsigned long *count) @@ -560,20 +566,12 @@ int hfi1_user_sdma_process_request(struct hfi1_filedata *fd, req->ahg_idx = sdma_ahg_alloc(req->sde); set_comp_state(pq, cq, info.comp_idx, QUEUED, 0); + pq->state = SDMA_PKT_Q_ACTIVE; /* Send the first N packets in the request to buy us some time */ ret = user_sdma_send_pkts(req, pcount); if (unlikely(ret < 0 && ret != -EBUSY)) goto free_req; - /* - * It is possible that the SDMA engine would have processed all the - * submitted packets by the time we get here. Therefore, only set - * packet queue state to ACTIVE if there are still uncompleted - * requests. - */ - if (atomic_read(&pq->n_reqs)) - xchg(&pq->state, SDMA_PKT_Q_ACTIVE); - /* * This is a somewhat blocking send implementation. * The driver will block the caller until all packets of the @@ -1391,10 +1389,8 @@ static void user_sdma_txreq_cb(struct sdma_txreq *txreq, int status) static inline void pq_update(struct hfi1_user_sdma_pkt_q *pq) { - if (atomic_dec_and_test(&pq->n_reqs)) { - xchg(&pq->state, SDMA_PKT_Q_INACTIVE); + if (atomic_dec_and_test(&pq->n_reqs)) wake_up(&pq->wait); - } } static void user_sdma_free_request(struct user_sdma_request *req, bool unpin) diff --git a/drivers/infiniband/hw/hfi1/user_sdma.h b/drivers/infiniband/hw/hfi1/user_sdma.h index 5af52334b7dc..2b5326d6db53 100644 --- a/drivers/infiniband/hw/hfi1/user_sdma.h +++ b/drivers/infiniband/hw/hfi1/user_sdma.h @@ -94,9 +94,10 @@ #define TXREQ_FLAGS_REQ_ACK BIT(0) /* Set the ACK bit in the header */ #define TXREQ_FLAGS_REQ_DISABLE_SH BIT(1) /* Disable header suppression */ -#define SDMA_PKT_Q_INACTIVE BIT(0) -#define SDMA_PKT_Q_ACTIVE BIT(1) -#define SDMA_PKT_Q_DEFERRED BIT(2) +enum pkt_q_sdma_state { + SDMA_PKT_Q_ACTIVE, + SDMA_PKT_Q_DEFERRED, +}; /* * Maximum retry attempts to submit a TX request @@ -124,7 +125,7 @@ struct hfi1_user_sdma_pkt_q { struct user_sdma_request *reqs; unsigned long *req_in_use; struct iowait busy; - unsigned state; + enum pkt_q_sdma_state state; wait_queue_head_t wait; unsigned long unpinned; struct mmu_rb_handler *handler; -- 2.19.1