Received: by 2002:a17:90a:1609:0:0:0:0 with SMTP id n9csp2192383pja; Thu, 26 Mar 2020 11:08:09 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvEIu7Sitdy01TAyy7c8Uv/c+zfRn9BAWFVJcNNJSLOaf45zIjpgWJkjDcevo+Sg7mtn4fu X-Received: by 2002:aca:d64f:: with SMTP id n76mr1078699oig.48.1585246089242; Thu, 26 Mar 2020 11:08:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585246089; cv=none; d=google.com; s=arc-20160816; b=YX/K5NJoIVe2+ClZJL4UISp5+0PZjAU3nrY3bF92tL0afKYTCsIEYlMqMcFchiqEz1 h+YJMdsROhybE/qItr4CXapWWP4ps6KAJK+Ywdczbl59A9J+gq4v5xT8aCEpeL5uB1IC fLaHFW+guxEG1Z64yJ0Moeakj2UjY6ZGJGXBVZ66eyDbEIZzeNsN8epT+RzzHfC0XgBr Y3d6DOj76PpYb4kfO7pRdb40BUJDFmBKn6QX3wiQlXiwo5nzBw6GMSjHSUs6452n7Bwm /T+u1xfacd5kvmjuYx8TpN+0yVO+uZuQle8uIRrj+KoNCer/bepRNNy3wu7/oQKw1cbt PBaA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=S+88eV5gK0LljhqKdZ1yGcysPszYlI5kB6q6EVwjYtM=; b=Xt/XgGuli+eimeeHzB7qB0h5H8KDL6ek7zRlyWV8BdOPtrPbAkqd0rL+b/X7JwbzSp e1epJFUUrAbfMJk2fpGJSjEn10+ih+Tuy5Dyw76lrxqrfQllk3kSdY2wc8dD1iGv3JZb J4Q0oyetIkdQPBZCuYDN+EHfXlpkf4oM3kZQPYuZiFzuHtSLXiopdUt+Hgr8qeji9tED zShI56nX2WKvX2Ak6/+pxBLbVIjSACSVoSjmSg9PjeD30kMn5TdVKDPEomw2qoZ1tKBk 1Vzh4HiYI8Y6qmhMAdmoznQQMi952JGecQeqKKTHSXj8bVWYt7NMfEzY/hFaEIg5Gc73 I0tg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=iajwo6oj; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id z25si1044677otp.310.2020.03.26.11.07.55; Thu, 26 Mar 2020 11:08:09 -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=@chromium.org header.s=google header.b=iajwo6oj; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727879AbgCZSHY (ORCPT + 99 others); Thu, 26 Mar 2020 14:07:24 -0400 Received: from mail-ua1-f65.google.com ([209.85.222.65]:46029 "EHLO mail-ua1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727803AbgCZSHX (ORCPT ); Thu, 26 Mar 2020 14:07:23 -0400 Received: by mail-ua1-f65.google.com with SMTP id 9so2468280uav.12 for ; Thu, 26 Mar 2020 11:07:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=S+88eV5gK0LljhqKdZ1yGcysPszYlI5kB6q6EVwjYtM=; b=iajwo6ojaH6PQ0M+kFhP3CIwc4WeldtAB8KkVDaqEJ2XOiscCgtWqKrv9JgYGGrzCN 9HdQjVQDYrEB0Tpwu/BZBGrA+jNrpOZ5/jUEOE9t1h6DXRmYGPEbeHF4k7AwRlraXoPf nkYRKiOHMLvzeuAXL9m/nvB/Uo76yXnDU+Dw8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=S+88eV5gK0LljhqKdZ1yGcysPszYlI5kB6q6EVwjYtM=; b=P0283AbNi5TJOQyaKdS5WT2Yb8P+G+pzHSAAdA4IQ0645uFH+jkG3n3bptu/pBOY52 Agn6RSK37ZVWcqtUYgtGchfzhGaSHgvw/eoOu/6O8jUqESFfbWXw4zvjGIreU7epssy7 syM6IpymbSaRaIKi19EJNf5tq29Bo8RM6yki1tdqPexf5T9Lr5F4jiEKDLLVF2qFo3UF vEsa4mGPG/r2pWyXe0PhttEWYnxShd5e3FUleizS0VmOCkig6pjA79sYTe//YrPq/kP8 o9svDXdshSU1ZFxvxjLH3GPhG/6b7zvykfCWovRkDCOj0fpmDunB60Porn9LlOHY32PO qKyw== X-Gm-Message-State: ANhLgQ14ePDu10U9mt7cKKCwrGC7+Bjta0CjMTG1GBZwbEuljb5g5PEv OV58IofxQKQKc8kCmSmmU96i6YnNuJg= X-Received: by 2002:ab0:70a1:: with SMTP id q1mr7785760ual.52.1585246041293; Thu, 26 Mar 2020 11:07:21 -0700 (PDT) Received: from mail-vs1-f52.google.com (mail-vs1-f52.google.com. [209.85.217.52]) by smtp.gmail.com with ESMTPSA id e1sm1345644vkg.10.2020.03.26.11.07.19 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 26 Mar 2020 11:07:20 -0700 (PDT) Received: by mail-vs1-f52.google.com with SMTP id a63so4475810vsa.8 for ; Thu, 26 Mar 2020 11:07:19 -0700 (PDT) X-Received: by 2002:a67:1e46:: with SMTP id e67mr8011826vse.106.1585246038937; Thu, 26 Mar 2020 11:07:18 -0700 (PDT) MIME-Version: 1.0 References: <20190218140210.14631-1-rplsssn@codeaurora.org> <20190218140210.14631-2-rplsssn@codeaurora.org> In-Reply-To: <20190218140210.14631-2-rplsssn@codeaurora.org> From: Doug Anderson Date: Thu, 26 Mar 2020 11:07:07 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH RESEND v1 1/2] drivers: qcom: rpmh-rsc: clear active mode configuration for wake TCS To: Andy Gross , David Brown , linux-arm-msm , "open list:ARM/QUALCOMM SUPPORT" Cc: Rajendra Nayak , Bjorn Andersson , LKML , Linux PM , Stephen Boyd , Evan Green , Matthias Kaehlcke , Lina Iyer , "Raju P.L.S.S.S.N" , Maulik Shah Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi On Mon, 18 Feb 2019 19:32:09 Raju P.L.S.S.S.N wrote: > > For RSCs that have sleep & wake TCS but no dedicated active TCS, wake > TCS can be re-purposed to send active requests. Once the active requests > are sent and response is received, the active mode configuration needs > to be cleared so that controller can use wake TCS for sending wake > requests. > > Signed-off-by: Raju P.L.S.S.S.N > Reviewed-by: Matthias Kaehlcke > --- > drivers/soc/qcom/rpmh-rsc.c | 77 ++++++++++++++++++++++++++----------- > 1 file changed, 54 insertions(+), 23 deletions(-) > > diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c > index 75bd9a83aef0..6cc7f219ce48 100644 > --- a/drivers/soc/qcom/rpmh-rsc.c > +++ b/drivers/soc/qcom/rpmh-rsc.c > @@ -201,6 +201,42 @@ static const struct tcs_request *get_req_from_tcs(struct rsc_drv *drv, > return NULL; > } > > +static void __tcs_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) nit: can you rename this to __tcs_set_trigger() so it's a little more obvious that the last value means trigger/untrigger? It'd also be nice to really understand why it has to be structured this way. It's weird that the two options are "untrigger + retrigger" and "untrigger" > +{ > + u32 enable; > + > + /* > + * HW req: Clear the DRV_CONTROL and enable TCS again > + * While clearing ensure that the AMC mode trigger is cleared > + * and then the mode enable is cleared. > + */ > + enable = read_tcs_reg(drv, RSC_DRV_CONTROL, tcs_id, 0); > + enable &= ~TCS_AMC_MODE_TRIGGER; > + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); > + enable &= ~TCS_AMC_MODE_ENABLE; > + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); > + > + if (trigger) { > + /* Enable the AMC mode on the TCS and then trigger the TCS */ > + enable = TCS_AMC_MODE_ENABLE; > + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); > + enable |= TCS_AMC_MODE_TRIGGER; > + write_tcs_reg_sync(drv, RSC_DRV_CONTROL, tcs_id, enable); > + } > +} > + > +static inline void enable_tcs_irq(struct rsc_drv *drv, int tcs_id, bool enable) > +{ > + u32 data; > + > + data = read_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, 0); > + if (enable) > + data |= BIT(tcs_id); > + else > + data &= ~BIT(tcs_id); > + write_tcs_reg(drv, RSC_DRV_IRQ_ENABLE, 0, data); > +} > + > /** > * tcs_tx_done: TX Done interrupt handler > */ > @@ -237,6 +273,21 @@ static irqreturn_t tcs_tx_done(int irq, void *p) > } > > trace_rpmh_tx_done(drv, i, req, err); > + > + /* > + * if wake tcs was re-purposed for sending active > + * votes, clear AMC trigger & enable modes and > + * disable interrupt for this TCS > + */ > + if (!drv->tcs[ACTIVE_TCS].num_tcs) { > + __tcs_trigger(drv, i, false); I assume that the reason that the code originally didn't try to "untrigger" in the interrupt handler is that it's slow (it uses write_tcs_reg_sync). If that's true then maybe you shouldn't do the untrigger here for the case when you're on a borrowed TCS. Can't you just do the untrigger later when you reprogram the TCS for someone else's use? > + /* > + * Disable interrupt for this TCS to avoid being > + * spammed with interrupts coming when the solver > + * sends its wake votes. > + */ > + enable_tcs_irq(drv, i, false); Should you be doing this under the spinlock? You're doing a read-modify-write of the RSC_DRV_IRQ_ENABLE register which seems like it could race with someone trying to enable an IRQ if the borrowed TCS type has more than one TCS (so you could be trying to start a transfer on one TCS while one is finishing on another). It would be somewhat hard for this to happen, but I don't _think_ it's impossible. Specifically: 1. Two threads can call rpmh_write() at the same time. 2. Both threads call into rpmh_rsc_send_data() w/out holding any locks. 3. Both threads call into tcs_write() w/out holding any locks. 4. Both threads call get_tcs_for_msg() w/out holding any locks. 5. Both threads notice they need to borrow the wake TCS. 6. Both threads call rpmh_rsc_invalidate(). There are locks in here, but nothing stops both threads from returning 0 (not -EAGAIN) since nobody has claimed the wake TCS by setting 'tcs_in_use' yet. Assuming that there are more than one wake TCSs it is possible that both transfers can be happening at the same time and I believe it's even possible (though you'd need crazy timing) for one thread to hit the interrupt handler and finish at the same time that the other thread starts. Assuming we care about the case of having zero-active TCS and more-than-one-wake TCS, it'd be nice to fix. If we don't care about this case, it should be documented in the code. Funny enough, most of the time having zero-active TCS and more-than-one-wake TCS doesn't buy us much with the current code because the 2nd thread will return -EAGAIN from rpmh_rsc_invalidate() assuming that the 1st thread manages to set "tcs_in_use" before the 2nd thread gets there. Overall the locking involved with borrowing a wake TCS is really tricky if you want to close all corner cases. I need to constantly refer to my series adding documentation to have any chance here. https://lore.kernel.org/r/20200311161104.RFT.v2.5.I52653eb85d7dc8981ee0dafcd0b6cc0f273e9425@changeid I'd love review feedback on that! Some of this stuff maybe becomes easier to understand if we don't have Maulik's flushing series and we can always assume that writing active TCSs and writing sleep/wake TCSs never happen at the same time (I think traditionally sleep/wake TCSs only get written from special PM code when we know nothing else is running). -Doug