forked from Mirror/frr

Current behavor of BGP is to have a event per connection. Given that on startup of BGP with a high number of neighbors you end up with 2 * # of peers events that are being processed. Additionally once BGP has selected the connection this still only comes down to 512 events. This number of events is swamping the event system and in addition delaying any other work from being done in BGP at all because the the 512 events are always going to take precedence over everything else. The other main events are the handling of the metaQ(1 event), update group events( 1 per update group ) and the zebra batching event. These are being swamped. Modify the BGP code to have a FIFO of connections. As new data comes in to read, place the connection on the end of the FIFO. Have the bgp_process_packet handle up to 100 packets spread across the individual peers where each peer/connection is limited to the original quanta. During testing I noticed that withdrawal events at very very large scale are taking up to 40 seconds to process so I added a check for yielding to further limit the number of packets being processed. This change also allow for BGP to be interactive again on scale setups on initial convergence. Prior to this change any vtysh command entered would be delayed by 10's of seconds in my setup while BGP was doing other work. Signed-off-by: Donald Sharp <sharpd@nvidia.com>
93 lines
2.4 KiB
C
93 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/* BGP I/O.
|
|
* Implements packet I/O in a pthread.
|
|
* Copyright (C) 2017 Cumulus Networks
|
|
* Quentin Young
|
|
*/
|
|
|
|
#ifndef _FRR_BGP_IO_H
|
|
#define _FRR_BGP_IO_H
|
|
|
|
#define BGP_WRITE_PACKET_MAX 64U
|
|
#define BGP_READ_PACKET_MAX 10U
|
|
#define BGP_PACKET_PROCESS_LIMIT 100
|
|
|
|
#include "bgpd/bgpd.h"
|
|
#include "frr_pthread.h"
|
|
|
|
struct peer_connection;
|
|
|
|
/**
|
|
* Start function for write thread.
|
|
*
|
|
* @param arg - unused
|
|
*/
|
|
extern void *bgp_io_start(void *arg);
|
|
|
|
/**
|
|
* Start function for write thread.
|
|
*
|
|
* Uninitializes all resources and stops the thread.
|
|
*
|
|
* @param result - where to store data result, unused
|
|
*/
|
|
extern int bgp_io_stop(void **result, struct frr_pthread *fpt);
|
|
|
|
/**
|
|
* Turns on packet writing for a peer.
|
|
*
|
|
* After this function is called, any packets placed on connection->obuf will be
|
|
* written to connection->fd until no more packets remain.
|
|
*
|
|
* Additionally, it becomes unsafe to perform socket actions on connection->fd.
|
|
*
|
|
* @param peer - peer to register
|
|
*/
|
|
extern void bgp_writes_on(struct peer_connection *peer);
|
|
|
|
/**
|
|
* Turns off packet writing for a peer.
|
|
*
|
|
* After this function returns, packets placed on connection->obuf will not be
|
|
* written to connection->fd by the I/O thread.
|
|
*
|
|
* After this function returns it becomes safe to perform socket actions on
|
|
* connection->fd.
|
|
*
|
|
* @param connection - connection to deregister
|
|
* @param flush - as described
|
|
*/
|
|
extern void bgp_writes_off(struct peer_connection *connection);
|
|
|
|
/**
|
|
* Turns on packet reading for a peer.
|
|
*
|
|
* After this function is called, any packets received on connection->fd
|
|
* will be read and copied into the FIFO queue connection->ibuf.
|
|
*
|
|
* Additionally, it becomes unsafe to perform socket actions on connection->fd.
|
|
*
|
|
* Whenever one or more packets are placed onto connection->ibuf, a task of type
|
|
* THREAD_EVENT will be placed on the main thread whose handler is
|
|
*
|
|
* bgp_packet.c:bgp_process_packet()
|
|
*
|
|
* @param connection - The connection to register
|
|
*/
|
|
extern void bgp_reads_on(struct peer_connection *connection);
|
|
|
|
/**
|
|
* Turns off packet reading for a peer.
|
|
*
|
|
* After this function is called, any packets received on connection->fd
|
|
* will not be read by the I/O thread.
|
|
*
|
|
* After this function returns it becomes safe to perform socket actions on
|
|
* connection->fd.
|
|
*
|
|
* @param connection - The connection to register for
|
|
*/
|
|
extern void bgp_reads_off(struct peer_connection *connection);
|
|
|
|
#endif /* _FRR_BGP_IO_H */
|