frr/bgpd/bgp_io.h
Donald Sharp 12bf042c68 bgpd: Modify bgp to handle packet events in a FIFO
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>
2025-03-25 09:10:46 -04:00

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 */