LCOV - code coverage report
Current view: top level - disco/net - fd_net_tile_topo.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 113 130 86.9 %
Date: 2025-03-20 12:08:36 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /* Topology support routines for the net tile */
       2             : 
       3             : #include "fd_net_tile.h"
       4             : #include "../topo/fd_topob.h"
       5             : #include "../topo/fd_pod_format.h"
       6             : #include "../netlink/fd_netlink_tile.h"
       7             : 
       8             : #include <net/if.h>
       9             : 
      10             : static void
      11             : setup_xdp_tile( fd_topo_t *      topo,
      12             :                 ulong            i,
      13             :                 fd_topo_tile_t * netlink_tile,
      14             :                 ulong const *    tile_to_cpu,
      15             :                 char const       bind_interface[ IF_NAMESIZE ],
      16             :                 long             flush_timeout_micros,
      17             :                 ulong            xdp_rx_queue_size,
      18             :                 ulong            xdp_tx_queue_size,
      19             :                 int              xdp_zero_copy,
      20           3 :                 char const *     xdp_mode ) {
      21           3 :   fd_topo_tile_t * tile = fd_topob_tile( topo, "net", "net", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      22           3 :   fd_topob_link( topo, "net_netlnk", "net_netlnk", 128UL, 0UL, 0UL );
      23           3 :   fd_topob_tile_in(  topo, "netlnk", 0UL, "metric_in", "net_netlnk", i, FD_TOPOB_UNRELIABLE, FD_TOPOB_POLLED );
      24           3 :   fd_topob_tile_out( topo, "net",    i,                "net_netlnk", i );
      25           3 :   fd_netlink_topo_join( topo, netlink_tile, tile );
      26             : 
      27           3 :   fd_topo_obj_t * umem_obj = fd_topob_obj( topo, "dcache", "net_umem" );
      28           3 :   fd_topob_tile_uses( topo, tile, umem_obj, FD_SHMEM_JOIN_MODE_READ_WRITE );
      29           3 :   fd_pod_insertf_ulong( topo->props, umem_obj->id, "net.%lu.umem", i );
      30             : 
      31           3 :   strncpy( tile->net.interface, bind_interface, sizeof(tile->net.interface) );
      32             : 
      33           3 :   strcpy( tile->net.provider, "xdp" );
      34           3 :   tile->net.tx_flush_timeout_ns = (long)flush_timeout_micros * 1000L;
      35           3 :   tile->net.xdp_rx_queue_size = xdp_rx_queue_size;
      36           3 :   tile->net.xdp_tx_queue_size = xdp_tx_queue_size;
      37           3 :   tile->net.zero_copy         = xdp_zero_copy;
      38           3 :   fd_memset( tile->net.xdp_mode, 0, 4 );
      39           3 :   fd_memcpy( tile->net.xdp_mode, xdp_mode, strnlen( xdp_mode, 3 ) );  /* GCC complains about strncpy */
      40             : 
      41           3 :   tile->net.umem_dcache_obj_id    = umem_obj->id;
      42           3 :   tile->net.netdev_dbl_buf_obj_id = netlink_tile->netlink.netdev_dbl_buf_obj_id;
      43           3 :   tile->net.fib4_main_obj_id      = netlink_tile->netlink.fib4_main_obj_id;
      44           3 :   tile->net.fib4_local_obj_id     = netlink_tile->netlink.fib4_local_obj_id;
      45           3 :   tile->net.neigh4_obj_id         = netlink_tile->netlink.neigh4_obj_id;
      46           3 :   tile->net.neigh4_ele_obj_id     = netlink_tile->netlink.neigh4_ele_obj_id;
      47             : 
      48             :   /* Allocate free ring */
      49             : 
      50           3 :   tile->net.free_ring_depth = tile->net.xdp_tx_queue_size;
      51           3 :   if( i==0 ) {
      52             :     /* Allocate additional frames for loopback */
      53           3 :     tile->net.free_ring_depth += 16384UL;
      54           3 :   }
      55           3 : }
      56             : 
      57             : static void
      58             : setup_sock_tile( fd_topo_t *   topo,
      59           0 :                  ulong const * tile_to_cpu ) {
      60           0 :   fd_topo_tile_t * tile = fd_topob_tile( topo, "sock", "sock", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      61           0 :   strcpy( tile->net.provider, "socket" );
      62           0 : }
      63             : 
      64             : void
      65             : fd_topos_net_tiles( fd_topo_t *  topo,
      66             :                     ulong        net_tile_cnt,
      67             :                     ulong        netlnk_max_routes,
      68             :                     ulong        netlnk_max_neighbors,
      69             :                     char const * net_provider,
      70             :                     char const   bind_interface[ IF_NAMESIZE ],
      71             :                     long         flush_timeout_micros,
      72             :                     ulong        xdp_rx_queue_size,
      73             :                     ulong        xdp_tx_queue_size,
      74             :                     int          xdp_zero_copy,
      75             :                     char const * xdp_mode,
      76           3 :                     ulong const  tile_to_cpu[ FD_TILE_MAX ] ) {
      77             :   /* net_umem: Packet buffers */
      78           3 :   fd_topob_wksp( topo, "net_umem" );
      79             : 
      80             :   /* Create workspaces */
      81             : 
      82           3 :   if( 0==strcmp( net_provider, "xdp" ) ) {
      83             : 
      84             :     /* net: private working memory of the net tiles */
      85           3 :     fd_topob_wksp( topo, "net" );
      86             :     /* netlnk: private working memory of the netlnk tile */
      87           3 :     fd_topob_wksp( topo, "netlnk" );
      88             :     /* netbase: shared network config (config plane) */
      89           3 :     fd_topob_wksp( topo, "netbase" );
      90             :     /* net_netlnk: net->netlnk ARP requests */
      91           3 :     fd_topob_wksp( topo, "net_netlnk" );
      92             : 
      93           3 :     fd_topo_tile_t * netlink_tile = fd_topob_tile( topo, "netlnk", "netlnk", "metric_in", tile_to_cpu[ topo->tile_cnt ], 0, 0 );
      94           3 :     fd_netlink_topo_create( netlink_tile, topo, netlnk_max_routes, netlnk_max_neighbors, bind_interface );
      95             : 
      96           6 :     for( ulong i=0UL; i<net_tile_cnt; i++ ) {
      97           3 :       setup_xdp_tile( topo, i, netlink_tile, tile_to_cpu, bind_interface, flush_timeout_micros, xdp_rx_queue_size, xdp_tx_queue_size, xdp_zero_copy, xdp_mode );
      98           3 :     }
      99             : 
     100           3 :   } else if( 0==strcmp( net_provider, "socket" ) ) {
     101             : 
     102             :     /* sock: private working memory of the sock tiles */
     103           0 :     fd_topob_wksp( topo, "sock" );
     104             : 
     105           0 :     for( ulong i=0UL; i<net_tile_cnt; i++ ) {
     106           0 :       setup_sock_tile( topo, tile_to_cpu );
     107           0 :     }
     108             : 
     109           0 :   } else {
     110           0 :     FD_LOG_ERR(( "invalid `development.net.provider`" ));
     111           0 :   }
     112           3 : }
     113             : 
     114             : static int
     115           9 : topo_is_xdp( fd_topo_t * topo ) {
     116             :   /* FIXME hacky */
     117          18 :   for( ulong j=0UL; j<(topo->tile_cnt); j++ ) {
     118          18 :     if( 0==strcmp( topo->tiles[ j ].name, "net" ) ) {
     119           9 :       if( 0==strcmp( topo->tiles[ j ].net.provider, "xdp" ) ) {
     120           9 :         return 1;
     121           9 :       } else {
     122           0 :         return 0;
     123           0 :       }
     124           9 :     }
     125          18 :   }
     126           0 :   return 0;
     127           9 : }
     128             : 
     129             : static void
     130             : add_xdp_rx_link( fd_topo_t *  topo,
     131             :                  char const * link_name,
     132             :                  ulong        net_kind_id,
     133           6 :                  ulong        depth ) {
     134           6 :   if( FD_UNLIKELY( !topo || !link_name  ) ) FD_LOG_ERR(( "NULL args" ));
     135           6 :   if( FD_UNLIKELY( strlen( link_name )>=sizeof(topo->links[ topo->link_cnt ].name ) ) ) FD_LOG_ERR(( "link name too long: %s", link_name ));
     136           6 :   if( FD_UNLIKELY( topo->link_cnt>=FD_TOPO_MAX_LINKS ) ) FD_LOG_ERR(( "too many links" ));
     137             : 
     138           6 :   ulong kind_id = 0UL;
     139         189 :   for( ulong i=0UL; i<topo->link_cnt; i++ ) {
     140         183 :     if( !strcmp( topo->links[ i ].name, link_name ) ) kind_id++;
     141         183 :   }
     142             : 
     143           6 :   fd_topo_link_t * link = &topo->links[ topo->link_cnt ];
     144           6 :   strncpy( link->name, link_name, sizeof(link->name) );
     145           6 :   link->id       = topo->link_cnt;
     146           6 :   link->kind_id  = kind_id;
     147           6 :   link->depth    = depth;
     148           6 :   link->mtu      = FD_NET_MTU;
     149           6 :   link->burst    = 0UL;
     150             : 
     151           6 :   fd_topo_obj_t * obj = fd_topob_obj( topo, "mcache", "net_umem" );
     152           6 :   link->mcache_obj_id = obj->id;
     153           6 :   FD_TEST( fd_pod_insertf_ulong( topo->props, depth, "obj.%lu.depth", obj->id ) );
     154             : 
     155           6 :   link->dcache_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "net.%lu.umem", net_kind_id );
     156           6 :   if( FD_UNLIKELY( link->dcache_obj_id==ULONG_MAX ) ) FD_LOG_ERR(( "umem dcache not found for net %lu", net_kind_id ));
     157             : 
     158           6 :   topo->link_cnt++;
     159           6 : }
     160             : 
     161             : void
     162             : fd_topos_net_rx_link( fd_topo_t *  topo,
     163             :                       char const * link_name,
     164             :                       ulong        net_kind_id,
     165           6 :                       ulong        depth ) {
     166           6 :   if( topo_is_xdp( topo ) ) {
     167           6 :     add_xdp_rx_link( topo, link_name, net_kind_id, depth );
     168           6 :     fd_topob_tile_out( topo, "net", net_kind_id, link_name, net_kind_id );
     169           6 :   } else {
     170           0 :     fd_topob_link( topo, link_name, "net_umem", depth, FD_NET_MTU, 64 );
     171           0 :     fd_topob_tile_out( topo, "sock", net_kind_id, link_name, net_kind_id );
     172           0 :   }
     173           6 : }
     174             : 
     175             : void
     176             : fd_topos_tile_in_net( fd_topo_t *  topo,
     177             :                       char const * fseq_wksp,
     178             :                       char const * link_name,
     179             :                       ulong        link_kind_id,
     180             :                       int          reliable,
     181           6 :                       int          polled ) {
     182         138 :   for( ulong j=0UL; j<(topo->tile_cnt); j++ ) {
     183         132 :     if( 0==strcmp( topo->tiles[ j ].name, "net"  ) ||
     184         132 :         0==strcmp( topo->tiles[ j ].name, "sock" ) ) {
     185           6 :       fd_topob_tile_in( topo, topo->tiles[ j ].name, topo->tiles[ j ].kind_id, fseq_wksp, link_name, link_kind_id, reliable, polled );
     186           6 :     }
     187         132 :   }
     188           6 : }
     189             : 
     190             : void
     191             : fd_topos_net_tile_finish( fd_topo_t * topo,
     192           3 :                           ulong       net_kind_id ) {
     193           3 :   if( !topo_is_xdp( topo ) ) return;
     194             : 
     195           3 :   fd_topo_tile_t * net_tile = &topo->tiles[ fd_topo_find_tile( topo, "net", net_kind_id ) ];
     196             : 
     197           3 :   ulong rx_depth = net_tile->net.xdp_rx_queue_size;
     198           3 :   ulong tx_depth = net_tile->net.xdp_tx_queue_size;
     199           3 :   rx_depth += (rx_depth/2UL);
     200           3 :   tx_depth += (tx_depth/2UL);
     201             : 
     202           3 :   if( net_kind_id==0 ) {
     203             :     /* Double it for loopback XSK */
     204           3 :     rx_depth *= 2UL;
     205           3 :     tx_depth *= 2UL;
     206           3 :   }
     207             : 
     208           3 :   ulong cum_frame_cnt = rx_depth + tx_depth;
     209             : 
     210             :   /* Count up the depth of all RX mcaches */
     211             : 
     212          12 :   for( ulong j=0UL; j<(net_tile->out_cnt); j++ ) {
     213           9 :     ulong link_id       = net_tile->out_link_id[ j ];
     214           9 :     ulong mcache_obj_id = topo->links[ link_id ].mcache_obj_id;
     215           9 :     ulong depth = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "obj.%lu.depth", mcache_obj_id );
     216           9 :     if( FD_UNLIKELY( depth==ULONG_MAX ) ) FD_LOG_ERR(( "Didn't find depth for mcache %s", topo->links[ link_id ].name ));
     217           9 :     cum_frame_cnt += depth + 1UL;
     218           9 :   }
     219             : 
     220             :   /* Create a dcache object */
     221             : 
     222           3 :   ulong umem_obj_id = fd_pod_queryf_ulong( topo->props, ULONG_MAX, "net.%lu.umem", net_kind_id );
     223           3 :   FD_TEST( umem_obj_id!=ULONG_MAX );
     224             : 
     225           3 :   FD_TEST( net_tile->net.umem_dcache_obj_id > 0 );
     226           3 :   fd_pod_insertf_ulong( topo->props, cum_frame_cnt, "obj.%lu.depth", umem_obj_id );
     227           3 :   fd_pod_insertf_ulong( topo->props, 2UL,           "obj.%lu.burst", umem_obj_id ); /* 4096 byte padding */
     228           3 :   fd_pod_insertf_ulong( topo->props, 2048UL,        "obj.%lu.mtu",   umem_obj_id );
     229           3 : }

Generated by: LCOV version 1.14