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 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 : {
82 : "/proc/sys/net/core/wmem_max",
83 : 0,
84 : ENFORCE_MINIMUM,
85 : 0,
86 : },
87 : {0}
88 : };
89 :
90 : static sysctl_param_t sock_params[] = {
91 : {
92 : "/proc/sys/net/core/rmem_max",
93 : 0,
94 : ENFORCE_MINIMUM,
95 : 0,
96 : },
97 : {
98 : "/proc/sys/net/core/wmem_max",
99 : 0,
100 : ENFORCE_MINIMUM,
101 : 0,
102 : },
103 : {0}
104 : };
105 :
106 : static sysctl_param_t gui_params[] = {
107 : {
108 : "/proc/sys/net/core/wmem_max",
109 : 4194304,
110 : ENFORCE_MINIMUM,
111 : 0,
112 : },
113 : {0}
114 : };
115 :
116 : static void
117 0 : init_param_list( sysctl_param_t const * list ) {
118 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
119 0 : ulong param;
120 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
121 : /* If the syctl file does not exist in /proc/sys, it's likely it
122 : doesn't exist anywhere else */
123 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
124 :
125 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 ) ));
126 0 : }
127 0 : switch( p->mode ) {
128 0 : case ENFORCE_MINIMUM:
129 0 : if( FD_UNLIKELY( param<(p->value) ) ) {
130 0 : FD_LOG_NOTICE(( "%sRUN: `echo \"%lu\" > %s`%s", fd_log_style_dim(), p->value, p->path, fd_log_style_normal() ));
131 0 : if( FD_UNLIKELY( -1==fd_file_util_write_ulong( p->path, p->value ) ) )
132 0 : FD_LOG_ERR(( "could not set kernel parameter `%s` to %lu (%i-%s)", p->path, p->value, errno, fd_io_strerror( errno ) ));
133 0 : }
134 0 : break;
135 0 : default:
136 0 : break;
137 0 : }
138 0 : }
139 0 : }
140 :
141 : static void
142 0 : init( config_t const * config ) {
143 0 : init_param_list( params );
144 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
145 0 : xdp_params[ 4 ].value = fd_ulong_min( (ulong)config->net.xdp.xdp_tx_queue_size*2048UL, (ulong)INT_MAX ); /* the XSK send buffer fd_xsk_init asks for */
146 0 : init_param_list( xdp_params );
147 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
148 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
149 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
150 0 : init_param_list( sock_params );
151 0 : }
152 0 : if( config->tiles.gui.enabled ) init_param_list( gui_params );
153 0 : }
154 :
155 : static configure_result_t
156 0 : check_param_list( sysctl_param_t const * list ) {
157 0 : static int has_warned = 0;
158 :
159 0 : for( sysctl_param_t const * p=list; p->path; p++ ) {
160 0 : ulong param;
161 0 : if( FD_UNLIKELY( -1==fd_file_util_read_ulong( p->path, ¶m ) ) ) {
162 0 : if( FD_UNLIKELY( p->allow_missing && errno==ENOENT ) ) continue;
163 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 ) ));
164 0 : }
165 0 : switch( p->mode ) {
166 0 : case ENFORCE_MINIMUM:
167 0 : if( FD_UNLIKELY( param<(p->value) ) )
168 0 : NOT_CONFIGURED( "kernel parameter `%s` is too low (got %lu but expected at least %lu)", p->path, param, p->value );
169 0 : break;
170 0 : case WARN_MINIMUM:
171 0 : if( FD_UNLIKELY( !has_warned && param<(p->value) ) )
172 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 ));
173 0 : break;
174 0 : case WARN_EXACT:
175 0 : if( FD_UNLIKELY( !has_warned && param!=(p->value) ) )
176 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 ));
177 0 : break;
178 0 : }
179 0 : }
180 :
181 0 : has_warned = 1;
182 :
183 0 : CONFIGURE_OK();
184 0 : }
185 :
186 : static configure_result_t
187 : check( config_t const * config,
188 0 : int check_type FD_PARAM_UNUSED ) {
189 0 : configure_result_t r;
190 :
191 0 : r = check_param_list( params );
192 0 : if( r.result!=CONFIGURE_OK ) return r;
193 :
194 0 : if( 0==strcmp( config->net.provider, "xdp" ) ) {
195 0 : xdp_params[ 4 ].value = fd_ulong_min( (ulong)config->net.xdp.xdp_tx_queue_size*2048UL, (ulong)INT_MAX ); /* the XSK send buffer fd_xsk_init asks for */
196 0 : r = check_param_list( xdp_params );
197 0 : } else if( 0==strcmp( config->net.provider, "socket" ) ) {
198 0 : sock_params[ 0 ].value = config->net.socket.receive_buffer_size;
199 0 : sock_params[ 1 ].value = config->net.socket.send_buffer_size;
200 0 : r = check_param_list( sock_params );
201 0 : } else if( 0==strcmp( config->net.provider, "mlx5" ) ) {
202 : /* mlx5 has no provider-specific sysctls */
203 0 : } else {
204 0 : FD_LOG_ERR(( "unknown net provider: %s", config->net.provider ));
205 0 : }
206 0 : if( r.result!=CONFIGURE_OK ) return r;
207 :
208 0 : if( config->tiles.gui.enabled ) {
209 0 : r = check_param_list( gui_params );
210 0 : if( r.result!=CONFIGURE_OK ) return r;
211 0 : }
212 :
213 0 : CONFIGURE_OK();
214 0 : }
215 :
216 : configure_stage_t fd_cfg_stage_sysctl = {
217 : .name = NAME,
218 : .always_recreate = 0,
219 : .enabled = NULL,
220 : .init_perm = init_perm,
221 : .fini_perm = NULL,
222 : .init = init,
223 : .fini = NULL,
224 : .check = check,
225 : };
226 :
227 : #undef NAME
|