aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/port.c
diff options
context:
space:
mode:
authorAllan Stephens <Allan.Stephens@windriver.com>2011-01-24 15:02:14 -0500
committerPaul Gortmaker <paul.gortmaker@windriver.com>2011-02-23 18:05:18 -0500
commitcb7ce91448c01724e18c1759aa5aba86e5f1c69b (patch)
tree48f9a6acd989af2623517a7ad4a63633f9e4dc11 /net/tipc/port.c
parent69218fc426569739d2bb68e15ac4905948409642 (diff)
tipc: Fix port counter handling to correct congestion control
Modifies TIPC's congestion control between a connected port and its peer so that it works as documented. The following changes have been made: 1) The counter of the number of messages sent by a port now starts at zero, rather than one. This prevents the port from reporting port congestion one message earlier than it was supposed to. 2) The counter of the number of messages sent by a port is now incremented only if a non-empty message is sent successfully. This prevents the port from becoming permanently congested if too many send attempts are unsuccessful because of congestion (or other reasons). It also removes the risk that empty hand- shaking messages used during connection setup might cause the port to report congestion earlier than it was supposed to. 3) The counter of the number of unacknowledged messages received by a port controlled by an internal TIPC service is now incremented only if the message is non-empty, in order to be consistent with the aforementioned changes. Signed-off-by: Allan Stephens <Allan.Stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/port.c')
-rw-r--r--net/tipc/port.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/net/tipc/port.c b/net/tipc/port.c
index aff5dc0c3773..3e5122c5ba33 100644
--- a/net/tipc/port.c
+++ b/net/tipc/port.c
@@ -234,7 +234,6 @@ struct tipc_port *tipc_createport_raw(void *usr_handle,
234 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0); 234 tipc_msg_init(msg, importance, TIPC_NAMED_MSG, LONG_H_SIZE, 0);
235 msg_set_origport(msg, ref); 235 msg_set_origport(msg, ref);
236 p_ptr->last_in_seqno = 41; 236 p_ptr->last_in_seqno = 41;
237 p_ptr->sent = 1;
238 INIT_LIST_HEAD(&p_ptr->wait_list); 237 INIT_LIST_HEAD(&p_ptr->wait_list);
239 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list); 238 INIT_LIST_HEAD(&p_ptr->subscription.nodesub_list);
240 p_ptr->dispatcher = dispatcher; 239 p_ptr->dispatcher = dispatcher;
@@ -732,6 +731,7 @@ static void port_dispatcher_sigh(void *dummy)
732 tipc_conn_msg_event cb = up_ptr->conn_msg_cb; 731 tipc_conn_msg_event cb = up_ptr->conn_msg_cb;
733 u32 peer_port = port_peerport(p_ptr); 732 u32 peer_port = port_peerport(p_ptr);
734 u32 peer_node = port_peernode(p_ptr); 733 u32 peer_node = port_peernode(p_ptr);
734 u32 dsz;
735 735
736 tipc_port_unlock(p_ptr); 736 tipc_port_unlock(p_ptr);
737 if (unlikely(!cb)) 737 if (unlikely(!cb))
@@ -742,13 +742,14 @@ static void port_dispatcher_sigh(void *dummy)
742 } else if ((msg_origport(msg) != peer_port) || 742 } else if ((msg_origport(msg) != peer_port) ||
743 (msg_orignode(msg) != peer_node)) 743 (msg_orignode(msg) != peer_node))
744 goto reject; 744 goto reject;
745 if (unlikely(++p_ptr->conn_unacked >= 745 dsz = msg_data_sz(msg);
746 TIPC_FLOW_CONTROL_WIN)) 746 if (unlikely(dsz &&
747 (++p_ptr->conn_unacked >=
748 TIPC_FLOW_CONTROL_WIN)))
747 tipc_acknowledge(dref, 749 tipc_acknowledge(dref,
748 p_ptr->conn_unacked); 750 p_ptr->conn_unacked);
749 skb_pull(buf, msg_hdr_sz(msg)); 751 skb_pull(buf, msg_hdr_sz(msg));
750 cb(usr_handle, dref, &buf, msg_data(msg), 752 cb(usr_handle, dref, &buf, msg_data(msg), dsz);
751 msg_data_sz(msg));
752 break; 753 break;
753 } 754 }
754 case TIPC_DIRECT_MSG:{ 755 case TIPC_DIRECT_MSG:{
@@ -1221,7 +1222,8 @@ int tipc_send(u32 ref, unsigned int num_sect, struct iovec const *msg_sect)
1221 if (likely(res != -ELINKCONG)) { 1222 if (likely(res != -ELINKCONG)) {
1222 port_incr_out_seqno(p_ptr); 1223 port_incr_out_seqno(p_ptr);
1223 p_ptr->congested = 0; 1224 p_ptr->congested = 0;
1224 p_ptr->sent++; 1225 if (res > 0)
1226 p_ptr->sent++;
1225 return res; 1227 return res;
1226 } 1228 }
1227 } 1229 }
@@ -1263,13 +1265,17 @@ int tipc_send2name(u32 ref, struct tipc_name const *name, unsigned int domain,
1263 msg_set_destport(msg, destport); 1265 msg_set_destport(msg, destport);
1264 1266
1265 if (likely(destport)) { 1267 if (likely(destport)) {
1266 p_ptr->sent++;
1267 if (likely(destnode == tipc_own_addr)) 1268 if (likely(destnode == tipc_own_addr))
1268 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1269 res = tipc_port_recv_sections(p_ptr, num_sect,
1269 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, 1270 msg_sect);
1270 destnode); 1271 else
1271 if (likely(res != -ELINKCONG)) 1272 res = tipc_link_send_sections_fast(p_ptr, msg_sect,
1273 num_sect, destnode);
1274 if (likely(res != -ELINKCONG)) {
1275 if (res > 0)
1276 p_ptr->sent++;
1272 return res; 1277 return res;
1278 }
1273 if (port_unreliable(p_ptr)) { 1279 if (port_unreliable(p_ptr)) {
1274 /* Just calculate msg length and return */ 1280 /* Just calculate msg length and return */
1275 return tipc_msg_calc_data_size(msg_sect, num_sect); 1281 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1302,12 +1308,17 @@ int tipc_send2port(u32 ref, struct tipc_portid const *dest,
1302 msg_set_destnode(msg, dest->node); 1308 msg_set_destnode(msg, dest->node);
1303 msg_set_destport(msg, dest->ref); 1309 msg_set_destport(msg, dest->ref);
1304 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE); 1310 msg_set_hdr_sz(msg, DIR_MSG_H_SIZE);
1305 p_ptr->sent++; 1311
1306 if (dest->node == tipc_own_addr) 1312 if (dest->node == tipc_own_addr)
1307 return tipc_port_recv_sections(p_ptr, num_sect, msg_sect); 1313 res = tipc_port_recv_sections(p_ptr, num_sect, msg_sect);
1308 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect, dest->node); 1314 else
1309 if (likely(res != -ELINKCONG)) 1315 res = tipc_link_send_sections_fast(p_ptr, msg_sect, num_sect,
1316 dest->node);
1317 if (likely(res != -ELINKCONG)) {
1318 if (res > 0)
1319 p_ptr->sent++;
1310 return res; 1320 return res;
1321 }
1311 if (port_unreliable(p_ptr)) { 1322 if (port_unreliable(p_ptr)) {
1312 /* Just calculate msg length and return */ 1323 /* Just calculate msg length and return */
1313 return tipc_msg_calc_data_size(msg_sect, num_sect); 1324 return tipc_msg_calc_data_size(msg_sect, num_sect);
@@ -1343,12 +1354,16 @@ int tipc_send_buf2port(u32 ref, struct tipc_portid const *dest,
1343 1354
1344 skb_push(buf, DIR_MSG_H_SIZE); 1355 skb_push(buf, DIR_MSG_H_SIZE);
1345 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE); 1356 skb_copy_to_linear_data(buf, msg, DIR_MSG_H_SIZE);
1346 p_ptr->sent++; 1357
1347 if (dest->node == tipc_own_addr) 1358 if (dest->node == tipc_own_addr)
1348 return tipc_port_recv_msg(buf); 1359 res = tipc_port_recv_msg(buf);
1349 res = tipc_send_buf_fast(buf, dest->node); 1360 else
1350 if (likely(res != -ELINKCONG)) 1361 res = tipc_send_buf_fast(buf, dest->node);
1362 if (likely(res != -ELINKCONG)) {
1363 if (res > 0)
1364 p_ptr->sent++;
1351 return res; 1365 return res;
1366 }
1352 if (port_unreliable(p_ptr)) 1367 if (port_unreliable(p_ptr))
1353 return dsz; 1368 return dsz;
1354 return -ELINKCONG; 1369 return -ELINKCONG;