diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2014-08-22 18:09:13 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-08-23 14:18:34 -0400 |
commit | 5b8fa7ce823a59a328e0a7661df2478bfb745de4 (patch) | |
tree | 1bc95f4e995d044f3eaa7916b42bd98a0d698ca2 /net/tipc | |
parent | 739f5e4efc82c4cb6b5201cbed337b6ff663bf19 (diff) |
tipc: eliminate functions tipc_port_init and tipc_port_destroy
After the latest changes to the socket/port layer the existence of
the functions tipc_port_init() and tipc_port_destroy() cannot be
justified. They are both called only once, from tipc_sk_create() and
tipc_sk_delete() respectively, and their functionality can better be
merged into the latter two functions.
This also entails that all remaining references to port_lock now are
made from inside socket.c, something that will make it easier to remove
this lock.
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/port.c | 75 | ||||
-rw-r--r-- | net/tipc/port.h | 4 | ||||
-rw-r--r-- | net/tipc/socket.c | 51 |
3 files changed, 42 insertions, 88 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c index 1074ccb0c76f..1efa2982d2d2 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -42,10 +42,6 @@ | |||
42 | 42 | ||
43 | #define MAX_REJECT_SIZE 1024 | 43 | #define MAX_REJECT_SIZE 1024 |
44 | 44 | ||
45 | DEFINE_SPINLOCK(tipc_port_list_lock); | ||
46 | |||
47 | static LIST_HEAD(ports); | ||
48 | |||
49 | /** | 45 | /** |
50 | * tipc_port_peer_msg - verify message was sent by connected port's peer | 46 | * tipc_port_peer_msg - verify message was sent by connected port's peer |
51 | * | 47 | * |
@@ -67,73 +63,6 @@ int tipc_port_peer_msg(struct tipc_port *p_ptr, struct tipc_msg *msg) | |||
67 | (!peernode && (orignode == tipc_own_addr)); | 63 | (!peernode && (orignode == tipc_own_addr)); |
68 | } | 64 | } |
69 | 65 | ||
70 | /* tipc_port_init - intiate TIPC port and lock it | ||
71 | * | ||
72 | * Returns obtained reference if initialization is successful, zero otherwise | ||
73 | */ | ||
74 | u32 tipc_port_init(struct tipc_port *p_ptr, | ||
75 | const unsigned int importance) | ||
76 | { | ||
77 | struct tipc_msg *msg; | ||
78 | u32 ref; | ||
79 | |||
80 | ref = tipc_ref_acquire(p_ptr, &p_ptr->lock); | ||
81 | if (!ref) { | ||
82 | pr_warn("Port registration failed, ref. table exhausted\n"); | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | p_ptr->max_pkt = MAX_PKT_DEFAULT; | ||
87 | p_ptr->ref = ref; | ||
88 | INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); | ||
89 | INIT_LIST_HEAD(&p_ptr->publications); | ||
90 | INIT_LIST_HEAD(&p_ptr->port_list); | ||
91 | |||
92 | /* | ||
93 | * Must hold port list lock while initializing message header template | ||
94 | * to ensure a change to node's own network address doesn't result | ||
95 | * in template containing out-dated network address information | ||
96 | */ | ||
97 | spin_lock_bh(&tipc_port_list_lock); | ||
98 | msg = &p_ptr->phdr; | ||
99 | tipc_msg_init(msg, importance, TIPC_NAMED_MSG, NAMED_H_SIZE, 0); | ||
100 | msg_set_origport(msg, ref); | ||
101 | list_add_tail(&p_ptr->port_list, &ports); | ||
102 | spin_unlock_bh(&tipc_port_list_lock); | ||
103 | return ref; | ||
104 | } | ||
105 | |||
106 | void tipc_port_destroy(struct tipc_port *p_ptr) | ||
107 | { | ||
108 | struct sk_buff *buf = NULL; | ||
109 | struct tipc_msg *msg = NULL; | ||
110 | u32 peer_node; | ||
111 | |||
112 | tipc_withdraw(p_ptr, 0, NULL); | ||
113 | |||
114 | spin_lock_bh(p_ptr->lock); | ||
115 | tipc_ref_discard(p_ptr->ref); | ||
116 | spin_unlock_bh(p_ptr->lock); | ||
117 | |||
118 | k_cancel_timer(&p_ptr->timer); | ||
119 | if (p_ptr->connected) { | ||
120 | peer_node = tipc_port_peernode(p_ptr); | ||
121 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | ||
122 | SHORT_H_SIZE, 0, peer_node, | ||
123 | tipc_own_addr, tipc_port_peerport(p_ptr), | ||
124 | p_ptr->ref, TIPC_ERR_NO_PORT); | ||
125 | if (buf) { | ||
126 | msg = buf_msg(buf); | ||
127 | tipc_link_xmit(buf, peer_node, msg_link_selector(msg)); | ||
128 | } | ||
129 | tipc_node_remove_conn(peer_node, p_ptr->ref); | ||
130 | } | ||
131 | spin_lock_bh(&tipc_port_list_lock); | ||
132 | list_del(&p_ptr->port_list); | ||
133 | spin_unlock_bh(&tipc_port_list_lock); | ||
134 | k_term_timer(&p_ptr->timer); | ||
135 | } | ||
136 | |||
137 | static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) | 66 | static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) |
138 | { | 67 | { |
139 | struct publication *publ; | 68 | struct publication *publ; |
@@ -194,7 +123,7 @@ struct sk_buff *tipc_port_get_ports(void) | |||
194 | pb_len = ULTRA_STRING_MAX_LEN; | 123 | pb_len = ULTRA_STRING_MAX_LEN; |
195 | 124 | ||
196 | spin_lock_bh(&tipc_port_list_lock); | 125 | spin_lock_bh(&tipc_port_list_lock); |
197 | list_for_each_entry(p_ptr, &ports, port_list) { | 126 | list_for_each_entry(p_ptr, &tipc_socks, port_list) { |
198 | spin_lock_bh(p_ptr->lock); | 127 | spin_lock_bh(p_ptr->lock); |
199 | str_len += port_print(p_ptr, pb, pb_len, 0); | 128 | str_len += port_print(p_ptr, pb, pb_len, 0); |
200 | spin_unlock_bh(p_ptr->lock); | 129 | spin_unlock_bh(p_ptr->lock); |
@@ -213,7 +142,7 @@ void tipc_port_reinit(void) | |||
213 | struct tipc_msg *msg; | 142 | struct tipc_msg *msg; |
214 | 143 | ||
215 | spin_lock_bh(&tipc_port_list_lock); | 144 | spin_lock_bh(&tipc_port_list_lock); |
216 | list_for_each_entry(p_ptr, &ports, port_list) { | 145 | list_for_each_entry(p_ptr, &tipc_socks, port_list) { |
217 | msg = &p_ptr->phdr; | 146 | msg = &p_ptr->phdr; |
218 | msg_set_prevnode(msg, tipc_own_addr); | 147 | msg_set_prevnode(msg, tipc_own_addr); |
219 | msg_set_orignode(msg, tipc_own_addr); | 148 | msg_set_orignode(msg, tipc_own_addr); |
diff --git a/net/tipc/port.h b/net/tipc/port.h index c92e1721f672..4c6cfdd36351 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -63,7 +63,6 @@ | |||
63 | * @probing_state: | 63 | * @probing_state: |
64 | * @probing_interval: | 64 | * @probing_interval: |
65 | * @timer_ref: | 65 | * @timer_ref: |
66 | * @subscription: "node down" subscription used to terminate failed connections | ||
67 | */ | 66 | */ |
68 | struct tipc_port { | 67 | struct tipc_port { |
69 | spinlock_t *lock; | 68 | spinlock_t *lock; |
@@ -80,11 +79,10 @@ struct tipc_port { | |||
80 | u32 probing_state; | 79 | u32 probing_state; |
81 | u32 probing_interval; | 80 | u32 probing_interval; |
82 | struct timer_list timer; | 81 | struct timer_list timer; |
83 | struct tipc_node_subscr subscription; | ||
84 | }; | 82 | }; |
85 | 83 | ||
84 | extern struct list_head tipc_socks; | ||
86 | extern spinlock_t tipc_port_list_lock; | 85 | extern spinlock_t tipc_port_list_lock; |
87 | struct tipc_port_list; | ||
88 | 86 | ||
89 | /* | 87 | /* |
90 | * TIPC port manipulation routines | 88 | * TIPC port manipulation routines |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 686a11be5c58..f2be4c2e20bb 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -63,6 +63,9 @@ static const struct proto_ops msg_ops; | |||
63 | static struct proto tipc_proto; | 63 | static struct proto tipc_proto; |
64 | static struct proto tipc_proto_kern; | 64 | static struct proto tipc_proto_kern; |
65 | 65 | ||
66 | DEFINE_SPINLOCK(tipc_port_list_lock); | ||
67 | LIST_HEAD(tipc_socks); | ||
68 | |||
66 | /* | 69 | /* |
67 | * Revised TIPC socket locking policy: | 70 | * Revised TIPC socket locking policy: |
68 | * | 71 | * |
@@ -156,6 +159,7 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
156 | struct sock *sk; | 159 | struct sock *sk; |
157 | struct tipc_sock *tsk; | 160 | struct tipc_sock *tsk; |
158 | struct tipc_port *port; | 161 | struct tipc_port *port; |
162 | struct tipc_msg *msg; | ||
159 | u32 ref; | 163 | u32 ref; |
160 | 164 | ||
161 | /* Validate arguments */ | 165 | /* Validate arguments */ |
@@ -191,18 +195,28 @@ static int tipc_sk_create(struct net *net, struct socket *sock, | |||
191 | 195 | ||
192 | tsk = tipc_sk(sk); | 196 | tsk = tipc_sk(sk); |
193 | port = &tsk->port; | 197 | port = &tsk->port; |
194 | 198 | ref = tipc_ref_acquire(port, &port->lock); | |
195 | ref = tipc_port_init(port, TIPC_LOW_IMPORTANCE); | ||
196 | if (!ref) { | 199 | if (!ref) { |
197 | pr_warn("Socket registration failed, ref. table exhausted\n"); | 200 | pr_warn("Socket create failed; reference table exhausted\n"); |
198 | sk_free(sk); | ||
199 | return -ENOMEM; | 201 | return -ENOMEM; |
200 | } | 202 | } |
203 | port->max_pkt = MAX_PKT_DEFAULT; | ||
204 | port->ref = ref; | ||
205 | INIT_LIST_HEAD(&port->publications); | ||
206 | INIT_LIST_HEAD(&port->port_list); | ||
207 | |||
208 | /* Guard against race during node address update */ | ||
209 | spin_lock_bh(&tipc_port_list_lock); | ||
210 | msg = &port->phdr; | ||
211 | tipc_msg_init(msg, TIPC_LOW_IMPORTANCE, TIPC_NAMED_MSG, | ||
212 | NAMED_H_SIZE, 0); | ||
213 | msg_set_origport(msg, ref); | ||
214 | list_add_tail(&port->port_list, &tipc_socks); | ||
215 | spin_unlock_bh(&tipc_port_list_lock); | ||
201 | 216 | ||
202 | /* Finish initializing socket data structures */ | 217 | /* Finish initializing socket data structures */ |
203 | sock->ops = ops; | 218 | sock->ops = ops; |
204 | sock->state = state; | 219 | sock->state = state; |
205 | |||
206 | sock_init_data(sock, sk); | 220 | sock_init_data(sock, sk); |
207 | k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref); | 221 | k_init_timer(&port->timer, (Handler)tipc_sk_timeout, ref); |
208 | sk->sk_backlog_rcv = tipc_backlog_rcv; | 222 | sk->sk_backlog_rcv = tipc_backlog_rcv; |
@@ -330,6 +344,7 @@ static int tipc_release(struct socket *sock) | |||
330 | * Reject all unreceived messages, except on an active connection | 344 | * Reject all unreceived messages, except on an active connection |
331 | * (which disconnects locally & sends a 'FIN+' to peer) | 345 | * (which disconnects locally & sends a 'FIN+' to peer) |
332 | */ | 346 | */ |
347 | dnode = tipc_port_peernode(port); | ||
333 | while (sock->state != SS_DISCONNECTING) { | 348 | while (sock->state != SS_DISCONNECTING) { |
334 | buf = __skb_dequeue(&sk->sk_receive_queue); | 349 | buf = __skb_dequeue(&sk->sk_receive_queue); |
335 | if (buf == NULL) | 350 | if (buf == NULL) |
@@ -341,18 +356,31 @@ static int tipc_release(struct socket *sock) | |||
341 | (sock->state == SS_CONNECTED)) { | 356 | (sock->state == SS_CONNECTED)) { |
342 | sock->state = SS_DISCONNECTING; | 357 | sock->state = SS_DISCONNECTING; |
343 | port->connected = 0; | 358 | port->connected = 0; |
344 | tipc_node_remove_conn(tipc_port_peernode(port), | 359 | tipc_node_remove_conn(dnode, port->ref); |
345 | port->ref); | ||
346 | } | 360 | } |
347 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) | 361 | if (tipc_msg_reverse(buf, &dnode, TIPC_ERR_NO_PORT)) |
348 | tipc_link_xmit(buf, dnode, 0); | 362 | tipc_link_xmit(buf, dnode, 0); |
349 | } | 363 | } |
350 | } | 364 | } |
351 | 365 | ||
352 | /* Destroy TIPC port; also disconnects an active connection and | 366 | tipc_withdraw(port, 0, NULL); |
353 | * sends a 'FIN-' to peer. | 367 | spin_lock_bh(port->lock); |
354 | */ | 368 | tipc_ref_discard(port->ref); |
355 | tipc_port_destroy(port); | 369 | spin_unlock_bh(port->lock); |
370 | k_cancel_timer(&port->timer); | ||
371 | if (port->connected) { | ||
372 | buf = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, | ||
373 | SHORT_H_SIZE, 0, dnode, tipc_own_addr, | ||
374 | tipc_port_peerport(port), | ||
375 | port->ref, TIPC_ERR_NO_PORT); | ||
376 | if (buf) | ||
377 | tipc_link_xmit(buf, dnode, port->ref); | ||
378 | tipc_node_remove_conn(dnode, port->ref); | ||
379 | } | ||
380 | spin_lock_bh(&tipc_port_list_lock); | ||
381 | list_del(&port->port_list); | ||
382 | spin_unlock_bh(&tipc_port_list_lock); | ||
383 | k_term_timer(&port->timer); | ||
356 | 384 | ||
357 | /* Discard any remaining (connection-based) messages in receive queue */ | 385 | /* Discard any remaining (connection-based) messages in receive queue */ |
358 | __skb_queue_purge(&sk->sk_receive_queue); | 386 | __skb_queue_purge(&sk->sk_receive_queue); |
@@ -360,7 +388,6 @@ static int tipc_release(struct socket *sock) | |||
360 | /* Reject any messages that accumulated in backlog queue */ | 388 | /* Reject any messages that accumulated in backlog queue */ |
361 | sock->state = SS_DISCONNECTING; | 389 | sock->state = SS_DISCONNECTING; |
362 | release_sock(sk); | 390 | release_sock(sk); |
363 | |||
364 | sock_put(sk); | 391 | sock_put(sk); |
365 | sock->sk = NULL; | 392 | sock->sk = NULL; |
366 | 393 | ||