diff options
author | Ying Xue <ying.xue@windriver.com> | 2012-11-14 22:34:45 -0500 |
---|---|---|
committer | Paul Gortmaker <paul.gortmaker@windriver.com> | 2012-11-21 20:07:25 -0500 |
commit | 3c294cb374bf7ad6f5c2763f994d75935fb7814d (patch) | |
tree | f85f567d4c69ae8dbbbdce32022d6f306cf7fc35 /net/tipc/link.c | |
parent | 7503115107e5862870eaf5133627051b2e23ac0a (diff) |
tipc: remove the bearer congestion mechanism
Currently at the TIPC bearer layer there is the following congestion
mechanism:
Once sending packets has failed via that bearer, the bearer will be
flagged as being in congested state at once. During bearer congestion,
all packets arriving at link will be queued on the link's outgoing
buffer. When we detect that the state of bearer congestion has
relaxed (e.g. some packets are received from the bearer) we will try
our best to push all packets in the link's outgoing buffer until the
buffer is empty, or until the bearer is congested again.
However, in fact the TIPC bearer never receives any feedback from the
device layer whether a send was successful or not, so it must always
assume it was successful. Therefore, the bearer congestion mechanism
as it exists currently is of no value.
But the bearer blocking state is still useful for us. For example,
when the physical media goes down/up, we need to change the state of
the links bound to the bearer. So the code maintaing the state
information is not removed.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 117 |
1 files changed, 37 insertions, 80 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a79c755cb417..0cc64800ab93 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -872,17 +872,12 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
872 | return link_send_long_buf(l_ptr, buf); | 872 | return link_send_long_buf(l_ptr, buf); |
873 | 873 | ||
874 | /* Packet can be queued or sent. */ | 874 | /* Packet can be queued or sent. */ |
875 | if (likely(!tipc_bearer_congested(l_ptr->b_ptr, l_ptr) && | 875 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr) && |
876 | !link_congested(l_ptr))) { | 876 | !link_congested(l_ptr))) { |
877 | link_add_to_outqueue(l_ptr, buf, msg); | 877 | link_add_to_outqueue(l_ptr, buf, msg); |
878 | 878 | ||
879 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr))) { | 879 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
880 | l_ptr->unacked_window = 0; | 880 | l_ptr->unacked_window = 0; |
881 | } else { | ||
882 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
883 | l_ptr->stats.bearer_congs++; | ||
884 | l_ptr->next_out = buf; | ||
885 | } | ||
886 | return dsz; | 881 | return dsz; |
887 | } | 882 | } |
888 | /* Congestion: can message be bundled ? */ | 883 | /* Congestion: can message be bundled ? */ |
@@ -891,10 +886,8 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
891 | 886 | ||
892 | /* Try adding message to an existing bundle */ | 887 | /* Try adding message to an existing bundle */ |
893 | if (l_ptr->next_out && | 888 | if (l_ptr->next_out && |
894 | link_bundle_buf(l_ptr, l_ptr->last_out, buf)) { | 889 | link_bundle_buf(l_ptr, l_ptr->last_out, buf)) |
895 | tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); | ||
896 | return dsz; | 890 | return dsz; |
897 | } | ||
898 | 891 | ||
899 | /* Try creating a new bundle */ | 892 | /* Try creating a new bundle */ |
900 | if (size <= max_packet * 2 / 3) { | 893 | if (size <= max_packet * 2 / 3) { |
@@ -917,7 +910,6 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
917 | if (!l_ptr->next_out) | 910 | if (!l_ptr->next_out) |
918 | l_ptr->next_out = buf; | 911 | l_ptr->next_out = buf; |
919 | link_add_to_outqueue(l_ptr, buf, msg); | 912 | link_add_to_outqueue(l_ptr, buf, msg); |
920 | tipc_bearer_resolve_congestion(l_ptr->b_ptr, l_ptr); | ||
921 | return dsz; | 913 | return dsz; |
922 | } | 914 | } |
923 | 915 | ||
@@ -1006,16 +998,11 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1006 | 998 | ||
1007 | if (likely(!link_congested(l_ptr))) { | 999 | if (likely(!link_congested(l_ptr))) { |
1008 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { | 1000 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { |
1009 | if (likely(list_empty(&l_ptr->b_ptr->cong_links))) { | 1001 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr))) { |
1010 | link_add_to_outqueue(l_ptr, buf, msg); | 1002 | link_add_to_outqueue(l_ptr, buf, msg); |
1011 | if (likely(tipc_bearer_send(l_ptr->b_ptr, buf, | 1003 | tipc_bearer_send(l_ptr->b_ptr, buf, |
1012 | &l_ptr->media_addr))) { | 1004 | &l_ptr->media_addr); |
1013 | l_ptr->unacked_window = 0; | 1005 | l_ptr->unacked_window = 0; |
1014 | return res; | ||
1015 | } | ||
1016 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
1017 | l_ptr->stats.bearer_congs++; | ||
1018 | l_ptr->next_out = buf; | ||
1019 | return res; | 1006 | return res; |
1020 | } | 1007 | } |
1021 | } else | 1008 | } else |
@@ -1106,7 +1093,7 @@ exit: | |||
1106 | 1093 | ||
1107 | /* Exit if link (or bearer) is congested */ | 1094 | /* Exit if link (or bearer) is congested */ |
1108 | if (link_congested(l_ptr) || | 1095 | if (link_congested(l_ptr) || |
1109 | !list_empty(&l_ptr->b_ptr->cong_links)) { | 1096 | tipc_bearer_blocked(l_ptr->b_ptr)) { |
1110 | res = link_schedule_port(l_ptr, | 1097 | res = link_schedule_port(l_ptr, |
1111 | sender->ref, res); | 1098 | sender->ref, res); |
1112 | goto exit; | 1099 | goto exit; |
@@ -1329,15 +1316,11 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
1329 | if (r_q_size && buf) { | 1316 | if (r_q_size && buf) { |
1330 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1317 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
1331 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1318 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
1332 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1319 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1333 | l_ptr->retransm_queue_head = mod(++r_q_head); | 1320 | l_ptr->retransm_queue_head = mod(++r_q_head); |
1334 | l_ptr->retransm_queue_size = --r_q_size; | 1321 | l_ptr->retransm_queue_size = --r_q_size; |
1335 | l_ptr->stats.retransmitted++; | 1322 | l_ptr->stats.retransmitted++; |
1336 | return 0; | 1323 | return 0; |
1337 | } else { | ||
1338 | l_ptr->stats.bearer_congs++; | ||
1339 | return PUSH_FAILED; | ||
1340 | } | ||
1341 | } | 1324 | } |
1342 | 1325 | ||
1343 | /* Send deferred protocol message, if any: */ | 1326 | /* Send deferred protocol message, if any: */ |
@@ -1345,15 +1328,11 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
1345 | if (buf) { | 1328 | if (buf) { |
1346 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); | 1329 | msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1)); |
1347 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); | 1330 | msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in); |
1348 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1331 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1349 | l_ptr->unacked_window = 0; | 1332 | l_ptr->unacked_window = 0; |
1350 | kfree_skb(buf); | 1333 | kfree_skb(buf); |
1351 | l_ptr->proto_msg_queue = NULL; | 1334 | l_ptr->proto_msg_queue = NULL; |
1352 | return 0; | 1335 | return 0; |
1353 | } else { | ||
1354 | l_ptr->stats.bearer_congs++; | ||
1355 | return PUSH_FAILED; | ||
1356 | } | ||
1357 | } | 1336 | } |
1358 | 1337 | ||
1359 | /* Send one deferred data message, if send window not full: */ | 1338 | /* Send one deferred data message, if send window not full: */ |
@@ -1366,18 +1345,14 @@ u32 tipc_link_push_packet(struct tipc_link *l_ptr) | |||
1366 | if (mod(next - first) < l_ptr->queue_limit[0]) { | 1345 | if (mod(next - first) < l_ptr->queue_limit[0]) { |
1367 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); | 1346 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); |
1368 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 1347 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
1369 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1348 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1370 | if (msg_user(msg) == MSG_BUNDLER) | 1349 | if (msg_user(msg) == MSG_BUNDLER) |
1371 | msg_set_type(msg, CLOSED_MSG); | 1350 | msg_set_type(msg, CLOSED_MSG); |
1372 | l_ptr->next_out = buf->next; | 1351 | l_ptr->next_out = buf->next; |
1373 | return 0; | 1352 | return 0; |
1374 | } else { | ||
1375 | l_ptr->stats.bearer_congs++; | ||
1376 | return PUSH_FAILED; | ||
1377 | } | ||
1378 | } | 1353 | } |
1379 | } | 1354 | } |
1380 | return PUSH_FINISHED; | 1355 | return 1; |
1381 | } | 1356 | } |
1382 | 1357 | ||
1383 | /* | 1358 | /* |
@@ -1388,15 +1363,12 @@ void tipc_link_push_queue(struct tipc_link *l_ptr) | |||
1388 | { | 1363 | { |
1389 | u32 res; | 1364 | u32 res; |
1390 | 1365 | ||
1391 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) | 1366 | if (tipc_bearer_blocked(l_ptr->b_ptr)) |
1392 | return; | 1367 | return; |
1393 | 1368 | ||
1394 | do { | 1369 | do { |
1395 | res = tipc_link_push_packet(l_ptr); | 1370 | res = tipc_link_push_packet(l_ptr); |
1396 | } while (!res); | 1371 | } while (!res); |
1397 | |||
1398 | if (res == PUSH_FAILED) | ||
1399 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
1400 | } | 1372 | } |
1401 | 1373 | ||
1402 | static void link_reset_all(unsigned long addr) | 1374 | static void link_reset_all(unsigned long addr) |
@@ -1481,7 +1453,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1481 | 1453 | ||
1482 | msg = buf_msg(buf); | 1454 | msg = buf_msg(buf); |
1483 | 1455 | ||
1484 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1456 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { |
1485 | if (l_ptr->retransm_queue_size == 0) { | 1457 | if (l_ptr->retransm_queue_size == 0) { |
1486 | l_ptr->retransm_queue_head = msg_seqno(msg); | 1458 | l_ptr->retransm_queue_head = msg_seqno(msg); |
1487 | l_ptr->retransm_queue_size = retransmits; | 1459 | l_ptr->retransm_queue_size = retransmits; |
@@ -1491,7 +1463,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1491 | } | 1463 | } |
1492 | return; | 1464 | return; |
1493 | } else { | 1465 | } else { |
1494 | /* Detect repeated retransmit failures on uncongested bearer */ | 1466 | /* Detect repeated retransmit failures on unblocked bearer */ |
1495 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { | 1467 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { |
1496 | if (++l_ptr->stale_count > 100) { | 1468 | if (++l_ptr->stale_count > 100) { |
1497 | link_retransmit_failure(l_ptr, buf); | 1469 | link_retransmit_failure(l_ptr, buf); |
@@ -1507,17 +1479,10 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1507 | msg = buf_msg(buf); | 1479 | msg = buf_msg(buf); |
1508 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); | 1480 | msg_set_ack(msg, mod(l_ptr->next_in_no - 1)); |
1509 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); | 1481 | msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in); |
1510 | if (tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | 1482 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1511 | buf = buf->next; | 1483 | buf = buf->next; |
1512 | retransmits--; | 1484 | retransmits--; |
1513 | l_ptr->stats.retransmitted++; | 1485 | l_ptr->stats.retransmitted++; |
1514 | } else { | ||
1515 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
1516 | l_ptr->stats.bearer_congs++; | ||
1517 | l_ptr->retransm_queue_head = buf_seqno(buf); | ||
1518 | l_ptr->retransm_queue_size = retransmits; | ||
1519 | return; | ||
1520 | } | ||
1521 | } | 1486 | } |
1522 | 1487 | ||
1523 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; | 1488 | l_ptr->retransm_queue_head = l_ptr->retransm_queue_size = 0; |
@@ -1972,21 +1937,13 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
1972 | 1937 | ||
1973 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1938 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
1974 | 1939 | ||
1975 | /* Defer message if bearer is already congested */ | 1940 | /* Defer message if bearer is already blocked */ |
1976 | if (tipc_bearer_congested(l_ptr->b_ptr, l_ptr)) { | 1941 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { |
1977 | l_ptr->proto_msg_queue = buf; | ||
1978 | return; | ||
1979 | } | ||
1980 | |||
1981 | /* Defer message if attempting to send results in bearer congestion */ | ||
1982 | if (!tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr)) { | ||
1983 | tipc_bearer_schedule(l_ptr->b_ptr, l_ptr); | ||
1984 | l_ptr->proto_msg_queue = buf; | 1942 | l_ptr->proto_msg_queue = buf; |
1985 | l_ptr->stats.bearer_congs++; | ||
1986 | return; | 1943 | return; |
1987 | } | 1944 | } |
1988 | 1945 | ||
1989 | /* Discard message if it was sent successfully */ | 1946 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1990 | l_ptr->unacked_window = 0; | 1947 | l_ptr->unacked_window = 0; |
1991 | kfree_skb(buf); | 1948 | kfree_skb(buf); |
1992 | } | 1949 | } |
@@ -2937,8 +2894,8 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size) | |||
2937 | s->sent_nacks, s->sent_acks, s->retransmitted); | 2894 | s->sent_nacks, s->sent_acks, s->retransmitted); |
2938 | 2895 | ||
2939 | ret += tipc_snprintf(buf + ret, buf_size - ret, | 2896 | ret += tipc_snprintf(buf + ret, buf_size - ret, |
2940 | " Congestion bearer:%u link:%u Send queue" | 2897 | " Congestion link:%u Send queue" |
2941 | " max:%u avg:%u\n", s->bearer_congs, s->link_congs, | 2898 | " max:%u avg:%u\n", s->link_congs, |
2942 | s->max_queue_sz, s->queue_sz_counts ? | 2899 | s->max_queue_sz, s->queue_sz_counts ? |
2943 | (s->accu_queue_sz / s->queue_sz_counts) : 0); | 2900 | (s->accu_queue_sz / s->queue_sz_counts) : 0); |
2944 | 2901 | ||