ipmi: Clear drvdata when interface is removed
This patch fixes a bug on hotmod removing. After ipmi interface is removed using hotmod, kernel panic occurs when rmmod impi_si. For example, try this: # echo "remove,"`cat /proc/ipmi/0/params` > \ /sys/module/ipmi_si/parameters/hotmod # rmmod ipmi_si Then, rmmod fails with the following messages. ------------[ cut here ]------------ WARNING: CPU: 12 PID: 10819 at /mnt/repos/linux/lib/list_debug.c:53 __list_del_entry+0x63/0xd0() CPU: 12 PID: 10819 Comm: rmmod Not tainted 3.17.0-rc1 #19 Hardware name: FUJITSU-SV PRIMERGY BX920 S2/D3030, BIOS 080015 Rev.3D81.3030 02/10/2012 Call Trace: dump_stack+0x45/0x56 warn_slowpath_common+0x7d/0xa0 warn_slowpath_fmt+0x4c/0x50 __list_del_entry+0x63/0xd0 list_del+0xd/0x30 cleanup_one_si+0x2a/0x230 [ipmi_si] ipmi_pnp_remove+0x15/0x20 [ipmi_si] pnp_device_remove+0x24/0x40 __device_release_driver+0x7f/0xf0 driver_detach+0xb0/0xc0 bus_remove_driver+0x55/0xd0 driver_unregister+0x2c/0x50 pnp_unregister_driver+0x12/0x20 cleanup_ipmi_si+0xbc/0xf0 [ipmi_si] SyS_delete_module+0x132/0x1c0 system_call_fastpath+0x16/0x1b ---[ end trace 70b4377268f85c23 ]--- list_del in cleanup_one_si() fails because the smi_info is already removed when hotmod removing. When ipmi interface is removed by hotmod, smi_info is removed by cleanup_one_si(), but is is still set in drvdata. Therefore when rmmod ipmi_si, ipmi_pnp_remove tries to remove it again and fails. By this patch, a pointer to smi_info in drvdata is cleared when hotmod removing so that it will be not accessed when rmmod. changelog: v2: - Clear drvdata in cleanup_one_si - Change subject v1: https://lkml.org/lkml/2014/9/8/741 Signed-off-by: Takao Indoh <indou.takao@jp.fujitsu.com> Signed-off-by: Corey Minyard <cminyard@mvista.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
cc4cbe9011
commit
567eded965
1 changed files with 3 additions and 0 deletions
|
@ -3658,6 +3658,9 @@ static void cleanup_one_si(struct smi_info *to_clean)
|
|||
if (!to_clean)
|
||||
return;
|
||||
|
||||
if (to_clean->dev)
|
||||
dev_set_drvdata(to_clean->dev, NULL);
|
||||
|
||||
list_del(&to_clean->link);
|
||||
|
||||
/* Tell the driver that we are shutting down. */
|
||||
|
|
Loading…
Reference in a new issue