qcacld-3.0: Register the netdev notifier before the netdevices
Applications in the userspace can sleep on the RTM events from the driver. One such application waiting of RTM_NEW_LINK indication does interface up as soon as it recieves the indication, so the kernel takes rtnl_lock to call the dev_open on the interface. Load/unload of the driver and dev_open of the interfaces are synchronized with hdd_init_deinit_lock. So the __hdd_open is waiting on the hdd_init_deinit_lock which is currently held by the driver loading context. After registering the interfaces driver goes to register the netdev notifier which is blocked on the rtnl_lock currently held by the dev_open resulting in deadlock. To mitigate the issue register the netdev notifier before the interfaces are registered. Change-Id: Ibb0c187a43ad87fa535ff583316af430e1ddf04f CRs-Fixed: 2078720
This commit is contained in:

gecommit door
snandini

bovenliggende
4b404333ca
commit
08479ba85b
3
Kbuild
3
Kbuild
@@ -1615,7 +1615,8 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \
|
||||
-DCONVERGED_P2P_ENABLE \
|
||||
-DWLAN_POLICY_MGR_ENABLE \
|
||||
-DSUPPORT_11AX \
|
||||
-DCONVERGED_TDLS_ENABLE
|
||||
-DCONVERGED_TDLS_ENABLE \
|
||||
-DCONFIG_HDD_INIT_WITH_RTNL_LOCK
|
||||
|
||||
|
||||
############ WIFI POS ##############
|
||||
|
@@ -5648,15 +5648,9 @@ static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = register_netdevice_notifier(&hdd_netdev_notifier);
|
||||
if (ret) {
|
||||
hdd_err("register_netdevice_notifier failed: %d", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = hdd_wlan_register_ip6_notifier(hdd_ctx);
|
||||
if (ret)
|
||||
goto unregister_notifier;
|
||||
goto out;
|
||||
|
||||
hdd_ctx->ipv4_notifier.notifier_call = wlan_hdd_ipv4_changed;
|
||||
ret = register_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
|
||||
@@ -5669,8 +5663,6 @@ static int hdd_register_notifiers(struct hdd_context *hdd_ctx)
|
||||
|
||||
unregister_ip6_notifier:
|
||||
hdd_wlan_unregister_ip6_notifier(hdd_ctx);
|
||||
unregister_notifier:
|
||||
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
||||
out:
|
||||
return ret;
|
||||
|
||||
@@ -5689,8 +5681,6 @@ void hdd_unregister_notifiers(struct hdd_context *hdd_ctx)
|
||||
hdd_wlan_unregister_ip6_notifier(hdd_ctx);
|
||||
|
||||
unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier);
|
||||
|
||||
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6024,6 +6014,8 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
|
||||
QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status));
|
||||
}
|
||||
|
||||
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
||||
|
||||
hdd_wlan_stop_modules(hdd_ctx, false);
|
||||
|
||||
qdf_spinlock_destroy(&hdd_ctx->hdd_adapter_lock);
|
||||
@@ -9758,6 +9750,10 @@ int hdd_wlan_startup(struct device *dev)
|
||||
|
||||
hdd_initialize_mac_address(hdd_ctx);
|
||||
|
||||
ret = hdd_register_notifiers(hdd_ctx);
|
||||
if (ret)
|
||||
goto err_ipa_cleanup;
|
||||
|
||||
rtnl_held = hdd_hold_rtnl_lock();
|
||||
|
||||
ret = hdd_open_interfaces(hdd_ctx, rtnl_held);
|
||||
@@ -9793,10 +9789,6 @@ int hdd_wlan_startup(struct device *dev)
|
||||
if (hdd_ctx->rps)
|
||||
hdd_set_rps_cpu_mask(hdd_ctx);
|
||||
|
||||
ret = hdd_register_notifiers(hdd_ctx);
|
||||
if (ret)
|
||||
goto err_close_adapters;
|
||||
|
||||
status = wlansap_global_init();
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto err_close_adapters;
|
||||
@@ -9873,6 +9865,7 @@ err_release_rtnl_lock:
|
||||
if (rtnl_held)
|
||||
hdd_release_rtnl_lock();
|
||||
|
||||
err_ipa_cleanup:
|
||||
hdd_ipa_cleanup(hdd_ctx);
|
||||
|
||||
err_wiphy_unregister:
|
||||
|
Verwijs in nieuw issue
Block a user