summaryrefslogtreecommitdiff
path: root/drivers/staging/greybus/interface.c
diff options
context:
space:
mode:
authorDavid Lin <dtwlin@google.com>2016-08-02 15:34:46 -0700
committerGreg Kroah-Hartman <gregkh@google.com>2016-08-03 10:52:20 +0200
commitea2ff95ab4e178559e63b1ab5a174dd4dd6b4019 (patch)
tree800daacf6cef6731ecd11fc94a042cedfe01a510 /drivers/staging/greybus/interface.c
parentc0219cbf72418d5355e319a0d787dc2671df9d4f (diff)
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] [<ffffffc000207b40>] dump_backtrace+0x0/0x268 [ 1623.681272] [<ffffffc000207db8>] show_stack+0x10/0x1c [ 1623.681284] [<ffffffc000ccb890>] dump_stack+0x1c/0x28 [ 1623.681295] [<ffffffc00021f9dc>] warn_slowpath_common+0x74/0x9c [ 1623.681301] [<ffffffc00021fa60>] warn_slowpath_fmt+0x5c/0x80 [ 1623.681307] [<ffffffc000366624>] sysfs_add_one+0x94/0xb4 [ 1623.681315] [<ffffffc0003670b4>] sysfs_do_create_link_sd+0x100/0x1c8 [ 1623.681320] [<ffffffc0003671a8>] sysfs_create_link+0x2c/0x38 [ 1623.681332] [<ffffffc0005d5890>] bus_add_device+0xd8/0x190 [ 1623.681338] [<ffffffc0005d39ec>] device_add+0x2b4/0x604 [ 1623.681349] [<ffffffbffc006dfc>] gb_control_add+0x10/0x40 [greybus] [ 1623.681362] [<ffffffbffc003dac>] gb_interface_enable+0x20c/0x3b8 [greybus] [ 1623.681373] [<ffffffbffc002a30>] gb_module_add+0x124/0x174 [greybus] [ 1623.681385] [<ffffffbffc0082cc>] gb_svc_intf_set_power_mode+0xdd4/0xfe8 [greybus] [ 1623.681394] [<ffffffc00023888c>] process_one_work+0x268/0x3c8 [ 1623.681400] [<ffffffc000239a64>] worker_thread+0x204/0x358 [ 1623.681410] [<ffffffc00023f43c>] 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 <dtwlin@google.com> Reviewed-by: Johan Hovold <johan@hovoldconsulting.com> Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org> Reviewed-by: Jeffrey Carlyle <jcarlyle@google.com> Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/interface.c')
-rw-r--r--drivers/staging/greybus/interface.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c
index 19f5c71e078d..76569f8b086e 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);