diff options
| -rw-r--r-- | net/tipc/net.c | 4 | ||||
| -rw-r--r-- | net/tipc/socket.c | 30 |
2 files changed, 23 insertions, 11 deletions
diff --git a/net/tipc/net.c b/net/tipc/net.c index 28bf4feeb81c..ab8a2d5d1e32 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
| @@ -110,6 +110,10 @@ int tipc_net_start(struct net *net, u32 addr) | |||
| 110 | char addr_string[16]; | 110 | char addr_string[16]; |
| 111 | 111 | ||
| 112 | tn->own_addr = addr; | 112 | tn->own_addr = addr; |
| 113 | |||
| 114 | /* Ensure that the new address is visible before we reinit. */ | ||
| 115 | smp_mb(); | ||
| 116 | |||
| 113 | tipc_named_reinit(net); | 117 | tipc_named_reinit(net); |
| 114 | tipc_sk_reinit(net); | 118 | tipc_sk_reinit(net); |
| 115 | 119 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 103d1fd058c0..6b09a778cc71 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -430,8 +430,6 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
| 430 | INIT_LIST_HEAD(&tsk->cong_links); | 430 | INIT_LIST_HEAD(&tsk->cong_links); |
| 431 | msg = &tsk->phdr; | 431 | msg = &tsk->phdr; |
| 432 | tn = net_generic(sock_net(sk), tipc_net_id); | 432 | tn = net_generic(sock_net(sk), tipc_net_id); |
| 433 | tipc_msg_init(tn->own_addr, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, | ||
| 434 | NAMED_H_SIZE, 0); | ||
| 435 | 433 | ||
| 436 | /* Finish initializing socket data structures */ | 434 | /* Finish initializing socket data structures */ |
| 437 | sock->ops = ops; | 435 | sock->ops = ops; |
| @@ -441,6 +439,13 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
| 441 | pr_warn("Socket create failed; port number exhausted\n"); | 439 | pr_warn("Socket create failed; port number exhausted\n"); |
| 442 | return -EINVAL; | 440 | return -EINVAL; |
| 443 | } | 441 | } |
| 442 | |||
| 443 | /* Ensure tsk is visible before we read own_addr. */ | ||
| 444 | smp_mb(); | ||
| 445 | |||
| 446 | tipc_msg_init(tn->own_addr, msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, | ||
| 447 | NAMED_H_SIZE, 0); | ||
| 448 | |||
| 444 | msg_set_origport(msg, tsk->portid); | 449 | msg_set_origport(msg, tsk->portid); |
| 445 | setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk); | 450 | setup_timer(&sk->sk_timer, tipc_sk_timeout, (unsigned long)tsk); |
| 446 | sk->sk_shutdown = 0; | 451 | sk->sk_shutdown = 0; |
| @@ -2234,24 +2239,27 @@ static int tipc_sk_withdraw(struct tipc_sock *tsk, uint scope, | |||
| 2234 | void tipc_sk_reinit(struct net *net) | 2239 | void tipc_sk_reinit(struct net *net) |
| 2235 | { | 2240 | { |
| 2236 | struct tipc_net *tn = net_generic(net, tipc_net_id); | 2241 | struct tipc_net *tn = net_generic(net, tipc_net_id); |
| 2237 | const struct bucket_table *tbl; | 2242 | struct rhashtable_iter iter; |
| 2238 | struct rhash_head *pos; | ||
| 2239 | struct tipc_sock *tsk; | 2243 | struct tipc_sock *tsk; |
| 2240 | struct tipc_msg *msg; | 2244 | struct tipc_msg *msg; |
| 2241 | int i; | ||
| 2242 | 2245 | ||
| 2243 | rcu_read_lock(); | 2246 | rhashtable_walk_enter(&tn->sk_rht, &iter); |
| 2244 | tbl = rht_dereference_rcu((&tn->sk_rht)->tbl, &tn->sk_rht); | 2247 | |
| 2245 | for (i = 0; i < tbl->size; i++) { | 2248 | do { |
| 2246 | rht_for_each_entry_rcu(tsk, pos, tbl, i, node) { | 2249 | tsk = ERR_PTR(rhashtable_walk_start(&iter)); |
| 2250 | if (tsk) | ||
| 2251 | continue; | ||
| 2252 | |||
| 2253 | while ((tsk = rhashtable_walk_next(&iter)) && !IS_ERR(tsk)) { | ||
| 2247 | spin_lock_bh(&tsk->sk.sk_lock.slock); | 2254 | spin_lock_bh(&tsk->sk.sk_lock.slock); |
| 2248 | msg = &tsk->phdr; | 2255 | msg = &tsk->phdr; |
| 2249 | msg_set_prevnode(msg, tn->own_addr); | 2256 | msg_set_prevnode(msg, tn->own_addr); |
| 2250 | msg_set_orignode(msg, tn->own_addr); | 2257 | msg_set_orignode(msg, tn->own_addr); |
| 2251 | spin_unlock_bh(&tsk->sk.sk_lock.slock); | 2258 | spin_unlock_bh(&tsk->sk.sk_lock.slock); |
| 2252 | } | 2259 | } |
| 2253 | } | 2260 | |
| 2254 | rcu_read_unlock(); | 2261 | rhashtable_walk_stop(&iter); |
| 2262 | } while (tsk == ERR_PTR(-EAGAIN)); | ||
| 2255 | } | 2263 | } |
| 2256 | 2264 | ||
| 2257 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) | 2265 | static struct tipc_sock *tipc_sk_lookup(struct net *net, u32 portid) |
