Line data Source code
1 : #include "configure.h"
2 :
3 0 : #define NAME "sysctl"
4 :
5 : #include "../../../platform/fd_file_util.h"
6 :
7 : #include <errno.h>
8 : #include <stdio.h>
9 : #include <linux/capability.h>
10 :
11 : static void
12 : init_perm( fd_cap_chk_t * chk,
13 0 : config_t const * config FD_PARAM_UNUSED ) {
14 0 : fd_cap_chk_cap( chk, NAME, CAP_SYS_ADMIN, "set kernel parameters in `/proc/sys`" );
15 0 : }
16 :
17 0 : #define ENFORCE_MINIMUM 0
18 0 : #define WARN_MINIMUM 1
19 0 : #define WARN_EXACT 2
20 :
21 : typedef struct {
22 : char const * path;
23 : ulong value;
24 : int mode;
25 : int allow_missing;
26 : } sysctl_param_t;
27 :
28 : static const sysctl_param_t params[] = {
29 : {
30 : "/proc/sys/vm/max_map_count", /* int */
31 : 1000000,
32 : ENFORCE_MINIMUM,
33 : 0,
34 : },
35 : {
36 : "/proc/sys/fs/file-max", /* ulong */
37 : CONFIGURE_NR_OPEN_FILES,
38 : ENFORCE_MINIMUM,
39 : 0,
40 : },
41 : {
42 : "/proc/sys/fs/nr_open", /* uint */
43 : CONFIGURE_NR_OPEN_FILES,
44 : ENFORCE_MINIMUM,
45 : 0,
46 : },
47 : {
48 : "/proc/sys/kernel/numa_balancing", /* int? */
49 : 0,
50 : WARN_EXACT,
51 : 1,
52 : },
53 : {0}
54 : };
55 :
56 : static const sysctl_param_t xdp_params[] = {
57 : {
58 : "/proc/sys/net/ipv4/conf/lo/rp_filter",
59 : 2,
60 : ENFORCE_MINIMUM,
61 : 0,
62 : },
63 : {
64 : "/proc/sys/net/ipv4/conf/lo/accept_local",
65 : 1,
66 : ENFORCE_MINIMUM,
67 : 0,
68 : },
69 : {
70 : "/proc/sys/net/core/bpf_jit_enable",
71 : 1,
72 : WARN_MINIMUM,
73 : 0,
74 : },
75 : {
76 : "/proc/sys/net/ipv4/conf/lo/route_localnet",
77 : 1,
78 : ENFORCE_MINIMUM,
79 : 1,
80 : },
81 : {0}
82 : };
83 :
84 : static sysctl_param_t sock_params[] = {
85 : {
86 : "/proc/sys/net/core/rmem_max",
87 : 0,
88 : ENFORCE_MINIMUM,
89 : 0,
90 : },
91 : {
92 : "/proc/sys/net/core/wmem_max",
93 : 0,
94 : ENFORCE_MINIMUM,
95 : 0,
96 : },
97 : {0}
98 : };
99 :
100 : static sysctl_param_t gui_params[] = {
101 : {
102 : "/proc/sys/net/core/wmem_max",
103 : 4194304,
104 : ENFORCE_MINIMUM,
105 : 0,
106 : },
107 : {0}
108 : };
109 :
110 : /* Some of these sysctl limits are needed for the Agave client, not
111 : Firedancer. We set them on their behalf to make configuration easier
112 : for users. */
113 :
114 : static void
115 0 : init_param_list( sysctl_param_t const * list ) {
116 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
117 0 : ulong param;
118 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
119 : /* If the syctl file does not exist in /proc/sys, it's likely it
120 : doesn't exist anywhere else */
121 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
122 :
123 0 : FD_LOG_ERR(( "could not read kernel parameter `%s`, system might not support configuring sysctl (%i-%s)", p->path, errno, fd_io_strerror( errno ) ));
124 0 : }
125 0 : switch( p->mode ) {
126 0 : case ENFORCE_MINIMUM:
127 0 : if( FD_UNLIKELY( param<(p->value) ) ) {
128 0 : FD_LOG_NOTICE(( "%sRUN: `echo \"%lu\" > %s`%s", fd_log_style_dim(), p->value, p->path, fd_log_style_normal() ));
129 0 : if( FD_UNLIKELY( -1==fd_file_util_write_ulong( p->path, p->value ) ) )
130 0 : FD_LOG_ERR(( "could not set kernel parameter `%s` to %lu (%i-%s)", p->path, p->value, errno, fd_io_strerror( errno ) ));
131 0 : }
132 0 : break;
133 0 : default:
134 0 : break;
135 0 : }
136 0 : }
137 0 : }
138 :
139 : static void
140 0 : init( config_t const * config ) {
141 0 : init_param_list( params );
142 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
143 0 : init_param_list( xdp_params );
144 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
145 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
146 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
147 0 : init_param_list( sock_params );
148 0 : }
149 0 : if( config->tiles.gui.enabled ) init_param_list( gui_params );
150 0 : }
151 :
152 : static configure_result_t
153 0 : check_param_list( sysctl_param_t const * list ) {
154 0 : static int has_warned = 0;
155 :
156 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
157 0 : ulong param;
158 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
159 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
160 0 : FD_LOG_ERR(( "could not read kernel parameter `%s`, system might not support configuring sysctl (%i-%s)", p->path, errno, fd_io_strerror( errno ) ));
161 0 : }
162 0 : switch( p->mode ) {
163 0 : case ENFORCE_MINIMUM:
164 0 : if( FD_UNLIKELY( param<(p->value) ) )
165 0 : NOT_CONFIGURED( "kernel parameter `%s` is too low (got %lu but expected at least %lu)", p->path, param, p->value );
166 0 : break;
167 0 : case WARN_MINIMUM:
168 0 : if( FD_UNLIKELY( !has_warned && param<(p->value) ) )
169 0 : FD_LOG_WARNING(( "kernel parameter `%s` is too low (got %lu but expected at least %lu). Proceeding but performance may be reduced.", p->path, param, p->value ));
170 0 : break;
171 0 : case WARN_EXACT:
172 0 : if( FD_UNLIKELY( !has_warned && param!=(p->value) ) )
173 0 : FD_LOG_WARNING(( "kernel parameter `%s` is set to %lu, not the expected value of %lu. Proceeding but performance may be reduced.", p->path, param, p->value ));
174 0 : break;
175 0 : }
176 0 : }
177 :
178 0 : has_warned = 1;
179 :
180 0 : CONFIGURE_OK();
181 0 : }
182 :
183 : static configure_result_t
184 : check( config_t const * config,
185 0 : int check_type FD_PARAM_UNUSED ) {
186 0 : configure_result_t r;
187 :
188 0 : r = check_param_list( params );
189 0 : if( r.result!=CONFIGURE_OK ) return r;
190 :
191 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
192 0 : r = check_param_list( xdp_params );
193 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
194 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
195 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
196 0 : r = check_param_list( sock_params );
197 0 : } else if( 0==strcmp( config->net.provider, "mlx5" ) ) {
198 : /* mlx5 has no provider-specific sysctls */
199 0 : } else {
200 0 : FD_LOG_ERR(( "unknown net provider: %s", config->net.provider ));
201 0 : }
202 0 : if( r.result!=CONFIGURE_OK ) return r;
203 :
204 0 : if( config->tiles.gui.enabled ) {
205 0 : r = check_param_list( gui_params );
206 0 : if( r.result!=CONFIGURE_OK ) return r;
207 0 : }
208 :
209 0 : CONFIGURE_OK();
210 0 : }
211 :
212 : configure_stage_t fd_cfg_stage_sysctl = {
213 : .name = NAME,
214 : .always_recreate = 0,
215 : .enabled = NULL,
216 : .init_perm = init_perm,
217 : .fini_perm = NULL,
218 : .init = init,
219 : .fini = NULL,
220 : .check = check,
221 : };
222 :
223 : #undef NAME
|