On Tue, Jul 05, 2022 at 11:02:10PM -0700, Chris Lew wrote: > There is a very tight race where the irq_retrigger function is run > on one cpu and the actual retrigger softirq is running on a second > cpu. When this happens, there may be a chance that the second cpu > will not see the updated irq_pending value from first cpu. > > Add a memory barrier to ensure that irq_pending is read correctly. > > Signed-off-by: Chris Lew <quic_clew@xxxxxxxxxxx> > --- > drivers/soc/qcom/smp2p.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c > index a94cddcb0298..a1ea5f55c228 100644 > --- a/drivers/soc/qcom/smp2p.c > +++ b/drivers/soc/qcom/smp2p.c > @@ -249,6 +249,9 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) > > status = val ^ entry->last_value; > entry->last_value = val; > + > + /* Ensure irq_pending is read correctly */ > + mb(); I don't quite understand why you need a barrier here. mb() makes sure all the prior instructions gets executed before executing the later one. But why is it needed here? > status |= *entry->irq_pending; > > /* No changes of this entry? */ > @@ -356,6 +359,11 @@ static int smp2p_retrigger_irq(struct irq_data *irqd) > > set_bit(irq, entry->irq_pending); > > + /* Ensure irq_pending is visible to all cpus that retried interrupt > + * can run on > + */ > + mb(); > + Here it makes sense because you want the CPU to set irq_pending before exiting from this function. But even then you can use the less strict smp_wmb() that serves the exact purpose. Thanks, Mani > return 0; > } > > -- > 2.7.4 > -- மணிவண்ணன் சதாசிவம்