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); |
