Skip to content

Commit d12d2e1

Browse files
Jon Maloydavem330
authored andcommitted
tipc: send out join messages as soon as new member is discovered
When a socket is joining a group, we look up in the binding table to find if there are already other members of the group present. This is used for being able to return EAGAIN instead of EHOSTUNREACH if the user proceeds directly to a send attempt. However, the information in the binding table can be used to directly set the created member in state MBR_PUBLISHED and send a JOIN message to the peer, instead of waiting for a topology PUBLISH event to do this. When there are many members in a group, the propagation time for such events can be significant, and we can save time during the join operation if we use the initial lookup result fully. In this commit, we eliminate the member state MBR_DISCOVERED which has been the result of the initial lookup, and do instead go directly to MBR_PUBLISHED, which initiates the setup. After this change, the tipc_member FSM looks as follows: +-----------+ ---->| PUBLISHED |-----------------------------------------------+ PUB- +-----------+ LEAVE/WITHRAW | LISH |JOIN | | +-------------------------------------------+ | | | LEAVE/WITHDRAW | | | | +------------+ | | | | +----------->| PENDING |---------+ | | | | |msg/maxactv +-+---+------+ LEAVE/ | | | | | | | | WITHDRAW | | | | | | +----------+ | | | | | | | |revert/maxactv| | | | | | | V V V V V | +----------+ msg +------------+ +-----------+ +-->| JOINED |------>| ACTIVE |------>| LEAVING |---> | +----------+ +--- -+------+ LEAVE/+-----------+DOWN | A A | WITHDRAW A A A EVT | | | |RECLAIM | | | | | |REMIT V | | | | | |== adv +------------+ | | | | | +---------| RECLAIMING |--------+ | | | | +-----+------+ LEAVE/ | | | | |REMIT WITHDRAW | | | | |< adv | | | |msg/ V LEAVE/ | | | |adv==ADV_IDLE+------------+ WITHDRAW | | | +-------------| REMITTED |------------+ | | +------------+ | |PUBLISH | JOIN +-----------+ LEAVE/WITHDRAW | ---->| JOINING |-----------------------------------------------+ +-----------+ Acked-by: Ying Xue <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c2b22bc commit d12d2e1

File tree

4 files changed

+68
-42
lines changed

4 files changed

+68
-42
lines changed

net/tipc/group.c

Lines changed: 62 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
#define ADV_ACTIVE (ADV_UNIT * 12)
5050

5151
enum mbr_state {
52-
MBR_DISCOVERED,
5352
MBR_JOINING,
5453
MBR_PUBLISHED,
5554
MBR_JOINED,
@@ -141,7 +140,7 @@ static bool tipc_group_is_receiver(struct tipc_member *m)
141140

142141
static bool tipc_group_is_sender(struct tipc_member *m)
143142
{
144-
return m && m->state >= MBR_JOINED;
143+
return m && m->state != MBR_JOINING && m->state != MBR_PUBLISHED;
145144
}
146145

147146
u32 tipc_group_exclude(struct tipc_group *grp)
@@ -184,6 +183,21 @@ struct tipc_group *tipc_group_create(struct net *net, u32 portid,
184183
return NULL;
185184
}
186185

186+
void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcvbuf)
187+
{
188+
struct rb_root *tree = &grp->members;
189+
struct tipc_member *m, *tmp;
190+
struct sk_buff_head xmitq;
191+
192+
skb_queue_head_init(&xmitq);
193+
rbtree_postorder_for_each_entry_safe(m, tmp, tree, tree_node) {
194+
tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, &xmitq);
195+
tipc_group_update_member(m, 0);
196+
}
197+
tipc_node_distr_xmit(net, &xmitq);
198+
*sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
199+
}
200+
187201
void tipc_group_delete(struct net *net, struct tipc_group *grp)
188202
{
189203
struct rb_root *tree = &grp->members;
@@ -274,7 +288,7 @@ static void tipc_group_add_to_tree(struct tipc_group *grp,
274288

275289
static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
276290
u32 node, u32 port,
277-
int state)
291+
u32 instance, int state)
278292
{
279293
struct tipc_member *m;
280294

@@ -287,6 +301,7 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
287301
m->group = grp;
288302
m->node = node;
289303
m->port = port;
304+
m->instance = instance;
290305
m->bc_acked = grp->bc_snd_nxt - 1;
291306
grp->member_cnt++;
292307
tipc_group_add_to_tree(grp, m);
@@ -295,9 +310,10 @@ static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
295310
return m;
296311
}
297312

298-
void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port)
313+
void tipc_group_add_member(struct tipc_group *grp, u32 node,
314+
u32 port, u32 instance)
299315
{
300-
tipc_group_create_member(grp, node, port, MBR_DISCOVERED);
316+
tipc_group_create_member(grp, node, port, instance, MBR_PUBLISHED);
301317
}
302318

303319
static void tipc_group_delete_member(struct tipc_group *grp,
@@ -623,7 +639,6 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
623639
tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq);
624640
break;
625641
case MBR_RECLAIMING:
626-
case MBR_DISCOVERED:
627642
case MBR_JOINING:
628643
case MBR_LEAVING:
629644
default:
@@ -721,26 +736,26 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
721736
case GRP_JOIN_MSG:
722737
if (!m)
723738
m = tipc_group_create_member(grp, node, port,
724-
MBR_JOINING);
739+
0, MBR_JOINING);
725740
if (!m)
726741
return;
727742
m->bc_syncpt = msg_grp_bc_syncpt(hdr);
728743
m->bc_rcv_nxt = m->bc_syncpt;
729744
m->window += msg_adv_win(hdr);
730745

731-
/* Wait until PUBLISH event is received */
732-
if (m->state == MBR_DISCOVERED) {
733-
m->state = MBR_JOINING;
734-
} else if (m->state == MBR_PUBLISHED) {
735-
m->state = MBR_JOINED;
736-
*usr_wakeup = true;
737-
m->usr_pending = false;
738-
tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
739-
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
740-
m->bc_syncpt, inputq);
741-
}
746+
/* Wait until PUBLISH event is received if necessary */
747+
if (m->state != MBR_PUBLISHED)
748+
return;
749+
750+
/* Member can be taken into service */
751+
m->state = MBR_JOINED;
752+
*usr_wakeup = true;
753+
m->usr_pending = false;
742754
list_del_init(&m->small_win);
743755
tipc_group_update_member(m, 0);
756+
tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
757+
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
758+
m->bc_syncpt, inputq);
744759
return;
745760
case GRP_LEAVE_MSG:
746761
if (!m)
@@ -844,30 +859,36 @@ void tipc_group_member_evt(struct tipc_group *grp,
844859

845860
m = tipc_group_find_member(grp, node, port);
846861

847-
if (event == TIPC_PUBLISHED) {
848-
if (!m)
849-
m = tipc_group_create_member(grp, node, port,
850-
MBR_DISCOVERED);
851-
if (!m)
852-
return;
862+
switch (event) {
863+
case TIPC_PUBLISHED:
864+
/* Send and wait for arrival of JOIN message if necessary */
865+
if (!m) {
866+
m = tipc_group_create_member(grp, node, port, instance,
867+
MBR_PUBLISHED);
868+
if (!m)
869+
break;
870+
tipc_group_update_member(m, 0);
871+
tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
872+
break;
873+
}
853874

854-
m->instance = instance;
875+
if (m->state != MBR_JOINING)
876+
break;
855877

856-
/* Hold back event if JOIN message not yet received */
857-
if (m->state == MBR_DISCOVERED) {
858-
m->state = MBR_PUBLISHED;
859-
} else {
860-
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
861-
m->bc_syncpt, inputq);
862-
m->state = MBR_JOINED;
863-
*usr_wakeup = true;
864-
m->usr_pending = false;
865-
}
866-
tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
878+
/* Member can be taken into service */
879+
m->instance = instance;
880+
m->state = MBR_JOINED;
881+
*usr_wakeup = true;
882+
m->usr_pending = false;
883+
list_del_init(&m->small_win);
867884
tipc_group_update_member(m, 0);
868-
} else if (event == TIPC_WITHDRAWN) {
885+
tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
886+
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
887+
m->bc_syncpt, inputq);
888+
break;
889+
case TIPC_WITHDRAWN:
869890
if (!m)
870-
return;
891+
break;
871892

872893
*usr_wakeup = true;
873894
m->usr_pending = false;
@@ -880,6 +901,9 @@ void tipc_group_member_evt(struct tipc_group *grp,
880901
if (!tipc_node_is_up(net, node))
881902
tipc_group_create_event(grp, m, TIPC_WITHDRAWN,
882903
m->bc_rcv_nxt, inputq);
904+
break;
905+
default:
906+
break;
883907
}
884908
*sk_rcvbuf = tipc_group_rcvbuf_limit(grp);
885909
}

net/tipc/group.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ struct tipc_msg;
4444

4545
struct tipc_group *tipc_group_create(struct net *net, u32 portid,
4646
struct tipc_group_req *mreq);
47+
void tipc_group_join(struct net *net, struct tipc_group *grp, int *sk_rcv_buf);
4748
void tipc_group_delete(struct net *net, struct tipc_group *grp);
48-
void tipc_group_add_member(struct tipc_group *grp, u32 node, u32 port);
49+
void tipc_group_add_member(struct tipc_group *grp, u32 node,
50+
u32 port, u32 instance);
4951
struct tipc_nlist *tipc_group_dests(struct tipc_group *grp);
5052
void tipc_group_self(struct tipc_group *grp, struct tipc_name_seq *seq,
5153
int *scope);

net/tipc/name_table.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
732732
list_for_each_entry(p, &info->zone_list, zone_list) {
733733
if (!tipc_in_scope(domain, p->node))
734734
continue;
735-
tipc_group_add_member(grp, p->node, p->ref);
735+
tipc_group_add_member(grp, p->node, p->ref, p->lower);
736736
}
737737
}
738738
spin_unlock_bh(&seq->lock);

net/tipc/socket.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2757,10 +2757,10 @@ static int tipc_sk_join(struct tipc_sock *tsk, struct tipc_group_req *mreq)
27572757
tipc_group_delete(net, grp);
27582758
tsk->group = NULL;
27592759
}
2760-
2761-
/* Eliminate any risk that a broadcast overtakes the sent JOIN */
2760+
/* Eliminate any risk that a broadcast overtakes sent JOINs */
27622761
tsk->mc_method.rcast = true;
27632762
tsk->mc_method.mandatory = true;
2763+
tipc_group_join(net, grp, &tsk->sk.sk_rcvbuf);
27642764
return rc;
27652765
}
27662766

0 commit comments

Comments
 (0)