diff options
author | Jon Paul Maloy <jon.maloy@ericsson.com> | 2014-06-25 21:41:40 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-06-27 15:50:56 -0400 |
commit | ec8a2e5621db2da24badb3969eda7fd359e1869f (patch) | |
tree | c169c9e1d7d043ff5c73c3c4ccdcf09702d4f69a /net/tipc | |
parent | b786e2b0faea1265d72533d59ec4482f764ad60f (diff) |
tipc: same receive code path for connection protocol and data messages
As a preparation to eliminate port_lock we need to bring reception
of connection protocol messages under proper protection of bh_lock_sock
or socket owner.
We fix this by letting those messages follow the same code path as
incoming data messages.
As a side effect of this change, the last reference to the function
net_route_msg() disappears, and we can eliminate that function.
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/link.c | 18 | ||||
-rw-r--r-- | net/tipc/net.c | 40 | ||||
-rw-r--r-- | net/tipc/net.h | 2 | ||||
-rw-r--r-- | net/tipc/port.c | 7 | ||||
-rw-r--r-- | net/tipc/port.h | 2 | ||||
-rw-r--r-- | net/tipc/socket.c | 5 |
6 files changed, 19 insertions, 55 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 93a8033263c0..96a8072f73cc 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -1479,6 +1479,7 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
1479 | case TIPC_MEDIUM_IMPORTANCE: | 1479 | case TIPC_MEDIUM_IMPORTANCE: |
1480 | case TIPC_HIGH_IMPORTANCE: | 1480 | case TIPC_HIGH_IMPORTANCE: |
1481 | case TIPC_CRITICAL_IMPORTANCE: | 1481 | case TIPC_CRITICAL_IMPORTANCE: |
1482 | case CONN_MANAGER: | ||
1482 | tipc_node_unlock(n_ptr); | 1483 | tipc_node_unlock(n_ptr); |
1483 | tipc_sk_rcv(buf); | 1484 | tipc_sk_rcv(buf); |
1484 | continue; | 1485 | continue; |
@@ -1493,10 +1494,6 @@ void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr) | |||
1493 | tipc_node_unlock(n_ptr); | 1494 | tipc_node_unlock(n_ptr); |
1494 | tipc_named_rcv(buf); | 1495 | tipc_named_rcv(buf); |
1495 | continue; | 1496 | continue; |
1496 | case CONN_MANAGER: | ||
1497 | tipc_node_unlock(n_ptr); | ||
1498 | tipc_port_proto_rcv(buf); | ||
1499 | continue; | ||
1500 | case BCAST_PROTOCOL: | 1497 | case BCAST_PROTOCOL: |
1501 | tipc_link_sync_rcv(n_ptr, buf); | 1498 | tipc_link_sync_rcv(n_ptr, buf); |
1502 | break; | 1499 | break; |
@@ -2106,6 +2103,7 @@ void tipc_link_bundle_rcv(struct sk_buff *buf) | |||
2106 | u32 msgcount = msg_msgcnt(buf_msg(buf)); | 2103 | u32 msgcount = msg_msgcnt(buf_msg(buf)); |
2107 | u32 pos = INT_H_SIZE; | 2104 | u32 pos = INT_H_SIZE; |
2108 | struct sk_buff *obuf; | 2105 | struct sk_buff *obuf; |
2106 | struct tipc_msg *omsg; | ||
2109 | 2107 | ||
2110 | while (msgcount--) { | 2108 | while (msgcount--) { |
2111 | obuf = buf_extract(buf, pos); | 2109 | obuf = buf_extract(buf, pos); |
@@ -2113,8 +2111,16 @@ void tipc_link_bundle_rcv(struct sk_buff *buf) | |||
2113 | pr_warn("Link unable to unbundle message(s)\n"); | 2111 | pr_warn("Link unable to unbundle message(s)\n"); |
2114 | break; | 2112 | break; |
2115 | } | 2113 | } |
2116 | pos += align(msg_size(buf_msg(obuf))); | 2114 | omsg = buf_msg(obuf); |
2117 | tipc_net_route_msg(obuf); | 2115 | pos += align(msg_size(omsg)); |
2116 | if (msg_isdata(omsg) || (msg_user(omsg) == CONN_MANAGER)) { | ||
2117 | tipc_sk_rcv(obuf); | ||
2118 | } else if (msg_user(omsg) == NAME_DISTRIBUTOR) { | ||
2119 | tipc_named_rcv(obuf); | ||
2120 | } else { | ||
2121 | pr_warn("Illegal bundled msg: %u\n", msg_user(omsg)); | ||
2122 | kfree_skb(obuf); | ||
2123 | } | ||
2118 | } | 2124 | } |
2119 | kfree_skb(buf); | 2125 | kfree_skb(buf); |
2120 | } | 2126 | } |
diff --git a/net/tipc/net.c b/net/tipc/net.c index 5f7d6ffb5465..7fcc94998fea 100644 --- a/net/tipc/net.c +++ b/net/tipc/net.c | |||
@@ -103,46 +103,6 @@ | |||
103 | * This is always used within the scope of a tipc_nametbl_lock(read). | 103 | * This is always used within the scope of a tipc_nametbl_lock(read). |
104 | * - A local spin_lock protecting the queue of subscriber events. | 104 | * - A local spin_lock protecting the queue of subscriber events. |
105 | */ | 105 | */ |
106 | void tipc_net_route_msg(struct sk_buff *buf) | ||
107 | { | ||
108 | struct tipc_msg *msg; | ||
109 | u32 dnode; | ||
110 | |||
111 | if (!buf) | ||
112 | return; | ||
113 | msg = buf_msg(buf); | ||
114 | |||
115 | /* Handle message for this node */ | ||
116 | dnode = msg_short(msg) ? tipc_own_addr : msg_destnode(msg); | ||
117 | if (tipc_in_scope(dnode, tipc_own_addr)) { | ||
118 | if (msg_isdata(msg)) { | ||
119 | if (msg_mcast(msg)) | ||
120 | tipc_port_mcast_rcv(buf, NULL); | ||
121 | else if (msg_destport(msg)) { | ||
122 | tipc_sk_rcv(buf); | ||
123 | } else { | ||
124 | pr_warn("Cannot route msg; no destination\n"); | ||
125 | kfree_skb(buf); | ||
126 | } | ||
127 | return; | ||
128 | } | ||
129 | switch (msg_user(msg)) { | ||
130 | case NAME_DISTRIBUTOR: | ||
131 | tipc_named_rcv(buf); | ||
132 | break; | ||
133 | case CONN_MANAGER: | ||
134 | tipc_port_proto_rcv(buf); | ||
135 | break; | ||
136 | default: | ||
137 | kfree_skb(buf); | ||
138 | } | ||
139 | return; | ||
140 | } | ||
141 | |||
142 | /* Handle message for another node */ | ||
143 | skb_trim(buf, msg_size(msg)); | ||
144 | tipc_link_xmit(buf, dnode, msg_link_selector(msg)); | ||
145 | } | ||
146 | 106 | ||
147 | int tipc_net_start(u32 addr) | 107 | int tipc_net_start(u32 addr) |
148 | { | 108 | { |
diff --git a/net/tipc/net.h b/net/tipc/net.h index c6c2b46f7c28..59ef3388be2c 100644 --- a/net/tipc/net.h +++ b/net/tipc/net.h | |||
@@ -37,8 +37,6 @@ | |||
37 | #ifndef _TIPC_NET_H | 37 | #ifndef _TIPC_NET_H |
38 | #define _TIPC_NET_H | 38 | #define _TIPC_NET_H |
39 | 39 | ||
40 | void tipc_net_route_msg(struct sk_buff *buf); | ||
41 | |||
42 | int tipc_net_start(u32 addr); | 40 | int tipc_net_start(u32 addr); |
43 | void tipc_net_stop(void); | 41 | void tipc_net_stop(void); |
44 | 42 | ||
diff --git a/net/tipc/port.c b/net/tipc/port.c index 60aede075b52..dcc630948e04 100644 --- a/net/tipc/port.c +++ b/net/tipc/port.c | |||
@@ -365,16 +365,14 @@ static struct sk_buff *port_build_peer_abort_msg(struct tipc_port *p_ptr, u32 er | |||
365 | return buf; | 365 | return buf; |
366 | } | 366 | } |
367 | 367 | ||
368 | void tipc_port_proto_rcv(struct sk_buff *buf) | 368 | void tipc_port_proto_rcv(struct tipc_port *p_ptr, struct sk_buff *buf) |
369 | { | 369 | { |
370 | struct tipc_msg *msg = buf_msg(buf); | 370 | struct tipc_msg *msg = buf_msg(buf); |
371 | struct tipc_port *p_ptr; | ||
372 | struct sk_buff *r_buf = NULL; | 371 | struct sk_buff *r_buf = NULL; |
373 | u32 destport = msg_destport(msg); | 372 | u32 destport = msg_destport(msg); |
374 | int wakeable; | 373 | int wakeable; |
375 | 374 | ||
376 | /* Validate connection */ | 375 | /* Validate connection */ |
377 | p_ptr = tipc_port_lock(destport); | ||
378 | if (!p_ptr || !p_ptr->connected || !tipc_port_peer_msg(p_ptr, msg)) { | 376 | if (!p_ptr || !p_ptr->connected || !tipc_port_peer_msg(p_ptr, msg)) { |
379 | r_buf = tipc_buf_acquire(BASIC_H_SIZE); | 377 | r_buf = tipc_buf_acquire(BASIC_H_SIZE); |
380 | if (r_buf) { | 378 | if (r_buf) { |
@@ -385,8 +383,6 @@ void tipc_port_proto_rcv(struct sk_buff *buf) | |||
385 | msg_set_origport(msg, destport); | 383 | msg_set_origport(msg, destport); |
386 | msg_set_destport(msg, msg_origport(msg)); | 384 | msg_set_destport(msg, msg_origport(msg)); |
387 | } | 385 | } |
388 | if (p_ptr) | ||
389 | tipc_port_unlock(p_ptr); | ||
390 | goto exit; | 386 | goto exit; |
391 | } | 387 | } |
392 | 388 | ||
@@ -409,7 +405,6 @@ void tipc_port_proto_rcv(struct sk_buff *buf) | |||
409 | break; | 405 | break; |
410 | } | 406 | } |
411 | p_ptr->probing_state = CONFIRMED; | 407 | p_ptr->probing_state = CONFIRMED; |
412 | tipc_port_unlock(p_ptr); | ||
413 | exit: | 408 | exit: |
414 | tipc_link_xmit2(r_buf, msg_destnode(msg), msg_link_selector(msg)); | 409 | tipc_link_xmit2(r_buf, msg_destnode(msg), msg_link_selector(msg)); |
415 | kfree_skb(buf); | 410 | kfree_skb(buf); |
diff --git a/net/tipc/port.h b/net/tipc/port.h index 231d9488189c..3f28fd420ff9 100644 --- a/net/tipc/port.h +++ b/net/tipc/port.h | |||
@@ -140,7 +140,7 @@ int tipc_port_mcast_xmit(struct tipc_port *port, | |||
140 | unsigned int len); | 140 | unsigned int len); |
141 | 141 | ||
142 | struct sk_buff *tipc_port_get_ports(void); | 142 | struct sk_buff *tipc_port_get_ports(void); |
143 | void tipc_port_proto_rcv(struct sk_buff *buf); | 143 | void tipc_port_proto_rcv(struct tipc_port *port, struct sk_buff *buf); |
144 | void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp); | 144 | void tipc_port_mcast_rcv(struct sk_buff *buf, struct tipc_port_list *dp); |
145 | void tipc_port_reinit(void); | 145 | void tipc_port_reinit(void); |
146 | 146 | ||
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index bfe79bbd83a1..d838a4b66d3a 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -1416,6 +1416,11 @@ static int filter_rcv(struct sock *sk, struct sk_buff *buf) | |||
1416 | unsigned int limit = rcvbuf_limit(sk, buf); | 1416 | unsigned int limit = rcvbuf_limit(sk, buf); |
1417 | int rc = TIPC_OK; | 1417 | int rc = TIPC_OK; |
1418 | 1418 | ||
1419 | if (unlikely(msg_user(msg) == CONN_MANAGER)) { | ||
1420 | tipc_port_proto_rcv(&tsk->port, buf); | ||
1421 | return TIPC_OK; | ||
1422 | } | ||
1423 | |||
1419 | /* Reject message if it is wrong sort of message for socket */ | 1424 | /* Reject message if it is wrong sort of message for socket */ |
1420 | if (msg_type(msg) > TIPC_DIRECT_MSG) | 1425 | if (msg_type(msg) > TIPC_DIRECT_MSG) |
1421 | return -TIPC_ERR_NO_PORT; | 1426 | return -TIPC_ERR_NO_PORT; |