From 56480287f9776adc5b1a7a335ef62a9b9879ad7f Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 29 Jun 2010 15:05:29 -0700 Subject: ipmi: make sure drivers were registered before unregistering them The ipmi code will never register a PCI or Open Firmware driver if a hardcoded device is provided by the user by providing device addresses via the module parameters. This can cause us to attempt to unregister a driver that was never registered, resulting in an oops. Keep track of registration in order to avoid this. Fixes a post-2.6.34 regression. Signed-off-by: Matthew Garrett Acked-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'drivers/char/ipmi/ipmi_si_intf.c') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 35603dd4e6c..311f85b67cc 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -302,6 +302,12 @@ struct smi_info { static int force_kipmid[SI_MAX_PARMS]; static int num_force_kipmid; +#ifdef CONFIG_PCI +static int pci_registered; +#endif +#ifdef CONFIG_PPC_OF +static int of_registered; +#endif static unsigned int kipmid_max_busy_us[SI_MAX_PARMS]; static int num_max_busy_us; @@ -3314,6 +3320,8 @@ static __devinit int init_ipmi_si(void) rv = pci_register_driver(&ipmi_pci_driver); if (rv) printk(KERN_ERR PFX "Unable to register PCI driver: %d\n", rv); + else + pci_registered = 1; #endif #ifdef CONFIG_ACPI @@ -3330,6 +3338,7 @@ static __devinit int init_ipmi_si(void) #ifdef CONFIG_PPC_OF of_register_platform_driver(&ipmi_of_platform_driver); + of_registered = 1; #endif /* We prefer devices with interrupts, but in the case of a machine @@ -3383,11 +3392,13 @@ static __devinit int init_ipmi_si(void) if (unload_when_empty && list_empty(&smi_infos)) { mutex_unlock(&smi_infos_lock); #ifdef CONFIG_PCI - pci_unregister_driver(&ipmi_pci_driver); + if (pci_registered) + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&ipmi_of_platform_driver); + if (of_registered) + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif driver_unregister(&ipmi_driver.driver); printk(KERN_WARNING PFX @@ -3478,14 +3489,16 @@ static __exit void cleanup_ipmi_si(void) return; #ifdef CONFIG_PCI - pci_unregister_driver(&ipmi_pci_driver); + if (pci_registered) + pci_unregister_driver(&ipmi_pci_driver); #endif #ifdef CONFIG_ACPI pnp_unregister_driver(&ipmi_pnp_driver); #endif #ifdef CONFIG_PPC_OF - of_unregister_platform_driver(&ipmi_of_platform_driver); + if (of_registered) + of_unregister_platform_driver(&ipmi_of_platform_driver); #endif mutex_lock(&smi_infos_lock); -- cgit v1.2.3-70-g09d2 From 8d1f66dc9b4f80a1441bc1c33efa98aca99e8813 Mon Sep 17 00:00:00 2001 From: Martin Wilck Date: Tue, 29 Jun 2010 15:05:31 -0700 Subject: ipmi: set schedule_timeout_wait() value back to one Fix a regression introduced by ae74e823cb7d ("ipmi: add parameter to limit CPU usage in kipmid"). Some systems were seeing CPU usage go up dramatically with the recent changes to try to reduce timer usage in the IPMI driver. This was traced down to schedule_timeout_interruptible(1) being changed to schedule_timeout_interruptbile(0). Revert that part of the change. Addresses https://bugzilla.kernel.org/show_bug.cgi?id=16147 Reported-by: Thomas Jarosch Signed-off-by: Corey Minyard Tested-by: Thomas Jarosch Cc: [2.6.34.x] Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/char/ipmi/ipmi_si_intf.c') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 311f85b67cc..094bdc355b1 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -1024,7 +1024,7 @@ static int ipmi_thread(void *data) else if (smi_result == SI_SM_IDLE) schedule_timeout_interruptible(100); else - schedule_timeout_interruptible(0); + schedule_timeout_interruptible(1); } return 0; } -- cgit v1.2.3-70-g09d2