Skip to content
This repository was archived by the owner on Oct 31, 2024. It is now read-only.

Commit c8c76f1

Browse files
Eric Dumazetgregkh
Eric Dumazet
authored andcommitted
rtnetlink: change nlk->cb_mutex role
[ Upstream commit e39951d ] In commit af65bdf ("[NETLINK]: Switch cb_lock spinlock to mutex and allow to override it"), Patrick McHardy used a common mutex to protect both nlk->cb and the dump() operations. The override is used for rtnl dumps, registered with rntl_register() and rntl_register_module(). We want to be able to opt-out some dump() operations to not acquire RTNL, so we need to protect nlk->cb with a per socket mutex. This patch renames nlk->cb_def_mutex to nlk->nl_cb_mutex The optional pointer to the mutex used to protect dump() call is stored in nlk->dump_cb_mutex Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net> Stable-dep-of: 5be2062 ("mpls: Handle error of rtnl_register_module().") Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f4df31a commit c8c76f1

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

net/netlink/af_netlink.c

+18-14
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ static struct proto netlink_proto = {
636636
};
637637

638638
static int __netlink_create(struct net *net, struct socket *sock,
639-
struct mutex *cb_mutex, int protocol,
639+
struct mutex *dump_cb_mutex, int protocol,
640640
int kern)
641641
{
642642
struct sock *sk;
@@ -651,15 +651,11 @@ static int __netlink_create(struct net *net, struct socket *sock,
651651
sock_init_data(sock, sk);
652652

653653
nlk = nlk_sk(sk);
654-
if (cb_mutex) {
655-
nlk->cb_mutex = cb_mutex;
656-
} else {
657-
nlk->cb_mutex = &nlk->cb_def_mutex;
658-
mutex_init(nlk->cb_mutex);
659-
lockdep_set_class_and_name(nlk->cb_mutex,
654+
mutex_init(&nlk->nl_cb_mutex);
655+
lockdep_set_class_and_name(&nlk->nl_cb_mutex,
660656
nlk_cb_mutex_keys + protocol,
661657
nlk_cb_mutex_key_strings[protocol]);
662-
}
658+
nlk->dump_cb_mutex = dump_cb_mutex;
663659
init_waitqueue_head(&nlk->wait);
664660

665661
sk->sk_destruct = netlink_sock_destruct;
@@ -2211,7 +2207,7 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
22112207
int alloc_size;
22122208

22132209
if (!lock_taken)
2214-
mutex_lock(nlk->cb_mutex);
2210+
mutex_lock(&nlk->nl_cb_mutex);
22152211
if (!nlk->cb_running) {
22162212
err = -EINVAL;
22172213
goto errout_skb;
@@ -2263,14 +2259,22 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
22632259
netlink_skb_set_owner_r(skb, sk);
22642260

22652261
if (nlk->dump_done_errno > 0) {
2262+
struct mutex *extra_mutex = nlk->dump_cb_mutex;
2263+
22662264
cb->extack = &extack;
2265+
2266+
if (extra_mutex)
2267+
mutex_lock(extra_mutex);
22672268
nlk->dump_done_errno = cb->dump(skb, cb);
2269+
if (extra_mutex)
2270+
mutex_unlock(extra_mutex);
2271+
22682272
cb->extack = NULL;
22692273
}
22702274

22712275
if (nlk->dump_done_errno > 0 ||
22722276
skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
2273-
mutex_unlock(nlk->cb_mutex);
2277+
mutex_unlock(&nlk->nl_cb_mutex);
22742278

22752279
if (sk_filter(sk, skb))
22762280
kfree_skb(skb);
@@ -2304,13 +2308,13 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
23042308
WRITE_ONCE(nlk->cb_running, false);
23052309
module = cb->module;
23062310
skb = cb->skb;
2307-
mutex_unlock(nlk->cb_mutex);
2311+
mutex_unlock(&nlk->nl_cb_mutex);
23082312
module_put(module);
23092313
consume_skb(skb);
23102314
return 0;
23112315

23122316
errout_skb:
2313-
mutex_unlock(nlk->cb_mutex);
2317+
mutex_unlock(&nlk->nl_cb_mutex);
23142318
kfree_skb(skb);
23152319
return err;
23162320
}
@@ -2333,7 +2337,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
23332337
}
23342338

23352339
nlk = nlk_sk(sk);
2336-
mutex_lock(nlk->cb_mutex);
2340+
mutex_lock(&nlk->nl_cb_mutex);
23372341
/* A dump is in progress... */
23382342
if (nlk->cb_running) {
23392343
ret = -EBUSY;
@@ -2384,7 +2388,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
23842388
module_put(control->module);
23852389
error_unlock:
23862390
sock_put(sk);
2387-
mutex_unlock(nlk->cb_mutex);
2391+
mutex_unlock(&nlk->nl_cb_mutex);
23882392
error_free:
23892393
kfree_skb(skb);
23902394
return ret;

net/netlink/af_netlink.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ struct netlink_sock {
3939
bool cb_running;
4040
int dump_done_errno;
4141
struct netlink_callback cb;
42-
struct mutex *cb_mutex;
43-
struct mutex cb_def_mutex;
42+
struct mutex nl_cb_mutex;
43+
44+
struct mutex *dump_cb_mutex;
4445
void (*netlink_rcv)(struct sk_buff *skb);
4546
int (*netlink_bind)(struct net *net, int group);
4647
void (*netlink_unbind)(struct net *net, int group);

0 commit comments

Comments
 (0)