Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1df496e8 authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by Gerrit - the friendly Code Review server
Browse files

drivers: shs: fix deadlock caused between generic netlink and rtnl locks



Fix for a deadlock seen when trying to register the shs generic netlink family
inside of the callback context of rtnl_netlink. Instead of running in the
notifier's context, the generic netlink registration is moved to initialization
of the kernel module. Fixes the following lock contention scenario:

[ 3302.102281] Call trace:
[ 3302.102332] __switch_to+0x108/0x118
[ 3302.102357] __schedule+0x8fc/0xcd8
[ 3302.102368] schedule_preempt_disabled+0x7c/0xa8
[ 3302.102384] __mutex_lock+0x444/0x660
[ 3302.102392] __mutex_lock_slowpath+0x10/0x18
[ 3302.102399] mutex_lock+0x30/0x38 mutex_lock(&rtnl_mutex);
[ 3302.102422] rtnl_lock+0x14/0x20 rtnl_lock
[ 3302.102448] nl80211_pre_doit+0x28/0x1a0
[ 3302.102465] genl_rcv_msg+0x3a4/0x408
[ 3302.102473] netlink_rcv_skb+0xa8/0x120
[ 3302.102481] genl_rcv+0x30/0x48 down_read(&cb_lock);
[ 3302.102487] netlink_unicast+0x1ec/0x290
[ 3302.102496] netlink_sendmsg+0x2ec/0x348

[ 3302.102609] Call trace:
[ 3302.102615] __switch_to+0x108/0x118
[ 3302.102624] __schedule+0x8fc/0xcd8
[ 3302.102630] schedule+0x70/0x90
[ 3302.102638] rwsem_down_write_failed+0x2bc/0x3c8
[ 3302.102644] down_write+0x4c/0x50
[ 3302.102652] genl_register_family+0xb4/0x650 down_write(&cb_lock);
[ 3302.102818] rmnet_shs_wq_genl_init+0x1c/0x38 [rmnet_shs]
[ 3302.102847] rmnet_shs_wq_init+0x218/0x328 [rmnet_shs]
[ 3302.102873] rmnet_shs_dev_notify_cb+0x378/0x3e0 [rmnet_shs]
[ 3302.102892] raw_notifier_call_chain+0x3c/0x68
[ 3302.102909] register_netdevice+0x374/0x560
[ 3302.102934] rmnet_vnd_newlink+0x6c/0xe8
[ 3302.102942] rmnet_newlink+0x9c/0x198
[ 3302.102950] rtnl_newlink+0x648/0x7b0
[ 3302.102960] rtnetlink_rcv_msg+0x270/0x388 mutex_lock(&rtnl_mutex);

Change-Id: Ib71de0cb4617477cab40a7f42154584765e30c2b
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent 7bfe056a
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "rmnet_shs_config.h"
#include "rmnet_shs.h"
#include "rmnet_shs_wq.h"
#include "rmnet_shs_wq_genl.h"

MODULE_LICENSE("GPL v2");

@@ -51,6 +52,11 @@ int __init rmnet_shs_module_init(void)
	pr_info("%s(): Starting rmnet SHS module\n", __func__);
	trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_INIT,
			    0xDEF, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);

	if (rmnet_shs_wq_genl_init()) {
		rm_err("%s", "SHS_GNL: Failed to init generic netlink");
	}

	return register_netdevice_notifier(&rmnet_shs_dev_notifier);
}

@@ -60,6 +66,9 @@ void __exit rmnet_shs_module_exit(void)
	trace_rmnet_shs_high(RMNET_SHS_MODULE, RMNET_SHS_MODULE_EXIT,
			    0xDEF, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
	unregister_netdevice_notifier(&rmnet_shs_dev_notifier);

	rmnet_shs_wq_genl_deinit();

	pr_info("%s(): Exiting rmnet SHS module\n", __func__);
}

+0 −5
Original line number Diff line number Diff line
@@ -1989,7 +1989,6 @@ void rmnet_shs_wq_exit(void)
	if (!rmnet_shs_wq || !rmnet_shs_delayed_wq)
		return;

	rmnet_shs_wq_genl_deinit();
	rmnet_shs_wq_mem_deinit();

	trace_rmnet_shs_wq_high(RMNET_SHS_WQ_EXIT, RMNET_SHS_WQ_EXIT_START,
@@ -2078,10 +2077,6 @@ void rmnet_shs_wq_init(struct net_device *dev)
	INIT_DEFERRABLE_WORK(&rmnet_shs_delayed_wq->wq,
			     rmnet_shs_wq_process_wq);

	if (rmnet_shs_wq_genl_init()) {
		rm_err("%s", "SHS_GNL: Failed to init generic netlink");
	}

	trace_rmnet_shs_wq_high(RMNET_SHS_WQ_INIT, RMNET_SHS_WQ_INIT_END,
				0xDEF, 0xDEF, 0xDEF, 0xDEF, NULL, NULL);
}