Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit e39951d

Browse files
edumazetdavem330
authored andcommitted
rtnetlink: change nlk->cb_mutex role
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent b559027 commit e39951d

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

net/netlink/af_netlink.c

Lines changed: 18 additions & 14 deletions
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;
@@ -2209,7 +2205,7 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
22092205
int alloc_size;
22102206

22112207
if (!lock_taken)
2212-
mutex_lock(nlk->cb_mutex);
2208+
mutex_lock(&nlk->nl_cb_mutex);
22132209
if (!nlk->cb_running) {
22142210
err = -EINVAL;
22152211
goto errout_skb;
@@ -2261,14 +2257,22 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
22612257
netlink_skb_set_owner_r(skb, sk);
22622258

22632259
if (nlk->dump_done_errno > 0) {
2260+
struct mutex *extra_mutex = nlk->dump_cb_mutex;
2261+
22642262
cb->extack = &extack;
2263+
2264+
if (extra_mutex)
2265+
mutex_lock(extra_mutex);
22652266
nlk->dump_done_errno = cb->dump(skb, cb);
2267+
if (extra_mutex)
2268+
mutex_unlock(extra_mutex);
2269+
22662270
cb->extack = NULL;
22672271
}
22682272

22692273
if (nlk->dump_done_errno > 0 ||
22702274
skb_tailroom(skb) < nlmsg_total_size(sizeof(nlk->dump_done_errno))) {
2271-
mutex_unlock(nlk->cb_mutex);
2275+
mutex_unlock(&nlk->nl_cb_mutex);
22722276

22732277
if (sk_filter(sk, skb))
22742278
kfree_skb(skb);
@@ -2302,13 +2306,13 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
23022306
WRITE_ONCE(nlk->cb_running, false);
23032307
module = cb->module;
23042308
skb = cb->skb;
2305-
mutex_unlock(nlk->cb_mutex);
2309+
mutex_unlock(&nlk->nl_cb_mutex);
23062310
module_put(module);
23072311
consume_skb(skb);
23082312
return 0;
23092313

23102314
errout_skb:
2311-
mutex_unlock(nlk->cb_mutex);
2315+
mutex_unlock(&nlk->nl_cb_mutex);
23122316
kfree_skb(skb);
23132317
return err;
23142318
}
@@ -2331,7 +2335,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
23312335
}
23322336

23332337
nlk = nlk_sk(sk);
2334-
mutex_lock(nlk->cb_mutex);
2338+
mutex_lock(&nlk->nl_cb_mutex);
23352339
/* A dump is in progress... */
23362340
if (nlk->cb_running) {
23372341
ret = -EBUSY;
@@ -2382,7 +2386,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
23822386
module_put(control->module);
23832387
error_unlock:
23842388
sock_put(sk);
2385-
mutex_unlock(nlk->cb_mutex);
2389+
mutex_unlock(&nlk->nl_cb_mutex);
23862390
error_free:
23872391
kfree_skb(skb);
23882392
return ret;

net/netlink/af_netlink.h

Lines changed: 3 additions & 2 deletions
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)