Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipmi: Disable some operations during a panic

Don't do kfree or other risky things when oops_in_progress is set.
It's easy enough to avoid doing them

Signed-off-by: Corey Minyard <cminyard@mvista.com>

+19 -8
+7 -3
drivers/char/ipmi/ipmi_msghandler.c
··· 4789 4789 static void free_smi_msg(struct ipmi_smi_msg *msg) 4790 4790 { 4791 4791 atomic_dec(&smi_msg_inuse_count); 4792 - kfree(msg); 4792 + /* Try to keep as much stuff out of the panic path as possible. */ 4793 + if (!oops_in_progress) 4794 + kfree(msg); 4793 4795 } 4794 4796 4795 4797 struct ipmi_smi_msg *ipmi_alloc_smi_msg(void) ··· 4810 4808 static void free_recv_msg(struct ipmi_recv_msg *msg) 4811 4809 { 4812 4810 atomic_dec(&recv_msg_inuse_count); 4813 - kfree(msg); 4811 + /* Try to keep as much stuff out of the panic path as possible. */ 4812 + if (!oops_in_progress) 4813 + kfree(msg); 4814 4814 } 4815 4815 4816 4816 static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void) ··· 4830 4826 4831 4827 void ipmi_free_recv_msg(struct ipmi_recv_msg *msg) 4832 4828 { 4833 - if (msg->user) 4829 + if (msg->user && !oops_in_progress) 4834 4830 kref_put(&msg->user->refcount, free_user); 4835 4831 msg->done(msg); 4836 4832 }
+12 -5
drivers/char/ipmi/ipmi_watchdog.c
··· 342 342 static DECLARE_COMPLETION(msg_wait); 343 343 static void msg_free_smi(struct ipmi_smi_msg *msg) 344 344 { 345 - if (atomic_dec_and_test(&msg_tofree)) 346 - complete(&msg_wait); 345 + if (atomic_dec_and_test(&msg_tofree)) { 346 + if (!oops_in_progress) 347 + complete(&msg_wait); 348 + } 347 349 } 348 350 static void msg_free_recv(struct ipmi_recv_msg *msg) 349 351 { 350 - if (atomic_dec_and_test(&msg_tofree)) 351 - complete(&msg_wait); 352 + if (atomic_dec_and_test(&msg_tofree)) { 353 + if (!oops_in_progress) 354 + complete(&msg_wait); 355 + } 352 356 } 353 357 static struct ipmi_smi_msg smi_msg = { 354 358 .done = msg_free_smi ··· 438 434 rv = __ipmi_set_timeout(&smi_msg, 439 435 &recv_msg, 440 436 &send_heartbeat_now); 441 - if (rv) 437 + if (rv) { 438 + atomic_set(&msg_tofree, 0); 442 439 return rv; 440 + } 443 441 444 442 wait_for_completion(&msg_wait); 445 443 ··· 586 580 &recv_msg, 587 581 1); 588 582 if (rv) { 583 + atomic_set(&msg_tofree, 0); 589 584 pr_warn("heartbeat send failure: %d\n", rv); 590 585 return rv; 591 586 }