IO: Replace RX priority heuristic with explicit mark
In BIRD, RX has lower priority than TX with the exception of RX from control socket. The patch replaces heuristic based on socket type with explicit mark and uses it for both control socket and BGP session waiting to be established. This should avoid an issue when during heavy load, outgoing connection could connect (TX event), send open, but then failed to receive OPEN / establish in time, not sending notifications between and therefore got hold timer expired error from the neighbor immediately after it finally established the connection.
This commit is contained in:
parent
e86cfd41d9
commit
9e7b3ebdf9
4 changed files with 8 additions and 2 deletions
|
@ -28,6 +28,7 @@ typedef struct birdsock {
|
||||||
struct iface *iface; /* Interface; specify this for broad/multicast sockets */
|
struct iface *iface; /* Interface; specify this for broad/multicast sockets */
|
||||||
|
|
||||||
byte *rbuf, *rpos; /* NULL=allocate automatically */
|
byte *rbuf, *rpos; /* NULL=allocate automatically */
|
||||||
|
uint fast_rx; /* RX has higher priority in event loop */
|
||||||
uint rbsize;
|
uint rbsize;
|
||||||
int (*rx_hook)(struct birdsock *, int size); /* NULL=receiving turned off, returns 1 to clear rx buffer */
|
int (*rx_hook)(struct birdsock *, int size); /* NULL=receiving turned off, returns 1 to clear rx buffer */
|
||||||
|
|
||||||
|
|
|
@ -374,6 +374,8 @@ bgp_conn_enter_established_state(struct bgp_conn *conn)
|
||||||
if (ipa_zero(p->source_addr))
|
if (ipa_zero(p->source_addr))
|
||||||
p->source_addr = conn->sk->saddr;
|
p->source_addr = conn->sk->saddr;
|
||||||
|
|
||||||
|
conn->sk->fast_rx = 0;
|
||||||
|
|
||||||
p->conn = conn;
|
p->conn = conn;
|
||||||
p->last_error_class = 0;
|
p->last_error_class = 0;
|
||||||
p->last_error_code = 0;
|
p->last_error_code = 0;
|
||||||
|
@ -696,6 +698,7 @@ bgp_setup_sk(struct bgp_conn *conn, sock *s)
|
||||||
{
|
{
|
||||||
s->data = conn;
|
s->data = conn;
|
||||||
s->err_hook = bgp_sock_err;
|
s->err_hook = bgp_sock_err;
|
||||||
|
s->fast_rx = 1;
|
||||||
conn->sk = s;
|
conn->sk = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2152,7 +2152,7 @@ io_loop(void)
|
||||||
int steps;
|
int steps;
|
||||||
|
|
||||||
steps = MAX_STEPS;
|
steps = MAX_STEPS;
|
||||||
if ((s->type >= SK_MAGIC) && (pfd[s->index].revents & (POLLIN | POLLHUP | POLLERR)) && s->rx_hook)
|
if (s->fast_rx && (pfd[s->index].revents & (POLLIN | POLLHUP | POLLERR)) && s->rx_hook)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
steps--;
|
steps--;
|
||||||
|
@ -2197,7 +2197,7 @@ io_loop(void)
|
||||||
goto next2;
|
goto next2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s->type < SK_MAGIC) && (pfd[s->index].revents & (POLLIN | POLLHUP | POLLERR)) && s->rx_hook)
|
if (!s->fast_rx && (pfd[s->index].revents & (POLLIN | POLLHUP | POLLERR)) && s->rx_hook)
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
io_log_event(s->rx_hook, s->data);
|
io_log_event(s->rx_hook, s->data);
|
||||||
|
|
|
@ -450,6 +450,7 @@ cli_connect(sock *s, int size UNUSED)
|
||||||
s->err_hook = cli_err;
|
s->err_hook = cli_err;
|
||||||
s->data = c = cli_new(s);
|
s->data = c = cli_new(s);
|
||||||
s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */
|
s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */
|
||||||
|
s->fast_rx = 1;
|
||||||
c->rx_pos = c->rx_buf;
|
c->rx_pos = c->rx_buf;
|
||||||
c->rx_aux = NULL;
|
c->rx_aux = NULL;
|
||||||
rmove(s, c->pool);
|
rmove(s, c->pool);
|
||||||
|
@ -466,6 +467,7 @@ cli_init_unix(uid_t use_uid, gid_t use_gid)
|
||||||
s->type = SK_UNIX_PASSIVE;
|
s->type = SK_UNIX_PASSIVE;
|
||||||
s->rx_hook = cli_connect;
|
s->rx_hook = cli_connect;
|
||||||
s->rbsize = 1024;
|
s->rbsize = 1024;
|
||||||
|
s->fast_rx = 1;
|
||||||
|
|
||||||
/* Return value intentionally ignored */
|
/* Return value intentionally ignored */
|
||||||
unlink(path_control_socket);
|
unlink(path_control_socket);
|
||||||
|
|
Loading…
Reference in a new issue