Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 735FCC433F5 for ; Tue, 11 Jan 2022 20:20:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S244359AbiAKUUe (ORCPT ); Tue, 11 Jan 2022 15:20:34 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244059AbiAKUU1 (ORCPT ); Tue, 11 Jan 2022 15:20:27 -0500 Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3932C061756 for ; Tue, 11 Jan 2022 12:20:26 -0800 (PST) Received: by mail-pj1-x102b.google.com with SMTP id n30-20020a17090a5aa100b001b2b6509685so856822pji.3 for ; Tue, 11 Jan 2022 12:20:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=C3y1gsU53cU0M96DAP0mJZYhnckzL5l0LMIdOY1soDM=; b=DIBAYaAINs1ZCRwrmioj93W8oTc1wNh6GCtdd3lx0HkK1+34jZUuhSYeHcceGA5gUk spfkDqAXZWVKYXcMubaTtH4oIFNAx+aWLhUXk1l6BkKx23gEPoVTZ14wF9l7HrTSIKs6 B6EQS3cIIx2f/9KGNhSZkgla9BG7blg0lFH54= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=C3y1gsU53cU0M96DAP0mJZYhnckzL5l0LMIdOY1soDM=; b=TEsO1j+y9aUc1SUzr8IuGItOTOhSagVJGmIy7R29jlxPOxLfk4KTglC474saZrDiJb f+hOsKQ5ywYPl4/EzKpvHuQra4Su1KTdmQPEAebihOG0BtTbEKfOwtxPV83RQ7hkXQLr 2xAxEcioAnjdsHw0d3QXJeBY8F3Qjo4juEiz7UR8ZAhSD0IV0UOyX2+Nrri/B74rylD2 E2G6TyaZ2BfR+DXUBEov6s0K4whty9ZLbdCpXADN7iGGfHAGrWrB0lqnjYIeLPcqzcow aN3j9SMPNnRDDjK+gVindKAOAxDdeERhkGYKxWPLRr+Z2PD+36xTLYdQXiWPt81O65Wp BaRw== X-Gm-Message-State: AOAM531GqMwTCoeUAIaVr+HlG6hDQzVJE9vkhbqZsEOBkoJHh/XVtaZD 3GpXAPJdyekB8PHov3J52BHUKg== X-Google-Smtp-Source: ABdhPJxdFw4zQYvyjcl5AtbxFlvjo9EJjjDavrF0GPgcOtKpd3UN4iOcTHrAENdb5oKbCz1XkpU/TA== X-Received: by 2002:a17:902:e88a:b0:14a:19f6:6396 with SMTP id w10-20020a170902e88a00b0014a19f66396mr6285403plg.95.1641932426389; Tue, 11 Jan 2022 12:20:26 -0800 (PST) Received: from localhost ([2620:15c:202:201:f0a7:d33a:2234:5687]) by smtp.gmail.com with UTF8SMTPSA id p32sm178337pgb.49.2022.01.11.12.20.25 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 11 Jan 2022 12:20:26 -0800 (PST) Date: Tue, 11 Jan 2022 12:20:24 -0800 From: Matthias Kaehlcke To: Alex Elder Cc: davem@davemloft.net, kuba@kernel.org, jponduru@codeaurora.org, avuyyuru@codeaurora.org, bjorn.andersson@linaro.org, agross@kernel.org, cpratapa@codeaurora.org, subashab@codeaurora.org, evgreen@chromium.org, elder@kernel.org, netdev@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH net 2/2] net: ipa: prevent concurrent replenish Message-ID: References: <20220111192150.379274-1-elder@linaro.org> <20220111192150.379274-3-elder@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20220111192150.379274-3-elder@linaro.org> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Jan 11, 2022 at 01:21:50PM -0600, Alex Elder wrote: > We have seen cases where an endpoint RX completion interrupt arrives > while replenishing for the endpoint is underway. This causes another > instance of replenishing to begin as part of completing the receive > transaction. If this occurs it can lead to transaction corruption. > > Use a new atomic variable to ensure only replenish instance for an > endpoint executes at a time. > > Fixes: 84f9bd12d46db ("soc: qcom: ipa: IPA endpoints") > Signed-off-by: Alex Elder > --- > drivers/net/ipa/ipa_endpoint.c | 13 +++++++++++++ > drivers/net/ipa/ipa_endpoint.h | 2 ++ > 2 files changed, 15 insertions(+) > > diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c > index 8b055885cf3cf..a1019f5fe1748 100644 > --- a/drivers/net/ipa/ipa_endpoint.c > +++ b/drivers/net/ipa/ipa_endpoint.c > @@ -1088,15 +1088,27 @@ static void ipa_endpoint_replenish(struct ipa_endpoint *endpoint, bool add_one) > return; > } > > + /* If already active, just update the backlog */ > + if (atomic_xchg(&endpoint->replenish_active, 1)) { > + if (add_one) > + atomic_inc(&endpoint->replenish_backlog); > + return; > + } > + > while (atomic_dec_not_zero(&endpoint->replenish_backlog)) > if (ipa_endpoint_replenish_one(endpoint)) > goto try_again_later; I think there is a race here, not sure whether it's a problem: If the first interrupt is here just when a 2nd interrupt evaluates 'replenish_active' the latter will return, since it looks like replenishing is still active, when it actually just finished. Would replenishing be kicked off anyway shortly after or could the transaction be stalled until another endpoint RX completion interrupt arrives? > + > + atomic_set(&endpoint->replenish_active, 0); > + > if (add_one) > atomic_inc(&endpoint->replenish_backlog); > > return; > > try_again_later: > + atomic_set(&endpoint->replenish_active, 0); > + > /* The last one didn't succeed, so fix the backlog */ > delta = add_one ? 2 : 1; > backlog = atomic_add_return(delta, &endpoint->replenish_backlog); > @@ -1691,6 +1703,7 @@ static void ipa_endpoint_setup_one(struct ipa_endpoint *endpoint) > * backlog is the same as the maximum outstanding TREs. > */ > endpoint->replenish_enabled = false; > + atomic_set(&endpoint->replenish_active, 0); > atomic_set(&endpoint->replenish_saved, > gsi_channel_tre_max(gsi, endpoint->channel_id)); > atomic_set(&endpoint->replenish_backlog, 0); > diff --git a/drivers/net/ipa/ipa_endpoint.h b/drivers/net/ipa/ipa_endpoint.h > index 0a859d10312dc..200f093214997 100644 > --- a/drivers/net/ipa/ipa_endpoint.h > +++ b/drivers/net/ipa/ipa_endpoint.h > @@ -53,6 +53,7 @@ enum ipa_endpoint_name { > * @netdev: Network device pointer, if endpoint uses one > * @replenish_enabled: Whether receive buffer replenishing is enabled > * @replenish_ready: Number of replenish transactions without doorbell > + * @replenish_active: 1 when replenishing is active, 0 otherwise > * @replenish_saved: Replenish requests held while disabled > * @replenish_backlog: Number of buffers needed to fill hardware queue > * @replenish_work: Work item used for repeated replenish failures > @@ -74,6 +75,7 @@ struct ipa_endpoint { > /* Receive buffer replenishing for RX endpoints */ > bool replenish_enabled; > u32 replenish_ready; > + atomic_t replenish_active; > atomic_t replenish_saved; > atomic_t replenish_backlog; > struct delayed_work replenish_work; /* global wq */ > -- > 2.32.0 >