On 01/09/2022 15:28, Greg KH wrote: > [...] >> I honestly didn't understand exactly what you're suggesting Greg... >> Mind clarifying? > > Something like this totally untested code: > > diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c > index adaa492c3d2d..6ad41b22671c 100644 > --- a/drivers/firmware/google/gsmi.c > +++ b/drivers/firmware/google/gsmi.c > @@ -19,6 +19,7 @@ > #include <linux/dma-mapping.h> > #include <linux/fs.h> > #include <linux/slab.h> > +#include <linux/panic.h> > #include <linux/panic_notifier.h> > #include <linux/ioctl.h> > #include <linux/acpi.h> > @@ -611,6 +612,11 @@ static const struct attribute *gsmi_attrs[] = { > NULL, > }; > > +static bool panic_in_progress(void) > +{ > + return unlikely(atomic_read(&panic_cpu) != PANIC_CPU_INVALID); > +} > + > static int gsmi_shutdown_reason(int reason) > { > struct gsmi_log_entry_type_1 entry = { > @@ -629,7 +635,8 @@ static int gsmi_shutdown_reason(int reason) > if (saved_reason & (1 << reason)) > return 0; > > - spin_lock_irqsave(&gsmi_dev.lock, flags); > + if (!panic_in_progress()) > + spin_lock_irqsave(&gsmi_dev.lock, flags); > > saved_reason |= (1 << reason); > > @@ -644,7 +651,8 @@ static int gsmi_shutdown_reason(int reason) > > rc = gsmi_exec(GSMI_CALLBACK, GSMI_CMD_SET_EVENT_LOG); > > - spin_unlock_irqrestore(&gsmi_dev.lock, flags); > + if (!panic_in_progress()) > + spin_unlock_irqrestore(&gsmi_dev.lock, flags); > > if (rc < 0) > printk(KERN_ERR "gsmi: Log Shutdown Reason failed\n"); > > > Thanks! Personally, I feel the approach a bit more complex than mine, and...racy! Imagine CPU0 runs your tests, right after the if (!panic_in_progress()) is done, spinlock is taken and boom - panic on CPU1. This would cause the same issue... My approach is zero racy, since it checks if spinlock was taken in a moment that the machine is like a no-SMP, only a single CPU running... > That being said, are you sure spinlocks are still held in the panic > notifier? What about the call to bust_spinlocks() that is called in > panic() already? Wouldn't that have already dropped whatever you were > worried about here? This function is very weird. Basically, the call of "bust_spinlocks(1);" in panic effectively means "++oops_in_progress;" IIUC. So, I still think we can have lockups in panic notifiers with locks previously taken =) Cheers, Guilherme