diff options
Diffstat (limited to 'net/tipc/link.c')
-rw-r--r-- | net/tipc/link.c | 124 |
1 files changed, 31 insertions, 93 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index 69cd9bf3f561..3d73144a1ccc 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
@@ -386,14 +386,7 @@ exit: | |||
386 | */ | 386 | */ |
387 | static void link_release_outqueue(struct tipc_link *l_ptr) | 387 | static void link_release_outqueue(struct tipc_link *l_ptr) |
388 | { | 388 | { |
389 | struct sk_buff *buf = l_ptr->first_out; | 389 | kfree_skb_list(l_ptr->first_out); |
390 | struct sk_buff *next; | ||
391 | |||
392 | while (buf) { | ||
393 | next = buf->next; | ||
394 | kfree_skb(buf); | ||
395 | buf = next; | ||
396 | } | ||
397 | l_ptr->first_out = NULL; | 390 | l_ptr->first_out = NULL; |
398 | l_ptr->out_queue_size = 0; | 391 | l_ptr->out_queue_size = 0; |
399 | } | 392 | } |
@@ -415,32 +408,15 @@ void tipc_link_reset_fragments(struct tipc_link *l_ptr) | |||
415 | */ | 408 | */ |
416 | void tipc_link_stop(struct tipc_link *l_ptr) | 409 | void tipc_link_stop(struct tipc_link *l_ptr) |
417 | { | 410 | { |
418 | struct sk_buff *buf; | 411 | kfree_skb_list(l_ptr->oldest_deferred_in); |
419 | struct sk_buff *next; | 412 | kfree_skb_list(l_ptr->first_out); |
420 | |||
421 | buf = l_ptr->oldest_deferred_in; | ||
422 | while (buf) { | ||
423 | next = buf->next; | ||
424 | kfree_skb(buf); | ||
425 | buf = next; | ||
426 | } | ||
427 | |||
428 | buf = l_ptr->first_out; | ||
429 | while (buf) { | ||
430 | next = buf->next; | ||
431 | kfree_skb(buf); | ||
432 | buf = next; | ||
433 | } | ||
434 | |||
435 | tipc_link_reset_fragments(l_ptr); | 413 | tipc_link_reset_fragments(l_ptr); |
436 | |||
437 | kfree_skb(l_ptr->proto_msg_queue); | 414 | kfree_skb(l_ptr->proto_msg_queue); |
438 | l_ptr->proto_msg_queue = NULL; | 415 | l_ptr->proto_msg_queue = NULL; |
439 | } | 416 | } |
440 | 417 | ||
441 | void tipc_link_reset(struct tipc_link *l_ptr) | 418 | void tipc_link_reset(struct tipc_link *l_ptr) |
442 | { | 419 | { |
443 | struct sk_buff *buf; | ||
444 | u32 prev_state = l_ptr->state; | 420 | u32 prev_state = l_ptr->state; |
445 | u32 checkpoint = l_ptr->next_in_no; | 421 | u32 checkpoint = l_ptr->next_in_no; |
446 | int was_active_link = tipc_link_is_active(l_ptr); | 422 | int was_active_link = tipc_link_is_active(l_ptr); |
@@ -471,12 +447,7 @@ void tipc_link_reset(struct tipc_link *l_ptr) | |||
471 | link_release_outqueue(l_ptr); | 447 | link_release_outqueue(l_ptr); |
472 | kfree_skb(l_ptr->proto_msg_queue); | 448 | kfree_skb(l_ptr->proto_msg_queue); |
473 | l_ptr->proto_msg_queue = NULL; | 449 | l_ptr->proto_msg_queue = NULL; |
474 | buf = l_ptr->oldest_deferred_in; | 450 | kfree_skb_list(l_ptr->oldest_deferred_in); |
475 | while (buf) { | ||
476 | struct sk_buff *next = buf->next; | ||
477 | kfree_skb(buf); | ||
478 | buf = next; | ||
479 | } | ||
480 | if (!list_empty(&l_ptr->waiting_ports)) | 451 | if (!list_empty(&l_ptr->waiting_ports)) |
481 | tipc_link_wakeup_ports(l_ptr, 1); | 452 | tipc_link_wakeup_ports(l_ptr, 1); |
482 | 453 | ||
@@ -517,10 +488,11 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event) | |||
517 | if (!l_ptr->started && (event != STARTING_EVT)) | 488 | if (!l_ptr->started && (event != STARTING_EVT)) |
518 | return; /* Not yet. */ | 489 | return; /* Not yet. */ |
519 | 490 | ||
520 | if (link_blocked(l_ptr)) { | 491 | /* Check whether changeover is going on */ |
492 | if (l_ptr->exp_msg_count) { | ||
521 | if (event == TIMEOUT_EVT) | 493 | if (event == TIMEOUT_EVT) |
522 | link_set_timer(l_ptr, cont_intv); | 494 | link_set_timer(l_ptr, cont_intv); |
523 | return; /* Changeover going on */ | 495 | return; |
524 | } | 496 | } |
525 | 497 | ||
526 | switch (l_ptr->state) { | 498 | switch (l_ptr->state) { |
@@ -790,8 +762,7 @@ int tipc_link_send_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
790 | return link_send_long_buf(l_ptr, buf); | 762 | return link_send_long_buf(l_ptr, buf); |
791 | 763 | ||
792 | /* Packet can be queued or sent. */ | 764 | /* Packet can be queued or sent. */ |
793 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr) && | 765 | if (likely(!link_congested(l_ptr))) { |
794 | !link_congested(l_ptr))) { | ||
795 | link_add_to_outqueue(l_ptr, buf, msg); | 766 | link_add_to_outqueue(l_ptr, buf, msg); |
796 | 767 | ||
797 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); | 768 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
@@ -957,14 +928,13 @@ static int link_send_buf_fast(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
957 | 928 | ||
958 | if (likely(!link_congested(l_ptr))) { | 929 | if (likely(!link_congested(l_ptr))) { |
959 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { | 930 | if (likely(msg_size(msg) <= l_ptr->max_pkt)) { |
960 | if (likely(!tipc_bearer_blocked(l_ptr->b_ptr))) { | 931 | link_add_to_outqueue(l_ptr, buf, msg); |
961 | link_add_to_outqueue(l_ptr, buf, msg); | 932 | tipc_bearer_send(l_ptr->b_ptr, buf, |
962 | tipc_bearer_send(l_ptr->b_ptr, buf, | 933 | &l_ptr->media_addr); |
963 | &l_ptr->media_addr); | 934 | l_ptr->unacked_window = 0; |
964 | l_ptr->unacked_window = 0; | 935 | return res; |
965 | return res; | 936 | } |
966 | } | 937 | else |
967 | } else | ||
968 | *used_max_pkt = l_ptr->max_pkt; | 938 | *used_max_pkt = l_ptr->max_pkt; |
969 | } | 939 | } |
970 | return tipc_link_send_buf(l_ptr, buf); /* All other cases */ | 940 | return tipc_link_send_buf(l_ptr, buf); /* All other cases */ |
@@ -1013,8 +983,7 @@ exit: | |||
1013 | } | 983 | } |
1014 | 984 | ||
1015 | /* Exit if link (or bearer) is congested */ | 985 | /* Exit if link (or bearer) is congested */ |
1016 | if (link_congested(l_ptr) || | 986 | if (link_congested(l_ptr)) { |
1017 | tipc_bearer_blocked(l_ptr->b_ptr)) { | ||
1018 | res = link_schedule_port(l_ptr, | 987 | res = link_schedule_port(l_ptr, |
1019 | sender->ref, res); | 988 | sender->ref, res); |
1020 | goto exit; | 989 | goto exit; |
@@ -1127,10 +1096,7 @@ again: | |||
1127 | if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { | 1096 | if (copy_from_user(buf->data + fragm_crs, sect_crs, sz)) { |
1128 | res = -EFAULT; | 1097 | res = -EFAULT; |
1129 | error: | 1098 | error: |
1130 | for (; buf_chain; buf_chain = buf) { | 1099 | kfree_skb_list(buf_chain); |
1131 | buf = buf_chain->next; | ||
1132 | kfree_skb(buf_chain); | ||
1133 | } | ||
1134 | return res; | 1100 | return res; |
1135 | } | 1101 | } |
1136 | sect_crs += sz; | 1102 | sect_crs += sz; |
@@ -1180,18 +1146,12 @@ error: | |||
1180 | if (l_ptr->max_pkt < max_pkt) { | 1146 | if (l_ptr->max_pkt < max_pkt) { |
1181 | sender->max_pkt = l_ptr->max_pkt; | 1147 | sender->max_pkt = l_ptr->max_pkt; |
1182 | tipc_node_unlock(node); | 1148 | tipc_node_unlock(node); |
1183 | for (; buf_chain; buf_chain = buf) { | 1149 | kfree_skb_list(buf_chain); |
1184 | buf = buf_chain->next; | ||
1185 | kfree_skb(buf_chain); | ||
1186 | } | ||
1187 | goto again; | 1150 | goto again; |
1188 | } | 1151 | } |
1189 | } else { | 1152 | } else { |
1190 | reject: | 1153 | reject: |
1191 | for (; buf_chain; buf_chain = buf) { | 1154 | kfree_skb_list(buf_chain); |
1192 | buf = buf_chain->next; | ||
1193 | kfree_skb(buf_chain); | ||
1194 | } | ||
1195 | return tipc_port_reject_sections(sender, hdr, msg_sect, | 1155 | return tipc_port_reject_sections(sender, hdr, msg_sect, |
1196 | len, TIPC_ERR_NO_NODE); | 1156 | len, TIPC_ERR_NO_NODE); |
1197 | } | 1157 | } |
@@ -1281,9 +1241,6 @@ void tipc_link_push_queue(struct tipc_link *l_ptr) | |||
1281 | { | 1241 | { |
1282 | u32 res; | 1242 | u32 res; |
1283 | 1243 | ||
1284 | if (tipc_bearer_blocked(l_ptr->b_ptr)) | ||
1285 | return; | ||
1286 | |||
1287 | do { | 1244 | do { |
1288 | res = tipc_link_push_packet(l_ptr); | 1245 | res = tipc_link_push_packet(l_ptr); |
1289 | } while (!res); | 1246 | } while (!res); |
@@ -1370,26 +1327,15 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf, | |||
1370 | 1327 | ||
1371 | msg = buf_msg(buf); | 1328 | msg = buf_msg(buf); |
1372 | 1329 | ||
1373 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { | 1330 | /* Detect repeated retransmit failures */ |
1374 | if (l_ptr->retransm_queue_size == 0) { | 1331 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { |
1375 | l_ptr->retransm_queue_head = msg_seqno(msg); | 1332 | if (++l_ptr->stale_count > 100) { |
1376 | l_ptr->retransm_queue_size = retransmits; | 1333 | link_retransmit_failure(l_ptr, buf); |
1377 | } else { | 1334 | return; |
1378 | pr_err("Unexpected retransmit on link %s (qsize=%d)\n", | ||
1379 | l_ptr->name, l_ptr->retransm_queue_size); | ||
1380 | } | 1335 | } |
1381 | return; | ||
1382 | } else { | 1336 | } else { |
1383 | /* Detect repeated retransmit failures on unblocked bearer */ | 1337 | l_ptr->last_retransmitted = msg_seqno(msg); |
1384 | if (l_ptr->last_retransmitted == msg_seqno(msg)) { | 1338 | l_ptr->stale_count = 1; |
1385 | if (++l_ptr->stale_count > 100) { | ||
1386 | link_retransmit_failure(l_ptr, buf); | ||
1387 | return; | ||
1388 | } | ||
1389 | } else { | ||
1390 | l_ptr->last_retransmitted = msg_seqno(msg); | ||
1391 | l_ptr->stale_count = 1; | ||
1392 | } | ||
1393 | } | 1339 | } |
1394 | 1340 | ||
1395 | while (retransmits && (buf != l_ptr->next_out) && buf) { | 1341 | while (retransmits && (buf != l_ptr->next_out) && buf) { |
@@ -1786,7 +1732,8 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
1786 | l_ptr->proto_msg_queue = NULL; | 1732 | l_ptr->proto_msg_queue = NULL; |
1787 | } | 1733 | } |
1788 | 1734 | ||
1789 | if (link_blocked(l_ptr)) | 1735 | /* Don't send protocol message during link changeover */ |
1736 | if (l_ptr->exp_msg_count) | ||
1790 | return; | 1737 | return; |
1791 | 1738 | ||
1792 | /* Abort non-RESET send if communication with node is prohibited */ | 1739 | /* Abort non-RESET send if communication with node is prohibited */ |
@@ -1861,12 +1808,6 @@ void tipc_link_send_proto_msg(struct tipc_link *l_ptr, u32 msg_typ, | |||
1861 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); | 1808 | skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg)); |
1862 | buf->priority = TC_PRIO_CONTROL; | 1809 | buf->priority = TC_PRIO_CONTROL; |
1863 | 1810 | ||
1864 | /* Defer message if bearer is already blocked */ | ||
1865 | if (tipc_bearer_blocked(l_ptr->b_ptr)) { | ||
1866 | l_ptr->proto_msg_queue = buf; | ||
1867 | return; | ||
1868 | } | ||
1869 | |||
1870 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); | 1811 | tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr); |
1871 | l_ptr->unacked_window = 0; | 1812 | l_ptr->unacked_window = 0; |
1872 | kfree_skb(buf); | 1813 | kfree_skb(buf); |
@@ -1885,7 +1826,8 @@ static void link_recv_proto_msg(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
1885 | u32 msg_tol; | 1826 | u32 msg_tol; |
1886 | struct tipc_msg *msg = buf_msg(buf); | 1827 | struct tipc_msg *msg = buf_msg(buf); |
1887 | 1828 | ||
1888 | if (link_blocked(l_ptr)) | 1829 | /* Discard protocol message during link changeover */ |
1830 | if (l_ptr->exp_msg_count) | ||
1889 | goto exit; | 1831 | goto exit; |
1890 | 1832 | ||
1891 | /* record unnumbered packet arrival (force mismatch on next timeout) */ | 1833 | /* record unnumbered packet arrival (force mismatch on next timeout) */ |
@@ -2306,11 +2248,7 @@ static int link_send_long_buf(struct tipc_link *l_ptr, struct sk_buff *buf) | |||
2306 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); | 2248 | fragm = tipc_buf_acquire(fragm_sz + INT_H_SIZE); |
2307 | if (fragm == NULL) { | 2249 | if (fragm == NULL) { |
2308 | kfree_skb(buf); | 2250 | kfree_skb(buf); |
2309 | while (buf_chain) { | 2251 | kfree_skb_list(buf_chain); |
2310 | buf = buf_chain; | ||
2311 | buf_chain = buf_chain->next; | ||
2312 | kfree_skb(buf); | ||
2313 | } | ||
2314 | return -ENOMEM; | 2252 | return -ENOMEM; |
2315 | } | 2253 | } |
2316 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); | 2254 | msg_set_size(&fragm_hdr, fragm_sz + INT_H_SIZE); |