diff options
author | dormando <dormando@rydia.net> | 2022-01-26 22:33:17 -0800 |
---|---|---|
committer | dormando <dormando@rydia.net> | 2022-01-26 22:33:17 -0800 |
commit | 5e5f18a893d3670b741a23deb282ddbf7ddc5fd0 (patch) | |
tree | 08a56206edc5f1da837c5c7f70f6833c03bde2f0 | |
parent | 52947e418f437e4aa6fb62e0fad715492ae1e38e (diff) | |
download | memcached-5e5f18a893d3670b741a23deb282ddbf7ddc5fd0.tar.gz |
proxy: `-o proxy_uring` to enable io_uring
instead of automatically attempting to use io_uring if compiled in,
require a start option.
-rw-r--r-- | memcached.c | 10 | ||||
-rw-r--r-- | memcached.h | 1 | ||||
-rw-r--r-- | proto_proxy.c | 90 | ||||
-rw-r--r-- | proto_proxy.h | 2 |
4 files changed, 60 insertions, 43 deletions
diff --git a/memcached.c b/memcached.c index 0f58744..2c5e41d 100644 --- a/memcached.c +++ b/memcached.c @@ -4040,6 +4040,9 @@ static void usage(void) { #endif #ifdef PROXY printf(" - proxy_config: path to lua config file.\n"); +#ifdef HAVE_LIBURING + printf(" - proxy_uring: enable IO_URING for proxy backends.\n"); +#endif #endif #ifdef TLS printf(" - ssl_chain_cert: certificate chain file in PEM format\n" @@ -4732,6 +4735,7 @@ int main (int argc, char **argv) { #endif #ifdef PROXY PROXY_CONFIG, + PROXY_URING, #endif #ifdef MEMCACHED_DEBUG RELAXED_PRIVILEGES, @@ -4790,6 +4794,7 @@ int main (int argc, char **argv) { #endif #ifdef PROXY [PROXY_CONFIG] = "proxy_config", + [PROXY_URING] = "proxy_uring", #endif #ifdef MEMCACHED_DEBUG [RELAXED_PRIVILEGES] = "relaxed_privileges", @@ -5549,6 +5554,9 @@ int main (int argc, char **argv) { settings.binding_protocol = proxy_prot; protocol_specified = true; break; + case PROXY_URING: + settings.proxy_uring = true; + break; #endif #ifdef MEMCACHED_DEBUG case RELAXED_PRIVILEGES: @@ -5955,7 +5963,7 @@ int main (int argc, char **argv) { /* start up worker threads if MT mode */ #ifdef PROXY if (settings.proxy_enabled) { - proxy_init(); + proxy_init(settings.proxy_uring); if (proxy_load_config(settings.proxy_ctx) != 0) { exit(EXIT_FAILURE); } diff --git a/memcached.h b/memcached.h index b0e10f7..f096f44 100644 --- a/memcached.h +++ b/memcached.h @@ -517,6 +517,7 @@ struct settings { char *memory_file; /* warm restart memory file path */ #ifdef PROXY bool proxy_enabled; + bool proxy_uring; /* if the proxy should use io_uring */ char *proxy_startfile; /* lua file to run when workers start */ void *proxy_ctx; /* proxy's state context */ #endif diff --git a/proto_proxy.c b/proto_proxy.c index 6ff904c..5ee29e1 100644 --- a/proto_proxy.c +++ b/proto_proxy.c @@ -193,6 +193,7 @@ typedef struct { pool_head_t manager_head; // stack for pool deallocation. bool worker_done; // signal variable for the worker lock/cond system. bool worker_failed; // covered by worker_lock as well. + bool use_uring; // use IO_URING for backend connections. struct proxy_global_stats global_stats; struct proxy_user_stats user_stats; struct proxy_timeouts timeouts; // NOTE: updates covered by stats_lock @@ -652,54 +653,60 @@ static int _start_proxy_config_threads(proxy_ctx_t *ctx) { // event threads. static void _proxy_init_evthread_events(proxy_event_thread_t *t) { #ifdef HAVE_LIBURING - bool use_uring = true; + bool use_uring = t->ctx->use_uring; struct io_uring_params p = {0}; assert(t->event_fd); // uring only exists where eventfd also does. // Setup the CQSIZE to be much larger than SQ size, since backpressure // issues can cause us to block on SQ submissions and as a network server, // stuff happens. - p.flags = IORING_SETUP_CQSIZE; - p.cq_entries = PRING_QUEUE_CQ_ENTRIES; - int ret = io_uring_queue_init_params(PRING_QUEUE_SQ_ENTRIES, &t->ring, &p); - if (ret) { - perror("io_uring_queue_init_params"); - exit(1); - } - if (!(p.features & IORING_FEAT_NODROP)) { - fprintf(stderr, "uring: kernel missing IORING_FEAT_NODROP, using libevent\n"); - use_uring = false; - } - if (!(p.features & IORING_FEAT_SINGLE_MMAP)) { - fprintf(stderr, "uring: kernel missing IORING_FEAT_SINGLE_MMAP, using libevent\n"); - use_uring = false; - } - if (!(p.features & IORING_FEAT_FAST_POLL)) { - fprintf(stderr, "uring: kernel missing IORING_FEAT_FAST_POLL, using libevent\n"); - use_uring = false; - } if (use_uring) { - // FIXME: Sigh. we need a blocking event_fd for io_uring but we've a - // chicken and egg in here. need a better structure... in meantime - // re-create the event_fd. - close(t->event_fd); - t->event_fd = eventfd(0, 0); - // FIXME: hack for event init. - t->ur_notify_event.set = false; - _proxy_evthr_evset_notifier(t); - - // periodic data updater for event thread - t->ur_clock_event.cb = proxy_event_updater_ur; - t->ur_clock_event.udata = t; - t->ur_clock_event.set = false; - _proxy_evthr_evset_clock(t); - - t->use_uring = true; - return; + p.flags = IORING_SETUP_CQSIZE; + p.cq_entries = PRING_QUEUE_CQ_ENTRIES; + int ret = io_uring_queue_init_params(PRING_QUEUE_SQ_ENTRIES, &t->ring, &p); + if (ret) { + perror("io_uring_queue_init_params"); + exit(1); + } + if (!(p.features & IORING_FEAT_NODROP)) { + fprintf(stderr, "uring: kernel missing IORING_FEAT_NODROP, using libevent\n"); + use_uring = false; + } + if (!(p.features & IORING_FEAT_SINGLE_MMAP)) { + fprintf(stderr, "uring: kernel missing IORING_FEAT_SINGLE_MMAP, using libevent\n"); + use_uring = false; + } + if (!(p.features & IORING_FEAT_FAST_POLL)) { + fprintf(stderr, "uring: kernel missing IORING_FEAT_FAST_POLL, using libevent\n"); + use_uring = false; + } + + if (use_uring) { + // FIXME: Sigh. we need a blocking event_fd for io_uring but we've a + // chicken and egg in here. need a better structure... in meantime + // re-create the event_fd. + close(t->event_fd); + t->event_fd = eventfd(0, 0); + // FIXME: hack for event init. + t->ur_notify_event.set = false; + _proxy_evthr_evset_notifier(t); + + // periodic data updater for event thread + t->ur_clock_event.cb = proxy_event_updater_ur; + t->ur_clock_event.udata = t; + t->ur_clock_event.set = false; + _proxy_evthr_evset_clock(t); + + t->use_uring = true; + return; + } else { + // Decided to not use io_uring, so don't waste memory. + t->use_uring = false; + io_uring_queue_exit(&t->ring); + } } else { - // Decided to not use io_uring, so don't waste memory. - io_uring_queue_exit(&t->ring); + t->use_uring = false; } #endif @@ -739,9 +746,10 @@ static void _proxy_init_evthread_events(proxy_event_thread_t *t) { // start the centralized lua state and config thread. // TODO: return ctx/state. avoid global vars. -void proxy_init(void) { +void proxy_init(bool use_uring) { proxy_ctx_t *ctx = calloc(1, sizeof(proxy_ctx_t)); settings.proxy_ctx = ctx; // FIXME: return and deal with outside? + ctx->use_uring = use_uring; pthread_mutex_init(&ctx->config_lock, NULL); pthread_cond_init(&ctx->config_cond, NULL); @@ -777,6 +785,7 @@ void proxy_init(void) { ctx->proxy_threads = threads; for (int i = 0; i < 1; i++) { proxy_event_thread_t *t = &threads[i]; + t->ctx = ctx; #ifdef USE_EVENTFD t->event_fd = eventfd(0, EFD_NONBLOCK); // FIXME: eventfd can fail? @@ -797,7 +806,6 @@ void proxy_init(void) { pthread_mutex_init(&t->mutex, NULL); pthread_cond_init(&t->cond, NULL); - t->ctx = ctx; memcpy(&t->timeouts, &ctx->timeouts, sizeof(t->timeouts)); #ifdef HAVE_LIBURING diff --git a/proto_proxy.h b/proto_proxy.h index aa58323..64d5759 100644 --- a/proto_proxy.h +++ b/proto_proxy.h @@ -8,7 +8,7 @@ void process_proxy_stats(ADD_STAT add_stats, conn *c); int try_read_command_proxy(conn *c); void complete_nread_proxy(conn *c); void proxy_thread_init(LIBEVENT_THREAD *thr); -void proxy_init(void); +void proxy_init(bool proxy_uring); // TODO: need better names or a better interface for these. can be confusing // to reason about the order. void proxy_start_reload(void *arg); |