Received: by 2002:a05:7412:798b:b0:fc:a2b0:25d7 with SMTP id fb11csp364752rdb; Thu, 22 Feb 2024 06:16:00 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCX2wQmkdrMG2OiOoXjmo7Z977NoL/OOpLUctD3ZOpr3yc61F6Cx8oYMefqoDakg3fZTAdtnN7+kV3/Zb9pNvTsxt1kC4kSUHycFtqC0ig== X-Google-Smtp-Source: AGHT+IER4W7ZN5a3+ykO7XfPRBTLgQaVgq5ClC85gBPohTAIPPQXx6To9rHuvlKbXtpK11Uq8BxJ X-Received: by 2002:a05:6602:2148:b0:7c7:760f:56c5 with SMTP id y8-20020a056602214800b007c7760f56c5mr4567342ioy.3.1708611360510; Thu, 22 Feb 2024 06:16:00 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708611360; cv=pass; d=google.com; s=arc-20160816; b=nI3HwDYmNRovDpFf+r6bVUnxUo8Ni6jzRb4zxX8tK5vkLOsyIjDEpZ5qIJNonuQEo7 lYfrp0b+xVwaE414Lf2coydYqyTZsrpG8VgRvZdzQNlDc01NYpkduWmnc4FqHPolFlr1 2XxiDzCjWN3ZIrOnRuwx/67Qqm1sgUhpnfhin45rloWmd1Eg1UsMMjzWNP0BZ4bH+RIh E6FseRiLyWSYdzGbw7ZZ/GNUSMR05t++sMX7KTZ0RCHcqSedrRzo57rPyblje1GKiHZL nOg58zwx2HLpzw85Am+/IVtdipaywZ2IHx/o9UgnlblF8nyMKOGJt5i/M4sYRtilu7u7 nDdQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:message-id:date:references :in-reply-to:subject:cc:to:from:dkim-signature; bh=CDJnUwBqaevKbMRbeYdVKkzK/bJdGi07s0xL4z9TrZE=; fh=mNdg52fuhQsqZWDSZieH+XyLeVfIrdtu+I/xof3LTzc=; b=YHtnFMqP7mMY5fEc7bt/4SrTW1cnUuy2rQ52NYwQI/bX0ceyvBLNSwUoZnvek+EAdE qD7sqyvzkdNioZoyT4+NhxxfQrUkwFdu0aLk6yVoevaE4TqAtOk7hfyW7CSbBuKitqj4 BNXWvHiU3SeBl1hKZba2LCLTuqlAbkH829bsj6pHZoRgz5R7uSHv+XzrI2feZKiTQPK8 XDiM41HBS16jO2+ZkNqIp/z7AHaH+uGXUpORWfXwEqORBgwqZKxSgfP17w6s4IdXykbs 1noTP+JCKSBBRWaYAbC4lrQpG277b6xaz7BvX3MWckh79TQx92ZbYcZ5JtbCw0fw8w1S ZzZw==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=iVKuLGwp; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-76678-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-76678-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id dx11-20020a0566381d0b00b004741d59093bsi3401691jab.167.2024.02.22.06.16.00 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 Feb 2024 06:16:00 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-76678-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=iVKuLGwp; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-76678-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-76678-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id 4D9C62833D6 for ; Thu, 22 Feb 2024 14:15:37 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4BDF414601D; Thu, 22 Feb 2024 14:15:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iVKuLGwp" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3642712FB02; Thu, 22 Feb 2024 14:15:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708611327; cv=none; b=lgvl3dVJcNWn8GYuEplzlg41+U1GeFGTtb94AIu8BTmcYNCDShdSuaQ4r4nTlNrjSwgPcmKU7pnD8Qspw+IuICmz34PgwYEArUMrKgGl6DOlR0DlksfEsb2sxyUKQwRpwV5q1jDqw8bDOGrNms25Az6yzV25lwmsP0rYbUITeIQ= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708611327; c=relaxed/simple; bh=kIZczWHR5/Nc3nYCAWYzUjsydPY/1nsM6oO6gbmZSHw=; h=From:To:Cc:Subject:In-Reply-To:References:Date:Message-ID: MIME-Version:Content-Type; b=NQco+sQ5IH9sMEfELuEmtPe1OqwEkDdt5QH+Pbm8PfA9OcBDLIhL6B4WR8dhb9CIb+J4SeADdcd9h8PallXVhv06cxQLaIH6LZSESXmTcGoV1Nlx2KY0eHW2J+njQmzwHgQr+Jfer/fSIsK18bseRxA6h9sta7SA/KNradKvO3s= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iVKuLGwp; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 790F7C433F1; Thu, 22 Feb 2024 14:15:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1708611327; bh=kIZczWHR5/Nc3nYCAWYzUjsydPY/1nsM6oO6gbmZSHw=; h=From:To:Cc:Subject:In-Reply-To:References:Date:From; b=iVKuLGwp5DCor24xZgAAwTwbovowF/3KA6uXFHUuiRANLfpMQdn8lzSu93BRzigiF zQHiyJFhIJro3MAq5tOfWq/PdEmtCHZZ+2lIbaH291kiNdNCwJAuWyOVyUzn48AKdc sBtesUDmENKKh6ghBZQEal9sTLzLaEa0V0LVK8xWlCf9+fdjB44brVSGFaRDcwKWl2 KYPJlnO+cZngbU8tJUTJGgHY8aMRqruGi/jkJePAdeXaBjTpOEQ8QKEolQpNV2cJUE 1awqBYW+WNH8BPC74erA05naYUY5MwNXzi7Xvw2/Zg0o8i9mkE9CjZXj9zA34AS3YD HIUl+FnTPD8PA== From: =?utf-8?B?QmrDtnJuIFTDtnBlbA==?= To: Anup Patel Cc: Anup Patel , Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Rob Herring , Krzysztof Kozlowski , Frank Rowand , Conor Dooley , devicetree@vger.kernel.org, Saravana Kannan , Marc Zyngier , linux-kernel@vger.kernel.org, Atish Patra , linux-riscv@lists.infradead.org, linux-arm-kernel@lists.infradead.org, Andrew Jones Subject: Re: [PATCH v14 11/18] irqchip: Add RISC-V incoming MSI controller early driver In-Reply-To: References: <20240222094006.1030709-1-apatel@ventanamicro.com> <20240222094006.1030709-12-apatel@ventanamicro.com> <87r0h4tzeq.fsf@all.your.base.are.belong.to.us> Date: Thu, 22 Feb 2024 15:15:24 +0100 Message-ID: <874je0twjn.fsf@all.your.base.are.belong.to.us> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Anup Patel writes: > On Thu, Feb 22, 2024 at 6:43=E2=80=AFPM Bj=C3=B6rn T=C3=B6pel wrote: >> >> Anup Patel writes: >> >> > diff --git a/drivers/irqchip/irq-riscv-imsic-state.c b/drivers/irqchip= /irq-riscv-imsic-state.c >> > new file mode 100644 >> > index 000000000000..0c19ffb9ca3e >> > --- /dev/null >> > +++ b/drivers/irqchip/irq-riscv-imsic-state.c >> > @@ -0,0 +1,870 @@ >> >> [...] >> >> > +static void __imsic_local_sync(struct imsic_local_priv *lpriv) >> > +{ >> > + struct imsic_local_config *mlocal; >> > + struct imsic_vector *vec, *mvec; >> > + int i; >> > + >> > + lockdep_assert_held(&lpriv->lock); >> > + >> > + /* This pairs with the barrier in __imsic_remote_sync(). */ >> > + smp_mb(); >> >> I'm trying to figure out why this barrier is needed? All the updates are >> done behind the spinlocks. If there're some ordering constraints that >> I'm missing, please document them. >> >> > + >> > + for_each_set_bit(i, lpriv->dirty_bitmap, imsic->global.nr_ids + = 1) { >> > + if (!i || i =3D=3D IMSIC_IPI_ID) >> > + goto skip; >> > + vec =3D &lpriv->vectors[i]; >> > + >> > + if (READ_ONCE(vec->enable)) >> > + __imsic_id_set_enable(i); >> > + else >> > + __imsic_id_clear_enable(i); >> > + >> > + /* >> > + * If the ID was being moved to a new ID on some other C= PU >> > + * then we can get a MSI during the movement so check the >> > + * ID pending bit and re-trigger the new ID on other CPU >> > + * using MMIO write. >> > + */ >> > + mvec =3D READ_ONCE(vec->move); >> > + WRITE_ONCE(vec->move, NULL); >> >> mvec =3D xchg(&vec->move, NULL) ? > > The __imsic_local_sync() is called with spinlock held. Yeah, this was a readability comment. >> > + if (mvec && mvec !=3D vec) { >> > + if (__imsic_id_read_clear_pending(i)) { >> > + mlocal =3D per_cpu_ptr(imsic->global.loc= al, mvec->cpu); >> > + writel_relaxed(mvec->local_id, mlocal->m= si_va); >> > + } >> > + >> > + imsic_vector_free(&lpriv->vectors[i]); >> > + } >> > + >> > +skip: >> > + bitmap_clear(lpriv->dirty_bitmap, i, 1); >> > + } >> > +} >> > + >> > +void imsic_local_sync_all(void) >> > +{ >> > + struct imsic_local_priv *lpriv =3D this_cpu_ptr(imsic->lpriv); >> > + unsigned long flags; >> > + >> > + raw_spin_lock_irqsave(&lpriv->lock, flags); >> > + bitmap_fill(lpriv->dirty_bitmap, imsic->global.nr_ids + 1); >> > + __imsic_local_sync(lpriv); >> > + raw_spin_unlock_irqrestore(&lpriv->lock, flags); >> > +} >> > + >> > +void imsic_local_delivery(bool enable) >> > +{ >> > + if (enable) { >> > + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_ENABLE_EITHRESH= OLD); >> > + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_ENABLE_EIDELIVER= Y); >> > + return; >> > + } >> > + >> > + imsic_csr_write(IMSIC_EIDELIVERY, IMSIC_DISABLE_EIDELIVERY); >> > + imsic_csr_write(IMSIC_EITHRESHOLD, IMSIC_DISABLE_EITHRESHOLD); >> > +} >> > + >> > +#ifdef CONFIG_SMP >> > +static void imsic_local_timer_callback(struct timer_list *timer) >> > +{ >> > + struct imsic_local_priv *lpriv =3D this_cpu_ptr(imsic->lpriv); >> > + unsigned long flags; >> > + >> > + raw_spin_lock_irqsave(&lpriv->lock, flags); >> > + __imsic_local_sync(lpriv); >> > + raw_spin_unlock_irqrestore(&lpriv->lock, flags); >> > +} >> > + >> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsig= ned int cpu) >> > +{ >> > + lockdep_assert_held(&lpriv->lock); >> > + >> > + /* >> > + * Ensure that changes to vector enable, vector move and >> > + * dirty bitmap are visible to the target CPU. >> >> ...which case the spinlock(s) are enough, no? > > spinlocks are not fences. They are indeed, and it would be hard to use them as locks otherwise (acq/rel -- good ol' Documentation/memory-barriers.txt). > If the timer wheel on the target cpu is already running and we don't > have a fence here then the target cpu might not see the changes > done by this cpu. Remove the smp_mb() pair, the spinlocks are enough for this scenario! >> > + * >> > + * This pairs with the barrier in __imsic_local_sync(). >> > + */ >> > + smp_mb(); >> > + >> > + /* >> > + * We schedule a timer on the target CPU if the target CPU is not >> > + * same as the current CPU. An offline CPU will unconditionally >> > + * synchronize IDs through imsic_starting_cpu() when the >> > + * CPU is brought up. >> > + */ >> > + if (cpu_online(cpu)) { >> > + if (cpu =3D=3D smp_processor_id()) { >> > + __imsic_local_sync(lpriv); >> > + return; >> > + } >> >> Maybe move this if-clause out from the cpu_online(), and only have >> something like >> if (cpu_online(cpu) && !timer_pending(&lpriv->timer)) { ... } >> inside the CONFIG_SMP guard... >> >> > + >> > + if (!timer_pending(&lpriv->timer)) { >> > + lpriv->timer.expires =3D jiffies + 1; >> > + add_timer_on(&lpriv->timer, cpu); >> > + } >> > + } >> > +} >> > +#else >> > +static void __imsic_remote_sync(struct imsic_local_priv *lpriv, unsig= ned int cpu) >> > +{ >> > + lockdep_assert_held(&lpriv->lock); >> > + __imsic_local_sync(lpriv); >> > +} >> > +#endif >> >> ...where we can get rid of this special !SMP all together for this >> function. > > I failed to understand what is wrong the current code. Oh, nothing is wrong. Just trying to get rid of some ifdeffery. >> > +void imsic_vector_mask(struct imsic_vector *vec) >> > +{ >> > + struct imsic_local_priv *lpriv; >> > + >> > + lpriv =3D per_cpu_ptr(imsic->lpriv, vec->cpu); >> > + if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] !=3D vec)) >> > + return; >> > + >> > + /* >> > + * This function is called through Linux irq subsystem with >> > + * irqs disabled so no need to save/restore irq flags. >> > + */ >> > + >> > + raw_spin_lock(&lpriv->lock); >> > + >> > + vec->enable =3D false; >> >> Should have WRITE_ONCE to make the checkers happy. > > Okay, I will update. > >> >> > + bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1); >> > + __imsic_remote_sync(lpriv, vec->cpu); >> > + >> > + raw_spin_unlock(&lpriv->lock); >> > +} >> > + >> > +void imsic_vector_unmask(struct imsic_vector *vec) >> > +{ >> > + struct imsic_local_priv *lpriv; >> > + >> > + lpriv =3D per_cpu_ptr(imsic->lpriv, vec->cpu); >> > + if (WARN_ON_ONCE(&lpriv->vectors[vec->local_id] !=3D vec)) >> > + return; >> > + >> > + /* >> > + * This function is called through Linux irq subsystem with >> > + * irqs disabled so no need to save/restore irq flags. >> > + */ >> > + >> > + raw_spin_lock(&lpriv->lock); >> > + >> > + vec->enable =3D true; >> >> Dito. > > Okay, I will update. > >> >> > + bitmap_set(lpriv->dirty_bitmap, vec->local_id, 1); >> > + __imsic_remote_sync(lpriv, vec->cpu); >> > + >> > + raw_spin_unlock(&lpriv->lock); >> > +} >> > + >> > +static bool imsic_vector_move_update(struct imsic_local_priv *lpriv, = struct imsic_vector *vec, >> > + bool new_enable, struct imsic_vecto= r *new_move) >> > +{ >> > + unsigned long flags; >> > + bool enabled; >> > + >> > + raw_spin_lock_irqsave(&lpriv->lock, flags); >> > + >> > + /* Update enable and move details */ >> > + enabled =3D READ_ONCE(vec->enable); >> > + WRITE_ONCE(vec->enable, new_enable); >> >> Again, xchg() would be easier to read. > > why ? spinlock is not enough? They're enough! Just readbaility/personal taste. I'm running tests for this series now! Would be awesome to have the series land for 6.9! Cheers, Bj=C3=B6rn