aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/group.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/group.c')
-rw-r--r--net/tipc/group.c71
1 files changed, 48 insertions, 23 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c
index 12777cac638a..5f4ffae807ee 100644
--- a/net/tipc/group.c
+++ b/net/tipc/group.c
@@ -109,7 +109,8 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
109static void tipc_group_decr_active(struct tipc_group *grp, 109static void tipc_group_decr_active(struct tipc_group *grp,
110 struct tipc_member *m) 110 struct tipc_member *m)
111{ 111{
112 if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING) 112 if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING ||
113 m->state == MBR_REMITTED)
113 grp->active_cnt--; 114 grp->active_cnt--;
114} 115}
115 116
@@ -351,8 +352,7 @@ void tipc_group_update_member(struct tipc_member *m, int len)
351 if (m->window >= ADV_IDLE) 352 if (m->window >= ADV_IDLE)
352 return; 353 return;
353 354
354 if (!list_empty(&m->congested)) 355 list_del_init(&m->congested);
355 return;
356 356
357 /* Sort member into congested members' list */ 357 /* Sort member into congested members' list */
358 list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { 358 list_for_each_entry_safe(_m, tmp, &grp->congested, congested) {
@@ -369,18 +369,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack)
369 u16 prev = grp->bc_snd_nxt - 1; 369 u16 prev = grp->bc_snd_nxt - 1;
370 struct tipc_member *m; 370 struct tipc_member *m;
371 struct rb_node *n; 371 struct rb_node *n;
372 u16 ackers = 0;
372 373
373 for (n = rb_first(&grp->members); n; n = rb_next(n)) { 374 for (n = rb_first(&grp->members); n; n = rb_next(n)) {
374 m = container_of(n, struct tipc_member, tree_node); 375 m = container_of(n, struct tipc_member, tree_node);
375 if (tipc_group_is_enabled(m)) { 376 if (tipc_group_is_enabled(m)) {
376 tipc_group_update_member(m, len); 377 tipc_group_update_member(m, len);
377 m->bc_acked = prev; 378 m->bc_acked = prev;
379 ackers++;
378 } 380 }
379 } 381 }
380 382
381 /* Mark number of acknowledges to expect, if any */ 383 /* Mark number of acknowledges to expect, if any */
382 if (ack) 384 if (ack)
383 grp->bc_ackers = grp->member_cnt; 385 grp->bc_ackers = ackers;
384 grp->bc_snd_nxt++; 386 grp->bc_snd_nxt++;
385} 387}
386 388
@@ -497,6 +499,7 @@ void tipc_group_filter_msg(struct tipc_group *grp, struct sk_buff_head *inputq,
497 while ((skb = skb_peek(defq))) { 499 while ((skb = skb_peek(defq))) {
498 hdr = buf_msg(skb); 500 hdr = buf_msg(skb);
499 mtyp = msg_type(hdr); 501 mtyp = msg_type(hdr);
502 blks = msg_blocks(hdr);
500 deliver = true; 503 deliver = true;
501 ack = false; 504 ack = false;
502 update = false; 505 update = false;
@@ -546,7 +549,6 @@ void tipc_group_filter_msg(struct tipc_group *grp, struct sk_buff_head *inputq,
546 if (!update) 549 if (!update)
547 continue; 550 continue;
548 551
549 blks = msg_blocks(hdr);
550 tipc_group_update_rcv_win(grp, blks, node, port, xmitq); 552 tipc_group_update_rcv_win(grp, blks, node, port, xmitq);
551 } 553 }
552 return; 554 return;
@@ -561,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
561 int max_active = grp->max_active; 563 int max_active = grp->max_active;
562 int reclaim_limit = max_active * 3 / 4; 564 int reclaim_limit = max_active * 3 / 4;
563 int active_cnt = grp->active_cnt; 565 int active_cnt = grp->active_cnt;
564 struct tipc_member *m, *rm; 566 struct tipc_member *m, *rm, *pm;
565 567
566 m = tipc_group_find_member(grp, node, port); 568 m = tipc_group_find_member(grp, node, port);
567 if (!m) 569 if (!m)
@@ -604,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
604 pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); 606 pr_warn_ratelimited("Rcv unexpected msg after REMIT\n");
605 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); 607 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
606 } 608 }
609 grp->active_cnt--;
610 list_del_init(&m->list);
611 if (list_empty(&grp->pending))
612 return;
613
614 /* Set oldest pending member to active and advertise */
615 pm = list_first_entry(&grp->pending, struct tipc_member, list);
616 pm->state = MBR_ACTIVE;
617 list_move_tail(&pm->list, &grp->active);
618 grp->active_cnt++;
619 tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
607 break; 620 break;
608 case MBR_RECLAIMING: 621 case MBR_RECLAIMING:
609 case MBR_DISCOVERED: 622 case MBR_DISCOVERED:
@@ -648,6 +661,7 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
648 } else if (mtyp == GRP_REMIT_MSG) { 661 } else if (mtyp == GRP_REMIT_MSG) {
649 msg_set_grp_remitted(hdr, m->window); 662 msg_set_grp_remitted(hdr, m->window);
650 } 663 }
664 msg_set_dest_droppable(hdr, true);
651 __skb_queue_tail(xmitq, skb); 665 __skb_queue_tail(xmitq, skb);
652} 666}
653 667
@@ -689,15 +703,16 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
689 msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); 703 msg_set_grp_bc_seqno(ehdr, m->bc_syncpt);
690 __skb_queue_tail(inputq, m->event_msg); 704 __skb_queue_tail(inputq, m->event_msg);
691 } 705 }
692 if (m->window < ADV_IDLE) 706 list_del_init(&m->congested);
693 tipc_group_update_member(m, 0); 707 tipc_group_update_member(m, 0);
694 else
695 list_del_init(&m->congested);
696 return; 708 return;
697 case GRP_LEAVE_MSG: 709 case GRP_LEAVE_MSG:
698 if (!m) 710 if (!m)
699 return; 711 return;
700 m->bc_syncpt = msg_grp_bc_syncpt(hdr); 712 m->bc_syncpt = msg_grp_bc_syncpt(hdr);
713 list_del_init(&m->list);
714 list_del_init(&m->congested);
715 *usr_wakeup = true;
701 716
702 /* Wait until WITHDRAW event is received */ 717 /* Wait until WITHDRAW event is received */
703 if (m->state != MBR_LEAVING) { 718 if (m->state != MBR_LEAVING) {
@@ -709,8 +724,6 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
709 ehdr = buf_msg(m->event_msg); 724 ehdr = buf_msg(m->event_msg);
710 msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); 725 msg_set_grp_bc_seqno(ehdr, m->bc_syncpt);
711 __skb_queue_tail(inputq, m->event_msg); 726 __skb_queue_tail(inputq, m->event_msg);
712 *usr_wakeup = true;
713 list_del_init(&m->congested);
714 return; 727 return;
715 case GRP_ADV_MSG: 728 case GRP_ADV_MSG:
716 if (!m) 729 if (!m)
@@ -741,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
741 if (!m || m->state != MBR_RECLAIMING) 754 if (!m || m->state != MBR_RECLAIMING)
742 return; 755 return;
743 756
744 list_del_init(&m->list);
745 grp->active_cnt--;
746 remitted = msg_grp_remitted(hdr); 757 remitted = msg_grp_remitted(hdr);
747 758
748 /* Messages preceding the REMIT still in receive queue */ 759 /* Messages preceding the REMIT still in receive queue */
749 if (m->advertised > remitted) { 760 if (m->advertised > remitted) {
750 m->state = MBR_REMITTED; 761 m->state = MBR_REMITTED;
751 in_flight = m->advertised - remitted; 762 in_flight = m->advertised - remitted;
763 m->advertised = ADV_IDLE + in_flight;
764 return;
752 } 765 }
753 /* All messages preceding the REMIT have been read */ 766 /* All messages preceding the REMIT have been read */
754 if (m->advertised <= remitted) { 767 if (m->advertised <= remitted) {
@@ -760,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
760 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); 773 tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
761 774
762 m->advertised = ADV_IDLE + in_flight; 775 m->advertised = ADV_IDLE + in_flight;
776 grp->active_cnt--;
777 list_del_init(&m->list);
763 778
764 /* Set oldest pending member to active and advertise */ 779 /* Set oldest pending member to active and advertise */
765 if (list_empty(&grp->pending)) 780 if (list_empty(&grp->pending))
@@ -849,19 +864,29 @@ void tipc_group_member_evt(struct tipc_group *grp,
849 *usr_wakeup = true; 864 *usr_wakeup = true;
850 m->usr_pending = false; 865 m->usr_pending = false;
851 node_up = tipc_node_is_up(net, node); 866 node_up = tipc_node_is_up(net, node);
852 867 m->event_msg = NULL;
853 /* Hold back event if more messages might be expected */ 868
854 if (m->state != MBR_LEAVING && node_up) { 869 if (node_up) {
855 m->event_msg = skb; 870 /* Hold back event if a LEAVE msg should be expected */
856 tipc_group_decr_active(grp, m); 871 if (m->state != MBR_LEAVING) {
857 m->state = MBR_LEAVING; 872 m->event_msg = skb;
858 } else { 873 tipc_group_decr_active(grp, m);
859 if (node_up) 874 m->state = MBR_LEAVING;
875 } else {
860 msg_set_grp_bc_seqno(hdr, m->bc_syncpt); 876 msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
861 else 877 __skb_queue_tail(inputq, skb);
878 }
879 } else {
880 if (m->state != MBR_LEAVING) {
881 tipc_group_decr_active(grp, m);
882 m->state = MBR_LEAVING;
862 msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); 883 msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt);
884 } else {
885 msg_set_grp_bc_seqno(hdr, m->bc_syncpt);
886 }
863 __skb_queue_tail(inputq, skb); 887 __skb_queue_tail(inputq, skb);
864 } 888 }
889 list_del_init(&m->list);
865 list_del_init(&m->congested); 890 list_del_init(&m->congested);
866 } 891 }
867 *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); 892 *sk_rcvbuf = tipc_group_rcvbuf_limit(grp);