Skip to content

Commit eb929a9

Browse files
Jon Maloydavem330
authored andcommitted
tipc: improve poll() for group member socket
The current criteria for returning POLLOUT from a group member socket is too simplistic. It basically returns POLLOUT as soon as the group has external destinations, something obviously leading to a lot of spinning during destination congestion situations. At the same time, the internal congestion handling is unnecessarily complex. We now change this as follows. - We introduce an 'open' flag in struct tipc_group. This flag is used only to help poll() get the setting of POLLOUT right, and *not* for congeston handling as such. This means that a user can choose to ignore an EAGAIN for a destination and go on sending messages to other destinations in the group if he wants to. - The flag is set to false every time we return EAGAIN on a send call. - The flag is set to true every time any member, i.e., not necessarily the member that caused EAGAIN, is removed from the small_win list. - We remove the group member 'usr_pending' flag. The size of the send window and presence in the 'small_win' list is sufficient criteria for recognizing congestion. This solution seems to be a reasonable compromise between 'anycast', which is normally not waiting for POLLOUT for a specific destination, and the other three send modes, which are. Acked-by: Ying Xue <[email protected]> Signed-off-by: Jon Maloy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 232d07b commit eb929a9

File tree

3 files changed

+41
-33
lines changed

3 files changed

+41
-33
lines changed

net/tipc/group.c

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ struct tipc_member {
7474
u16 bc_rcv_nxt;
7575
u16 bc_syncpt;
7676
u16 bc_acked;
77-
bool usr_pending;
7877
};
7978

8079
struct tipc_group {
@@ -96,11 +95,27 @@ struct tipc_group {
9695
u16 bc_ackers;
9796
bool loopback;
9897
bool events;
98+
bool open;
9999
};
100100

101101
static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m,
102102
int mtyp, struct sk_buff_head *xmitq);
103103

104+
bool tipc_group_is_open(struct tipc_group *grp)
105+
{
106+
return grp->open;
107+
}
108+
109+
static void tipc_group_open(struct tipc_member *m, bool *wakeup)
110+
{
111+
*wakeup = false;
112+
if (list_empty(&m->small_win))
113+
return;
114+
list_del_init(&m->small_win);
115+
m->group->open = true;
116+
*wakeup = true;
117+
}
118+
104119
static void tipc_group_decr_active(struct tipc_group *grp,
105120
struct tipc_member *m)
106121
{
@@ -406,20 +421,20 @@ bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport,
406421
int adv, state;
407422

408423
m = tipc_group_find_dest(grp, dnode, dport);
409-
*mbr = m;
410-
if (!m)
424+
if (!tipc_group_is_receiver(m)) {
425+
*mbr = NULL;
411426
return false;
412-
if (m->usr_pending)
413-
return true;
427+
}
428+
*mbr = m;
429+
414430
if (m->window >= len)
415431
return false;
416-
m->usr_pending = true;
432+
433+
grp->open = false;
417434

418435
/* If not fully advertised, do it now to prevent mutual blocking */
419436
adv = m->advertised;
420437
state = m->state;
421-
if (state < MBR_JOINED)
422-
return true;
423438
if (state == MBR_JOINED && adv == ADV_IDLE)
424439
return true;
425440
if (state == MBR_ACTIVE && adv == ADV_ACTIVE)
@@ -437,9 +452,10 @@ bool tipc_group_bc_cong(struct tipc_group *grp, int len)
437452
struct tipc_member *m = NULL;
438453

439454
/* If prev bcast was replicast, reject until all receivers have acked */
440-
if (grp->bc_ackers)
455+
if (grp->bc_ackers) {
456+
grp->open = false;
441457
return true;
442-
458+
}
443459
if (list_empty(&grp->small_win))
444460
return false;
445461

@@ -754,9 +770,7 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
754770

755771
/* Member can be taken into service */
756772
m->state = MBR_JOINED;
757-
*usr_wakeup = true;
758-
m->usr_pending = false;
759-
list_del_init(&m->small_win);
773+
tipc_group_open(m, usr_wakeup);
760774
tipc_group_update_member(m, 0);
761775
tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq);
762776
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
@@ -767,8 +781,7 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
767781
return;
768782
m->bc_syncpt = msg_grp_bc_syncpt(hdr);
769783
list_del_init(&m->list);
770-
list_del_init(&m->small_win);
771-
*usr_wakeup = true;
784+
tipc_group_open(m, usr_wakeup);
772785
tipc_group_decr_active(grp, m);
773786
m->state = MBR_LEAVING;
774787
tipc_group_create_event(grp, m, TIPC_WITHDRAWN,
@@ -778,26 +791,25 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup,
778791
if (!m)
779792
return;
780793
m->window += msg_adv_win(hdr);
781-
*usr_wakeup = m->usr_pending;
782-
m->usr_pending = false;
783-
list_del_init(&m->small_win);
794+
tipc_group_open(m, usr_wakeup);
784795
return;
785796
case GRP_ACK_MSG:
786797
if (!m)
787798
return;
788799
m->bc_acked = msg_grp_bc_acked(hdr);
789800
if (--grp->bc_ackers)
790-
break;
801+
return;
802+
list_del_init(&m->small_win);
803+
m->group->open = true;
791804
*usr_wakeup = true;
792-
m->usr_pending = false;
805+
tipc_group_update_member(m, 0);
793806
return;
794807
case GRP_RECLAIM_MSG:
795808
if (!m)
796809
return;
797-
*usr_wakeup = m->usr_pending;
798-
m->usr_pending = false;
799810
tipc_group_proto_xmit(grp, m, GRP_REMIT_MSG, xmitq);
800811
m->window = ADV_IDLE;
812+
tipc_group_open(m, usr_wakeup);
801813
return;
802814
case GRP_REMIT_MSG:
803815
if (!m || m->state != MBR_RECLAIMING)
@@ -883,9 +895,7 @@ void tipc_group_member_evt(struct tipc_group *grp,
883895
/* Member can be taken into service */
884896
m->instance = instance;
885897
m->state = MBR_JOINED;
886-
*usr_wakeup = true;
887-
m->usr_pending = false;
888-
list_del_init(&m->small_win);
898+
tipc_group_open(m, usr_wakeup);
889899
tipc_group_update_member(m, 0);
890900
tipc_group_proto_xmit(grp, m, GRP_JOIN_MSG, xmitq);
891901
tipc_group_create_event(grp, m, TIPC_PUBLISHED,
@@ -895,12 +905,10 @@ void tipc_group_member_evt(struct tipc_group *grp,
895905
if (!m)
896906
break;
897907

898-
*usr_wakeup = true;
899-
m->usr_pending = false;
900908
tipc_group_decr_active(grp, m);
901909
m->state = MBR_LEAVING;
902910
list_del_init(&m->list);
903-
list_del_init(&m->small_win);
911+
tipc_group_open(m, usr_wakeup);
904912

905913
/* Only send event if no LEAVE message can be expected */
906914
if (!tipc_node_is_up(net, node))

net/tipc/group.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,9 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack);
6767
bool tipc_group_cong(struct tipc_group *grp, u32 dnode, u32 dport,
6868
int len, struct tipc_member **m);
6969
bool tipc_group_bc_cong(struct tipc_group *grp, int len);
70+
bool tipc_group_is_open(struct tipc_group *grp);
7071
void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node,
7172
u32 port, struct sk_buff_head *xmitq);
7273
u16 tipc_group_bc_snd_nxt(struct tipc_group *grp);
7374
void tipc_group_update_member(struct tipc_member *m, int len);
74-
int tipc_group_size(struct tipc_group *grp);
7575
#endif

net/tipc/socket.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -715,7 +715,7 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
715715
{
716716
struct sock *sk = sock->sk;
717717
struct tipc_sock *tsk = tipc_sk(sk);
718-
struct tipc_group *grp = tsk->group;
718+
struct tipc_group *grp;
719719
u32 revents = 0;
720720

721721
sock_poll_wait(file, sk_sleep(sk), wait);
@@ -736,9 +736,9 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock,
736736
revents |= POLLIN | POLLRDNORM;
737737
break;
738738
case TIPC_OPEN:
739-
if (!grp || tipc_group_size(grp))
740-
if (!tsk->cong_link_cnt)
741-
revents |= POLLOUT;
739+
grp = tsk->group;
740+
if ((!grp || tipc_group_is_open(grp)) && !tsk->cong_link_cnt)
741+
revents |= POLLOUT;
742742
if (!tipc_sk_type_connectionless(sk))
743743
break;
744744
if (skb_queue_empty(&sk->sk_receive_queue))

0 commit comments

Comments
 (0)