From 409b66bd16218f118d02bfdaaf77ae11b2c43a95 Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Mon, 2 Jun 2025 00:12:36 -0400 Subject: [PATCH] vcl: inject epoll functions into vcl from ldp Instead of trying to detect in ldp if vcl is asking for real epoll, have vcl use libc epoll directly. This is obtained either at startup or by means of ldp/vls. Type: improvement Change-Id: Ia77d49aef33be7618aeeb1a1d6a618d7ef4bcc6c Signed-off-by: Florin Coras --- src/vcl/ldp.c | 30 ++++-------------------------- src/vcl/vcl_locked.c | 17 ++++++++--------- src/vcl/vcl_locked.h | 9 ++++++++- src/vcl/vcl_private.c | 29 +++++++++++++++++++---------- src/vcl/vcl_private.h | 13 +++++++++++-- src/vcl/vcl_sapi.c | 4 ---- src/vcl/vppcom.c | 9 +++++---- 7 files changed, 55 insertions(+), 56 deletions(-) diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index d9f45b2bce9..b4978bf1a81 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -122,9 +122,6 @@ typedef struct u32 vlsh_bit_mask; u32 debug; - /** vcl needs next epoll_create to go to libc_epoll */ - u8 vcl_needs_real_epoll; - /** * crypto state used only for testing */ @@ -288,11 +285,11 @@ ldp_init (void) ldp_init_cfg (); ldp->init = 1; - ldp->vcl_needs_real_epoll = 1; + vls_set_epoll_fns ( + (vls_epoll_fns_t){ libc_epoll_create1, libc_epoll_ctl, libc_epoll_wait }); rv = vls_app_create (ldp_get_app_name ()); if (rv != VPPCOM_OK) { - ldp->vcl_needs_real_epoll = 0; if (rv == VPPCOM_EEXIST) return 0; LDBG (2, @@ -302,7 +299,6 @@ ldp_init (void) ldp->init = 0; return rv; } - ldp->vcl_needs_real_epoll = 0; LDBG (0, "LDP initialization: done!"); @@ -2385,22 +2381,11 @@ shutdown (int fd, int how) int epoll_create1 (int flags) { - ldp_worker_ctx_t *ldpw = ldp_worker_get_current (); vls_handle_t vlsh; int rv; ldp_init_check (); - if (ldp->vcl_needs_real_epoll || vls_use_real_epoll ()) - { - rv = libc_epoll_create1 (flags); - ldp->vcl_needs_real_epoll = 0; - /* Assume this is a request to create the mq epfd */ - ldpw->vcl_mq_epfd = rv; - LDBG (0, "created vcl epfd %u", rv); - return rv; - } - vlsh = vls_epoll_create (); if (PREDICT_FALSE (vlsh == VLS_INVALID_HANDLE)) { @@ -2527,10 +2512,6 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents, if (PREDICT_FALSE (vppcom_worker_index () == ~0)) vls_register_vcl_worker (); - ldpw = ldp_worker_get_current (); - if (epfd == ldpw->vcl_mq_epfd) - return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask); - ep_vlsh = ldp_fd_to_vlsh (epfd); if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE)) { @@ -2539,6 +2520,7 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents, return -1; } + ldpw = ldp_worker_get_current (); if (PREDICT_FALSE (ldpw->clib_time.init_cpu_time == 0)) clib_time_init (&ldpw->clib_time); time_to_wait = ((timeout >= 0) ? (double) timeout / 1000 : 0); @@ -2611,9 +2593,6 @@ ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events, vls_register_vcl_worker (); ldpw = ldp_worker_get_current (); - if (epfd == ldpw->vcl_mq_epfd) - return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask); - ep_vlsh = ldp_fd_to_vlsh (epfd); if (PREDICT_FALSE (ep_vlsh == VLS_INVALID_HANDLE)) { @@ -2655,8 +2634,7 @@ ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events, ldpw->vcl_mq_epfd = vppcom_mq_epoll_fd (); e.events = EPOLLIN; e.data.fd = ldpw->vcl_mq_epfd; - if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) < - 0) + if (libc_epoll_ctl (libc_epfd, EPOLL_CTL_ADD, ldpw->vcl_mq_epfd, &e) < 0) { LDBG (0, "epfd %d, add libc mq epoll fd %d to libc epoll fd %d", epfd, ldpw->vcl_mq_epfd, libc_epfd); diff --git a/src/vcl/vcl_locked.c b/src/vcl/vcl_locked.c index aaf47c8f9ef..15b53a3aba2 100644 --- a/src/vcl/vcl_locked.c +++ b/src/vcl/vcl_locked.c @@ -2216,15 +2216,6 @@ vls_mt_wrk_supported (void) return vcm->cfg.mt_wrk_supported; } -int -vls_use_real_epoll (void) -{ - if (vcl_get_worker_index () == ~0) - return 0; - - return vcl_worker_get_current ()->vcl_needs_real_epoll; -} - int vls_set_libc_epfd (vls_handle_t ep_vlsh, int libc_epfd) { @@ -2271,6 +2262,14 @@ vls_get_libc_epfd (vls_handle_t ep_vlsh) return rv; } +void +vls_set_epoll_fns (vls_epoll_fns_t ep_fns) +{ + vcm->vcl_epoll_create1 = ep_fns.epoll_create1_fn; + vcm->vcl_epoll_ctl = ep_fns.epoll_ctl_fn; + vcm->vcl_epoll_wait = ep_fns.epoll_wait_fn; +} + void vls_register_vcl_worker (void) { diff --git a/src/vcl/vcl_locked.h b/src/vcl/vcl_locked.h index 98a1c542e4a..a55d182a235 100644 --- a/src/vcl/vcl_locked.h +++ b/src/vcl/vcl_locked.h @@ -24,6 +24,13 @@ #define VLS_WORKER_RPC_TIMEOUT 3 /* timeout to wait rpc response. */ typedef int vls_handle_t; +typedef struct vls_epoll_fns_ +{ + int (*epoll_create1_fn) (int flags); + int (*epoll_ctl_fn) (int epfd, int op, int fd, struct epoll_event *event); + int (*epoll_wait_fn) (int epfd, struct epoll_event *events, int maxevents, + int timeout); +} vls_epoll_fns_t; vls_handle_t vls_create (uint8_t proto, uint8_t is_nonblocking); int vls_shutdown (vls_handle_t vlsh, int how); @@ -57,9 +64,9 @@ vls_handle_t vls_session_index_to_vlsh (uint32_t session_index); int vls_app_create (char *app_name); unsigned char vls_use_eventfd (void); unsigned char vls_mt_wrk_supported (void); -int vls_use_real_epoll (void); int vls_set_libc_epfd (vls_handle_t ep_vlsh, int libc_epfd); int vls_get_libc_epfd (vls_handle_t ep_vlsh); +void vls_set_epoll_fns (vls_epoll_fns_t ep_fns); void vls_register_vcl_worker (void); #endif /* SRC_VCL_VCL_LOCKED_H_ */ diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c index ea82c26803c..dcd827f2a61 100644 --- a/src/vcl/vcl_private.c +++ b/src/vcl/vcl_private.c @@ -48,7 +48,7 @@ vcl_mq_epoll_add_api_sock (vcl_worker_t *wrk) int rv; e.data.u32 = VCL_EP_SAPIFD_EVT; - rv = epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, cs->fd, &e); + rv = vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, cs->fd, &e); if (rv != EEXIST && rv < 0) return -1; @@ -77,7 +77,7 @@ vcl_mq_epoll_add_evfd (vcl_worker_t * wrk, svm_msg_q_t * mq) e.events = EPOLLIN; e.data.u32 = mqc_index; - if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, mq_fd, &e) < 0) + if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, mq_fd, &e) < 0) { VDBG (0, "failed to add mq eventfd to mq epoll fd"); return -1; @@ -101,7 +101,7 @@ vcl_mq_epoll_del_evfd (vcl_worker_t * wrk, u32 mqc_index) return -1; mqc = vcl_mq_evt_conn_get (wrk, mqc_index); - if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, mqc->mq_fd, 0) < 0) + if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, mqc->mq_fd, 0) < 0) { VDBG (0, "failed to del mq eventfd to mq epoll fd"); return -1; @@ -187,8 +187,8 @@ vcl_worker_detached_start_signal_mq (vcl_worker_t *wrk) struct epoll_event evt = {}; evt.events = EPOLLIN; evt.data.u32 = VCL_EP_PIPEFD_EVT; - if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, wrk->detached_pipefds[0], - &evt) < 0) + if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_ADD, + wrk->detached_pipefds[0], &evt) < 0) { VDBG (0, "failed to add mq eventfd to mq epoll fd"); exit (1); @@ -211,8 +211,8 @@ vcl_worker_detached_signal_mq (vcl_worker_t *wrk) void vcl_worker_detached_stop_signal_mq (vcl_worker_t *wrk) { - if (epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, wrk->detached_pipefds[0], 0) < - 0) + if (vcm->vcl_epoll_ctl (wrk->mqs_epfd, EPOLL_CTL_DEL, + wrk->detached_pipefds[0], 0) < 0) { VDBG (0, "failed to del mq eventfd to mq epoll fd"); exit (1); @@ -324,9 +324,7 @@ vcl_worker_alloc_and_init () wrk->mqs_epfd = -1; if (vcm->cfg.use_mq_eventfd) { - wrk->vcl_needs_real_epoll = 1; - wrk->mqs_epfd = epoll_create (1); - wrk->vcl_needs_real_epoll = 0; + wrk->mqs_epfd = vcm->vcl_epoll_create1 (0); if (wrk->mqs_epfd < 0) { clib_unix_warning ("epoll_create() returned"); @@ -374,6 +372,17 @@ vcl_worker_ctrl_mq (vcl_worker_t * wrk) return wrk->ctrl_mq; } +void +vcl_init_epoll_fns () +{ + if (!vcm->vcl_epoll_create1) + vcm->vcl_epoll_create1 = epoll_create1; + if (!vcm->vcl_epoll_ctl) + vcm->vcl_epoll_ctl = epoll_ctl; + if (!vcm->vcl_epoll_wait) + vcm->vcl_epoll_wait = epoll_wait; +} + int vcl_session_read_ready (vcl_session_t * s) { diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h index 609653f20a4..a66dbf33e87 100644 --- a/src/vcl/vcl_private.h +++ b/src/vcl/vcl_private.h @@ -320,8 +320,6 @@ typedef struct vcl_worker_ int session_attr_op_rv; transport_endpt_attr_t session_attr_rv; - /** vcl needs next epoll_create to go to libc_epoll */ - u8 vcl_needs_real_epoll; volatile int rpc_done; /* functions to be called pre/post wait if vcl managed by vls */ @@ -381,6 +379,14 @@ typedef struct vppcom_main_t_ vcl_rpc_fn_t *wrk_rpc_fn; + /* + * Pointers to libc epoll fns to avoid loops when ldp is on + */ + int (*vcl_epoll_create1) (int flags); + int (*vcl_epoll_ctl) (int epfd, int op, int fd, struct epoll_event *event); + int (*vcl_epoll_wait) (int epfd, struct epoll_event *events, int maxevents, + int timeout); + /* * Binary api context */ @@ -807,6 +813,9 @@ void vcl_worker_set_wait_mq_fns (vcl_worker_wait_mq_fn pre_wait, void vcl_worker_detached_start_signal_mq (vcl_worker_t *wrk); void vcl_worker_detached_signal_mq (vcl_worker_t *wrk); void vcl_worker_detached_stop_signal_mq (vcl_worker_t *wrk); + +void vcl_init_epoll_fns (void); + /* * VCL Binary API */ diff --git a/src/vcl/vcl_sapi.c b/src/vcl/vcl_sapi.c index e3e2b6ac377..f23273aa8f1 100644 --- a/src/vcl/vcl_sapi.c +++ b/src/vcl/vcl_sapi.c @@ -26,8 +26,6 @@ vcl_api_connect_app_socket (vcl_worker_t * wrk) cs->flags = CLIB_SOCKET_F_IS_CLIENT | CLIB_SOCKET_F_SEQPACKET | CLIB_SOCKET_F_BLOCKING; - wrk->vcl_needs_real_epoll = 1; - if ((err = clib_socket_init (cs))) { /* don't report the error to avoid flood of error messages during @@ -39,8 +37,6 @@ vcl_api_connect_app_socket (vcl_worker_t * wrk) done: - wrk->vcl_needs_real_epoll = 0; - return rv; } diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 0671a37ea29..62d2addd7bc 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -1482,6 +1482,7 @@ vppcom_app_create (const char *app_name) vcm->main_cpu = pthread_self (); vcm->main_pid = getpid (); vcm->app_name = format (0, "%s", app_name); + vcl_init_epoll_fns (); fifo_segment_main_init (&vcm->segment_main, (uword) ~0, 20 /* timeout in secs */); pool_alloc (vcm->workers, vcl_cfg->max_workers); @@ -2799,8 +2800,8 @@ vppcom_select_eventfd (vcl_worker_t * wrk, int n_bits, do { - n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events, - vec_len (wrk->mq_events), time_to_wait); + n_mq_evts = vcm->vcl_epoll_wait (wrk->mqs_epfd, wrk->mq_events, + vec_len (wrk->mq_events), time_to_wait); if (n_mq_evts < 0) { if (errno == EINTR) @@ -3599,8 +3600,8 @@ vppcom_epoll_wait_eventfd (vcl_worker_t *wrk, struct epoll_event *events, do { - n_mq_evts = epoll_wait (wrk->mqs_epfd, wrk->mq_events, - vec_len (wrk->mq_events), timeout_ms); + n_mq_evts = vcm->vcl_epoll_wait (wrk->mqs_epfd, wrk->mq_events, + vec_len (wrk->mq_events), timeout_ms); if (n_mq_evts < 0) { if (errno == EINTR) -- 2.16.6