genetlink: hold read cb_lock during iteration of genl_fam_idr in genl_bind()
In genl_bind(), currently genl_lock and write cb_lock are taken for iteration of genl_fam_idr and processing of static values stored in struct genl_family. Take just read cb_lock for this task as it is sufficient to guard the idr and the struct against concurrent genl_register/unregister_family() calls. This will allow to run genl command processing in genl_rcv() and mnl_socket_setsockopt(.., NETLINK_ADD_MEMBERSHIP, ..) in parallel. Reported-by: Vikas Gupta <vikas.gupta@broadcom.com> Signed-off-by: Jiri Pirko <jiri@nvidia.com> Link: https://lore.kernel.org/r/20220825081940.1283335-1-jiri@resnulli.us Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
0c1f77d87d
commit
8f1948bdcf
|
@ -1362,7 +1362,7 @@ static int genl_bind(struct net *net, int group)
|
|||
unsigned int id;
|
||||
int ret = 0;
|
||||
|
||||
genl_lock_all();
|
||||
down_read(&cb_lock);
|
||||
|
||||
idr_for_each_entry(&genl_fam_idr, family, id) {
|
||||
const struct genl_multicast_group *grp;
|
||||
|
@ -1383,7 +1383,7 @@ static int genl_bind(struct net *net, int group)
|
|||
break;
|
||||
}
|
||||
|
||||
genl_unlock_all();
|
||||
up_read(&cb_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue