aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorJon Paul Maloy <jon.maloy@ericsson.com>2014-08-22 18:09:13 -0400
committerDavid S. Miller <davem@davemloft.net>2014-08-23 14:18:34 -0400
commit5b8fa7ce823a59a328e0a7661df2478bfb745de4 (patch)
tree1bc95f4e995d044f3eaa7916b42bd98a0d698ca2 /net/tipc
parent739f5e4efc82c4cb6b5201cbed337b6ff663bf19 (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.c75
-rw-r--r--net/tipc/port.h4
-rw-r--r--net/tipc/socket.c51
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
45DEFINE_SPINLOCK(tipc_port_list_lock);
46
47static 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 */
74u32 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
106void 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
137static int port_print(struct tipc_port *p_ptr, char *buf, int len, int full_id) 66static 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 */
68struct tipc_port { 67struct 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
84extern struct list_head tipc_socks;
86extern spinlock_t tipc_port_list_lock; 85extern spinlock_t tipc_port_list_lock;
87struct 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;
63static struct proto tipc_proto; 63static struct proto tipc_proto;
64static struct proto tipc_proto_kern; 64static struct proto tipc_proto_kern;
65 65
66DEFINE_SPINLOCK(tipc_port_list_lock);
67LIST_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