diff options
-rw-r--r-- | net/tipc/group.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/net/tipc/group.c b/net/tipc/group.c index 8e12ab55346b..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, | |||
109 | static void tipc_group_decr_active(struct tipc_group *grp, | 109 | static 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 | ||
@@ -562,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
562 | int max_active = grp->max_active; | 563 | int max_active = grp->max_active; |
563 | int reclaim_limit = max_active * 3 / 4; | 564 | int reclaim_limit = max_active * 3 / 4; |
564 | int active_cnt = grp->active_cnt; | 565 | int active_cnt = grp->active_cnt; |
565 | struct tipc_member *m, *rm; | 566 | struct tipc_member *m, *rm, *pm; |
566 | 567 | ||
567 | m = tipc_group_find_member(grp, node, port); | 568 | m = tipc_group_find_member(grp, node, port); |
568 | if (!m) | 569 | if (!m) |
@@ -605,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
605 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); | 606 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); |
606 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 607 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
607 | } | 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); | ||
608 | break; | 620 | break; |
609 | case MBR_RECLAIMING: | 621 | case MBR_RECLAIMING: |
610 | case MBR_DISCOVERED: | 622 | case MBR_DISCOVERED: |
@@ -742,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
742 | if (!m || m->state != MBR_RECLAIMING) | 754 | if (!m || m->state != MBR_RECLAIMING) |
743 | return; | 755 | return; |
744 | 756 | ||
745 | list_del_init(&m->list); | ||
746 | grp->active_cnt--; | ||
747 | remitted = msg_grp_remitted(hdr); | 757 | remitted = msg_grp_remitted(hdr); |
748 | 758 | ||
749 | /* Messages preceding the REMIT still in receive queue */ | 759 | /* Messages preceding the REMIT still in receive queue */ |
750 | if (m->advertised > remitted) { | 760 | if (m->advertised > remitted) { |
751 | m->state = MBR_REMITTED; | 761 | m->state = MBR_REMITTED; |
752 | in_flight = m->advertised - remitted; | 762 | in_flight = m->advertised - remitted; |
763 | m->advertised = ADV_IDLE + in_flight; | ||
764 | return; | ||
753 | } | 765 | } |
754 | /* All messages preceding the REMIT have been read */ | 766 | /* All messages preceding the REMIT have been read */ |
755 | if (m->advertised <= remitted) { | 767 | if (m->advertised <= remitted) { |
@@ -761,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
761 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 773 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
762 | 774 | ||
763 | m->advertised = ADV_IDLE + in_flight; | 775 | m->advertised = ADV_IDLE + in_flight; |
776 | grp->active_cnt--; | ||
777 | list_del_init(&m->list); | ||
764 | 778 | ||
765 | /* Set oldest pending member to active and advertise */ | 779 | /* Set oldest pending member to active and advertise */ |
766 | if (list_empty(&grp->pending)) | 780 | if (list_empty(&grp->pending)) |