From ea2ff95ab4e178559e63b1ab5a174dd4dd6b4019 Mon Sep 17 00:00:00 2001 From: David Lin Date: Tue, 2 Aug 2016 15:34:46 -0700 Subject: [PATCH] greybus: interface: delete control device upon enable failure There is an issue that when an interface failed to be enabled due to timesync failure, a previously added control device is not deleted as part of the error clean-up. This causes a leak in the sysfs file when the interface is disabled. This would eventually cause this particular interface to be unable to register future control device even after unipro_reset. See failure logs below: [ 906.495261] greybus 1-3.3: failed to add to timesync: -19 [ 906.516497] greybus 1-3.3: failed to re-enable interface: -19 [ 907.016016] greybus 1-3.3: Interface removed ... [ 1623.677343] ------------[ cut here ]------------ [ 1623.681116] WARNING: at kernel/arche/fs/sysfs/dir.c:530 sysfs_add_one+0x98/0xb4() [ 1623.681128] sysfs: cannot create duplicate filename '/bus/greybus/devices/1-3.3.ctrl' [ 1623.681252] Call trace: [ 1623.681265] [] dump_backtrace+0x0/0x268 [ 1623.681272] [] show_stack+0x10/0x1c [ 1623.681284] [] dump_stack+0x1c/0x28 [ 1623.681295] [] warn_slowpath_common+0x74/0x9c [ 1623.681301] [] warn_slowpath_fmt+0x5c/0x80 [ 1623.681307] [] sysfs_add_one+0x94/0xb4 [ 1623.681315] [] sysfs_do_create_link_sd+0x100/0x1c8 [ 1623.681320] [] sysfs_create_link+0x2c/0x38 [ 1623.681332] [] bus_add_device+0xd8/0x190 [ 1623.681338] [] device_add+0x2b4/0x604 [ 1623.681349] [] gb_control_add+0x10/0x40 [greybus] [ 1623.681362] [] gb_interface_enable+0x20c/0x3b8 [greybus] [ 1623.681373] [] gb_module_add+0x124/0x174 [greybus] [ 1623.681385] [] gb_svc_intf_set_power_mode+0xdd4/0xfe8 [greybus] [ 1623.681394] [] process_one_work+0x268/0x3c8 [ 1623.681400] [] worker_thread+0x204/0x358 [ 1623.681410] [] kthread+0xb8/0xc4 [ 1623.681414] ---[ end trace 44489577dd9220db ]--- [ 1623.681818] greybus 1-3.3.ctrl: failed to register control device: -17 Testing Done: - Continuous unipro_reset stress test Signed-off-by: David Lin Reviewed-by: Johan Hovold Reviewed-by: Viresh Kumar Reviewed-by: Jeffrey Carlyle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/interface.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index 19f5c71..76569f8 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -1160,7 +1160,7 @@ int gb_interface_enable(struct gb_interface *intf) ret = gb_timesync_interface_add(intf); if (ret) { dev_err(&intf->dev, "failed to add to timesync: %d\n", ret); - goto err_destroy_bundles; + goto err_del_control; } pm_runtime_use_autosuspend(&intf->dev); @@ -1186,6 +1186,8 @@ int gb_interface_enable(struct gb_interface *intf) return 0; +err_del_control: + gb_control_del(intf->control); err_destroy_bundles: list_for_each_entry_safe(bundle, tmp, &intf->bundles, links) gb_bundle_destroy(bundle); -- 2.7.4