|
46 | 46 |
|
47 | 47 | static void accept_connection(h2o_socket_t *listener, const char *err); |
48 | 48 | static void accept_http_connection(h2o_socket_t *listener, const char *err); |
49 | | -static int get_listener_socket(const char *bind_address, uint16_t port); |
| 49 | +static int get_listener_socket(bool is_main_thread, |
| 50 | + int bpf_fd, |
| 51 | + const char *bind_address, |
| 52 | + uint16_t port); |
50 | 53 | static void on_close_connection(void *data); |
51 | 54 | static void process_messages(h2o_multithread_receiver_t *receiver, h2o_linklist_t *messages); |
52 | 55 | static void shutdown_server(h2o_socket_t *listener, const char *err); |
53 | | -static void start_accept_polling(const config_t *config, |
| 56 | +static void start_accept_polling(bool is_main_thread, |
| 57 | + int bpf_fd, |
| 58 | + const config_t *config, |
54 | 59 | h2o_socket_cb accept_cb, |
55 | 60 | bool is_https, |
56 | 61 | event_loop_t *loop); |
@@ -98,7 +103,10 @@ static void accept_http_connection(h2o_socket_t *listener, const char *err) |
98 | 103 | ctx->event_loop.h2o_accept_ctx.ssl_ctx = ssl_ctx; |
99 | 104 | } |
100 | 105 |
|
101 | | -static int get_listener_socket(const char *bind_address, uint16_t port) |
| 106 | +static int get_listener_socket(bool is_main_thread, |
| 107 | + int bpf_fd, |
| 108 | + const char *bind_address, |
| 109 | + uint16_t port) |
102 | 110 | { |
103 | 111 | int ret = -1; |
104 | 112 | char buf[16]; |
@@ -148,6 +156,15 @@ static int get_listener_socket(const char *bind_address, uint16_t port) |
148 | 156 | LOCAL_CHECK_ERRNO(setsockopt, s, IPPROTO_TCP, TCP_FASTOPEN, &option, sizeof(option)); |
149 | 157 | LOCAL_CHECK_ERRNO(bind, s, iter->ai_addr, iter->ai_addrlen); |
150 | 158 | LOCAL_CHECK_ERRNO(listen, s, INT_MAX); |
| 159 | + |
| 160 | + if (is_main_thread && bpf_fd >= 0) |
| 161 | + LOCAL_CHECK_ERRNO(setsockopt, |
| 162 | + s, |
| 163 | + SOL_SOCKET, |
| 164 | + SO_ATTACH_REUSEPORT_EBPF, |
| 165 | + &bpf_fd, |
| 166 | + sizeof(bpf_fd)); |
| 167 | + |
151 | 168 | ret = s; |
152 | 169 | break; |
153 | 170 |
|
@@ -256,16 +273,17 @@ static void shutdown_server(h2o_socket_t *listener, const char *err) |
256 | 273 | } |
257 | 274 | } |
258 | 275 |
|
259 | | -static void start_accept_polling(const config_t *config, |
| 276 | +static void start_accept_polling(bool is_main_thread, |
| 277 | + int bpf_fd, |
| 278 | + const config_t *config, |
260 | 279 | h2o_socket_cb accept_cb, |
261 | 280 | bool is_https, |
262 | 281 | event_loop_t *loop) |
263 | 282 | { |
264 | | - const int listener_sd = get_listener_socket(config->bind_address, |
| 283 | + const int listener_sd = get_listener_socket(is_main_thread, |
| 284 | + bpf_fd, |
| 285 | + config->bind_address, |
265 | 286 | is_https ? config->https_port : config->port); |
266 | | - // Let all the threads race to call accept() on the socket; since the latter is |
267 | | - // non-blocking, that will virtually act as load balancing, and SO_REUSEPORT |
268 | | - // will make it efficient. |
269 | 287 | h2o_socket_t * const h2o_socket = h2o_evloop_socket_create(loop->h2o_ctx.loop, |
270 | 288 | listener_sd, |
271 | 289 | H2O_SOCKET_FLAG_DONT_READ); |
@@ -345,13 +363,18 @@ void initialize_event_loop(bool is_main_thread, |
345 | 363 |
|
346 | 364 | if (global_data->ssl_ctx) { |
347 | 365 | loop->h2o_accept_ctx.ssl_ctx = global_data->ssl_ctx; |
348 | | - start_accept_polling(config, accept_connection, true, loop); |
| 366 | + start_accept_polling(is_main_thread, |
| 367 | + global_data->bpf_fd, |
| 368 | + config, |
| 369 | + accept_connection, |
| 370 | + true, |
| 371 | + loop); |
349 | 372 | // Assume that the majority of the connections use HTTPS, |
350 | 373 | // so HTTP can take a few extra operations. |
351 | 374 | accept_cb = accept_http_connection; |
352 | 375 | } |
353 | 376 |
|
354 | | - start_accept_polling(config, accept_cb, false, loop); |
| 377 | + start_accept_polling(is_main_thread, global_data->bpf_fd, config, accept_cb, false, loop); |
355 | 378 | h2o_multithread_register_receiver(loop->h2o_ctx.queue, |
356 | 379 | h2o_receiver, |
357 | 380 | process_messages); |
|
0 commit comments