Re: Issue with panic handling and ipmi

From: Corey Minyard
Date: Thu Sep 16 2021 - 14:11:50 EST


On Thu, Sep 16, 2021 at 04:53:00PM +0200, Anton Lundin wrote:
> Hi.
>
> I've just done a upgrade of the kernel we're using in a product from
> 4.19 to 5.10 and I noted a issue.
>
> It started that with that we didn't get panic and oops dumps in our erst
> backed pstore, and when debugging that I noted that the reboot on panic
> timer didn't work either.
>
> I've bisected it down to 2033f6858970 ("ipmi: Free receive messages when
> in an oops").

Hmm. Unfortunately removing that will break other things. Can you try
the following patch? It's a good idea, in general, to do as little as
possible in the panic path, this should cover a multitude of issues.

Thanks for the report.

-corey

>
> I tested just reverting that and both dumps to pstore and the panic
> reboot timer started working again.
>
>
> //Anton

commit e28aa211190b7d3a1135f051f0c30b0195016489
Author: Corey Minyard <cminyard@xxxxxxxxxx>
Date: Thu Sep 16 11:36:20 2021 -0500

ipmi: Disable some operations during a panic

Don't do kfree or other risky things when oops_in_progress is set.

Reported-by: Anton Lundin <glance@xxxxxxxxxx>
Fixes: 2033f6858970 ("ipmi: Free receive messages when > in an oops")
Signed-off-by: Corey Minyard <cminyard@xxxxxxxxxx>

diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index e96cb5c4f97a..a08f53f208bf 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -4789,7 +4789,9 @@ static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
static void free_smi_msg(struct ipmi_smi_msg *msg)
{
atomic_dec(&smi_msg_inuse_count);
- kfree(msg);
+ /* Try to keep as much stuff out of the panic path as possible. */
+ if (!oops_in_progress)
+ kfree(msg);
}

struct ipmi_smi_msg *ipmi_alloc_smi_msg(void)
@@ -4808,7 +4810,9 @@ EXPORT_SYMBOL(ipmi_alloc_smi_msg);
static void free_recv_msg(struct ipmi_recv_msg *msg)
{
atomic_dec(&recv_msg_inuse_count);
- kfree(msg);
+ /* Try to keep as much stuff out of the panic path as possible. */
+ if (!oops_in_progress)
+ kfree(msg);
}

static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
@@ -4826,7 +4830,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)

void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
{
- if (msg->user)
+ if (msg->user && !oops_in_progress)
kref_put(&msg->user->refcount, free_user);
msg->done(msg);
}