LCOV - code coverage report
Current view: top level - app/shared/commands/configure - hyperthreads.c (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 63 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #include "configure.h"
       2             : 
       3             : #define NAME "hyperthreads"
       4             : 
       5             : #include "fd_cpu_isolation.h"
       6             : #include "../../../../disco/topo/fd_topob.h"
       7             : 
       8             : #include <errno.h>
       9             : #include <fcntl.h>
      10             : #include <unistd.h>
      11             : 
      12             : static int
      13             : sibling_isolated_idle( config_t const * config,
      14           0 :                        ulong            cpu_idx ) {
      15           0 :   char path[ PATH_MAX ];
      16           0 :   FD_TEST( fd_cstr_printf_check( path, sizeof(path), NULL, "/sys/fs/cgroup/%s/cpuset.cpus", config->name ) );
      17             : 
      18           0 :   int fd = open( path, O_RDONLY );
      19           0 :   if( FD_UNLIKELY( fd<0 ) ) {
      20           0 :     if( FD_LIKELY( errno==ENOENT ) ) return 0; /* cpuset stage not configured */
      21           0 :     FD_LOG_ERR(( "open(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      22           0 :   }
      23             : 
      24           0 :   char list[ FD_CPU_ISOLATION_LIST_MAX ];
      25           0 :   long list_len = read( fd, list, sizeof(list)-1UL );
      26           0 :   if( FD_UNLIKELY( list_len<0L ) ) FD_LOG_ERR(( "read(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      27           0 :   if( FD_UNLIKELY( close( fd ) ) ) FD_LOG_ERR(( "close(%s) failed (%i-%s)", path, errno, fd_io_strerror( errno ) ));
      28           0 :   list[ list_len ] = '\0';
      29             : 
      30           0 :   FD_CPUSET_DECL( partition );
      31           0 :   if( FD_UNLIKELY( !fd_cpu_isolation_parse_list( partition, list ) ) )
      32           0 :     FD_LOG_ERR(( "failed to parse `%s` (\"%s\")", path, list ));
      33             : 
      34           0 :   if( FD_LIKELY( cpu_idx>=FD_TILE_MAX || !fd_cpuset_test( partition, cpu_idx ) ) ) return 0;
      35             : 
      36           0 :   return 1;
      37           0 : }
      38             : 
      39             : static configure_result_t
      40             : check( config_t const * config,
      41           0 :        int              check_type ) {
      42           0 :   if( !( check_type==FD_CONFIGURE_CHECK_TYPE_CHECK ||
      43           0 :          check_type==FD_CONFIGURE_CHECK_TYPE_RUN ) ) CONFIGURE_OK();
      44             : 
      45           0 :   fd_topo_cpus_t cpus[1];
      46           0 :   fd_topo_cpus_init( cpus );
      47             : 
      48           0 :   fd_topo_t const * topo = &config->topo;
      49           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
      50           0 :     fd_topo_tile_t const * tile = &topo->tiles[ i ];
      51           0 :     if( FD_LIKELY( tile->kind_id || strcmp( tile->name, "pack" ) ) ) continue;
      52             : 
      53             :     /* A floating tile (efficient layout mode) shares its cores with
      54             :        the other floaters, so an idle sibling buys it nothing */
      55           0 :     if( FD_UNLIKELY( tile->cpu_idx>=cpus->cpu_cnt || tile->floats ) ) continue;
      56           0 :     ulong pair = cpus->cpu[ tile->cpu_idx ].sibling;
      57           0 :     if( FD_UNLIKELY( pair>=cpus->cpu_cnt ) ) continue;
      58             : 
      59           0 :     int pair_used = 0;
      60           0 :     for( ulong j=0UL; j<topo->tile_cnt; j++ ) {
      61           0 :       fd_topo_tile_t const * other = &topo->tiles[ j ];
      62           0 :       pair_used |= other->cpu_idx==pair && !( fd_topob_tile_class( other->name ) & FD_TOPOB_TILE_STARTUP );
      63           0 :     }
      64             : 
      65             :     /* An online-but-unused sibling inside this instance's isolated
      66             :        cpuset partition is permanently idle, which is about as good as
      67             :        offline for SMT purposes: no warning needed. */
      68           0 :     int pair_online = !pair_used && cpus->cpu[ pair ].online && !sibling_isolated_idle( config, pair );
      69             : 
      70           0 :     if( FD_UNLIKELY( pair_used ) )        FD_LOG_WARNING(( "%s cpu %lu has hyperthread pair cpu %lu which is used by another tile. Proceeding but performance may be reduced.", tile->name, tile->cpu_idx, pair ));
      71           0 :     else if( FD_UNLIKELY( pair_online ) ) FD_LOG_WARNING(( "%s cpu %lu has hyperthread pair cpu %lu which should be offline or in the isolated cpuset partition (`configure init cpuset`). Proceeding but performance may be reduced.", tile->name, tile->cpu_idx, pair ));
      72           0 :   }
      73             : 
      74             :   /* One summary line for the other hot tiles sharing a core */
      75           0 :   static char const * const HOT[] = { "replay", "shred", "execle", "execrp", "motor" };
      76           0 :   char  pairs[ 512 ] = "";
      77           0 :   ulong len = 0UL;
      78           0 :   ulong cnt = 0UL;
      79           0 :   for( ulong i=0UL; i<topo->tile_cnt; i++ ) {
      80           0 :     fd_topo_tile_t const * tile = &topo->tiles[ i ];
      81           0 :     int hot = 0;
      82           0 :     for( ulong k=0UL; k<sizeof(HOT)/sizeof(HOT[0]); k++ ) hot |= !strcmp( tile->name, HOT[ k ] );
      83           0 :     if( !hot || tile->floats || tile->cpu_idx>=cpus->cpu_cnt ) continue;
      84           0 :     ulong pair = cpus->cpu[ tile->cpu_idx ].sibling;
      85           0 :     for( ulong j=0UL; j<topo->tile_cnt && pair<cpus->cpu_cnt; j++ ) {
      86           0 :       fd_topo_tile_t const * other = &topo->tiles[ j ];
      87           0 :       if( other->cpu_idx!=pair || other->floats || ( fd_topob_tile_class( other->name ) & FD_TOPOB_TILE_STARTUP ) ) continue;
      88           0 :       ulong n = 0UL;
      89           0 :       if( cnt<8UL ) FD_TEST( fd_cstr_printf_check( pairs+len, sizeof(pairs)-len, &n, " %s:%lu/%s:%lu", tile->name, tile->kind_id, other->name, other->kind_id ) );
      90           0 :       len += n;
      91           0 :       cnt++;
      92           0 :       break;
      93           0 :     }
      94           0 :   }
      95           0 :   if( FD_UNLIKELY( cnt ) ) FD_LOG_NOTICE(( "%lu hot tiles share a physical core with another tile:%s%s", cnt, pairs, cnt>8UL ? " ..." : "" ));
      96             : 
      97           0 :   CONFIGURE_OK();
      98           0 : }
      99             : 
     100             : configure_stage_t fd_cfg_stage_hyperthreads = {
     101             :   .name            = NAME,
     102             :   .always_recreate = 0,
     103             :   .enabled         = NULL,
     104             :   .init_perm       = NULL,
     105             :   .fini_perm       = NULL,
     106             :   .init            = NULL,
     107             :   .fini            = NULL,
     108             :   .check           = check,
     109             : };
     110             : 
     111             : #undef NAME

Generated by: LCOV version 1.14