From patchwork Mon Nov 23 12:19:33 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Greg KH X-Patchwork-Id: 330658 Delivered-To: patch@linaro.org Received: by 2002:a92:ae0b:0:0:0:0:0 with SMTP id s11csp1964794ilh; Mon, 23 Nov 2020 04:44:45 -0800 (PST) X-Google-Smtp-Source: ABdhPJxmsqCg4Q+PE+/8mcSdt4BnF6+igzUlPJG6BpG7LmNe38nk9sgUIU/qCvMU46ov9kiynG0x X-Received: by 2002:a17:906:d784:: with SMTP id pj4mr42601234ejb.78.1606135485702; Mon, 23 Nov 2020 04:44:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1606135485; cv=none; d=google.com; s=arc-20160816; b=nd3WBPh2+sIcd2EXEu4KxAfaSPcUaRJHrKV51KVFV+jzKJJ0RalGLaTi8VVnjNSyRP 8t7xIPGjrDfAAO7fnfve7tL4JbcggJmuFIgWtpANMDFHWUs1mZBrzKx6sUSGuDmqc+4R uM3ETTjPSuk2+0aMtvEN/FmzdvcMavc7s2B8J88vN2ybO7A/2TrqIYPKH4lTKn5jyAgg KtdBSiGT3YqBxPyiGy6ri9cHgTi1Ly1n8Iwc4OQmbGGH06xeUF/9aH8c8x0hE4gcO9Dv SmU8CoyHIei5PXNOm01G6Gu+sPLzbYoX5reEK+/UTlg/HVcrY1hWVEtLgN2enMXejg95 TzIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=2b+h4eZcPxwD6AgaJELJPpBO+qSl1aLiCzeqypsakY8=; b=XjN9vDequwHnkPW2mCtOErXJC5HNJEL7TPTrIqessEO/+Zt2h3aCv7qGArQbMoPdDe g++zYaOLwihSln5dNvMVLP0H1lkybqEJW05wjP+/jSX/HyiCGBy7t/9TN2frJ38B8lxd XH6zrGSFvt55txUTL2XdYrWuVDj0rCvnoCnM5MobsKZpc8CIWZp38meIUPGYPyYk2Whc anfg6jp+8tQziCoCR6CWnaO/4IawXmCKGhAWOwvA3o1AJETTC092Z18LXLj0s5JL/O9C FiPRoiRXigElZy1MDxtwN1Ji2FqKvFerKFRMwqV2JPZUa80jz7SZMd69SB3HqYSvnJvs vrag== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=dKSO2CLN; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z21si6338215ejc.256.2020.11.23.04.44.45; Mon, 23 Nov 2020 04:44:45 -0800 (PST) Received-SPF: pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=dKSO2CLN; spf=pass (google.com: domain of stable-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732621AbgKWMmg (ORCPT + 14 others); Mon, 23 Nov 2020 07:42:36 -0500 Received: from mail.kernel.org ([198.145.29.99]:54896 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732753AbgKWMlv (ORCPT ); Mon, 23 Nov 2020 07:41:51 -0500 Received: from localhost (83-86-74-64.cable.dynamic.v4.ziggo.nl [83.86.74.64]) (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 E21EF20888; Mon, 23 Nov 2020 12:41:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1606135310; bh=6H6KG8txNKgnXHNj3Ey5OpYJ13zYZsJJLJPC37mIlEk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=dKSO2CLNmCC/m1Z8fu4wuOimpRfZ7s71YZDtamsaaQ2rlnW0EuqKzvmtRSuDmgfWs EqgNNktYT5yQRRNeZ/Ge5o/jTOUFfIV/obv3x1aKDCybE8MfGMEKT4kqYgR44o3Pjk T/7PrP17R7WacJOiNtXn1U4v6qNgATphO6Pukqnw= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, Stephen Boyd , Alex Elder , Jakub Kicinski Subject: [PATCH 5.9 023/252] net: ipa: lock when freeing transaction Date: Mon, 23 Nov 2020 13:19:33 +0100 Message-Id: <20201123121836.716621324@linuxfoundation.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20201123121835.580259631@linuxfoundation.org> References: <20201123121835.580259631@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Alex Elder [ Upstream commit 064c9c32b17ca9b36f95eba32ee790dbbebd9a5f ] Transactions sit on one of several lists, depending on their state (allocated, pending, complete, or polled). A spinlock protects against concurrent access when transactions are moved between these lists. Transactions are also reference counted. A newly-allocated transaction has an initial count of 1; a transaction is released in gsi_trans_free() only if its decremented reference count reaches 0. Releasing a transaction includes removing it from the polled (or if unused, allocated) list, so the spinlock is acquired when we release a transaction. The reference count is used to allow a caller to synchronously wait for a committed transaction to complete. In this case, the waiter takes an extra reference to the transaction *before* committing it (so it won't be freed), and releases its reference (calls gsi_trans_free()) when it is done with it. Similarly, gsi_channel_update() takes an extra reference to ensure a transaction isn't released before the function is done operating on it. Until the transaction is moved to the completed list (by this function) it won't be freed, so this reference is taken "safely." But in the quiesce path, we want to wait for the "last" transaction, which we find in the completed or polled list. Transactions on these lists can be freed at any time, so we (try to) prevent that by taking the reference while holding the spinlock. Currently gsi_trans_free() decrements a transaction's reference count unconditionally, acquiring the lock to remove the transaction from its list *only* when the count reaches 0. This does not protect the quiesce path, which depends on the lock to ensure its extra reference prevents release of the transaction. Fix this by only dropping the last reference to a transaction in gsi_trans_free() while holding the spinlock. Fixes: 9dd441e4ed575 ("soc: qcom: ipa: GSI transactions") Reported-by: Stephen Boyd Signed-off-by: Alex Elder Link: https://lore.kernel.org/r/20201114182017.28270-1-elder@linaro.org Signed-off-by: Jakub Kicinski Signed-off-by: Greg Kroah-Hartman --- drivers/net/ipa/gsi_trans.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) --- a/drivers/net/ipa/gsi_trans.c +++ b/drivers/net/ipa/gsi_trans.c @@ -363,22 +363,31 @@ struct gsi_trans *gsi_channel_trans_allo return trans; } -/* Free a previously-allocated transaction (used only in case of error) */ +/* Free a previously-allocated transaction */ void gsi_trans_free(struct gsi_trans *trans) { + refcount_t *refcount = &trans->refcount; struct gsi_trans_info *trans_info; + bool last; - if (!refcount_dec_and_test(&trans->refcount)) + /* We must hold the lock to release the last reference */ + if (refcount_dec_not_one(refcount)) return; trans_info = &trans->gsi->channel[trans->channel_id].trans_info; spin_lock_bh(&trans_info->spinlock); - list_del(&trans->links); + /* Reference might have been added before we got the lock */ + last = refcount_dec_and_test(refcount); + if (last) + list_del(&trans->links); spin_unlock_bh(&trans_info->spinlock); + if (!last) + return; + ipa_gsi_trans_release(trans); /* Releasing the reserved TREs implicitly frees the sgl[] and