aboutsummaryrefslogtreecommitdiffstats
path: root/src/vcl
diff options
context:
space:
mode:
Diffstat (limited to 'src/vcl')
-rw-r--r--src/vcl/vcl_private.c51
-rw-r--r--src/vcl/vcl_private.h6
-rw-r--r--src/vcl/vppcom.c3
3 files changed, 60 insertions, 0 deletions
diff --git a/src/vcl/vcl_private.c b/src/vcl/vcl_private.c
index 6892688da5a..7a9b60a1959 100644
--- a/src/vcl/vcl_private.c
+++ b/src/vcl/vcl_private.c
@@ -189,6 +189,55 @@ vcl_worker_cleanup_cb (void *arg)
}
void
+vcl_worker_detached_start_signal_mq (vcl_worker_t *wrk)
+{
+ /* Generate mq epfd events using pipes to hopefully force
+ * calls into epoll_wait which retries attaching to vpp */
+ if (!wrk->detached_pipefds[0])
+ {
+ if (pipe (wrk->detached_pipefds))
+ {
+ VDBG (0, "failed to add mq eventfd to mq epoll fd");
+ exit (1);
+ }
+ }
+
+ struct epoll_event evt = {};
+ evt.events = EPOLLIN;
+ evt.data.u32 = wrk->detached_pipefds[0];
+ if (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);
+ }
+
+ int __clib_unused rv;
+ u8 sig = 1;
+ rv = write (wrk->detached_pipefds[1], &sig, 1);
+}
+
+void
+vcl_worker_detached_signal_mq (vcl_worker_t *wrk)
+{
+ int __clib_unused rv;
+ u8 buf;
+ rv = read (wrk->detached_pipefds[0], &buf, 1);
+ rv = write (wrk->detached_pipefds[1], &buf, 1);
+}
+
+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)
+ {
+ VDBG (0, "failed to del mq eventfd to mq epoll fd");
+ exit (1);
+ }
+}
+
+void
vcl_worker_detach_sessions (vcl_worker_t *wrk)
{
session_event_t *e;
@@ -239,6 +288,8 @@ vcl_worker_detach_sessions (vcl_worker_t *wrk)
vec_free (seg_indices);
hash_free (seg_indices_map);
+
+ vcl_worker_detached_start_signal_mq (wrk);
}
void
diff --git a/src/vcl/vcl_private.h b/src/vcl/vcl_private.h
index c92bb58169d..72f0a8327f0 100644
--- a/src/vcl/vcl_private.h
+++ b/src/vcl/vcl_private.h
@@ -325,6 +325,9 @@ typedef struct vcl_worker_
/* functions to be called pre/post wait if vcl managed by vls */
vcl_worker_wait_mq_fn pre_wait_fn;
vcl_worker_wait_mq_fn post_wait_fn;
+
+ /* mq_epfd signal pipes when wrk detached from vpp */
+ int detached_pipefds[2];
} vcl_worker_t;
STATIC_ASSERT (sizeof (session_disconnected_msg_t) <= 16,
@@ -799,6 +802,9 @@ void vcl_worker_detach_sessions (vcl_worker_t *wrk);
void vcl_worker_set_wait_mq_fns (vcl_worker_wait_mq_fn pre_wait,
vcl_worker_wait_mq_fn post_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);
/*
* VCL Binary API
*/
diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c
index 1e9c915ce39..8bc5f42d4a6 100644
--- a/src/vcl/vppcom.c
+++ b/src/vcl/vppcom.c
@@ -1404,6 +1404,8 @@ vcl_api_retry_attach (vcl_worker_t *wrk)
{
vcl_session_t *s;
+ vcl_worker_detached_signal_mq (wrk);
+
clib_spinlock_lock (&vcm->workers_lock);
if (vcl_is_first_reattach_to_execute ())
{
@@ -1412,6 +1414,7 @@ vcl_api_retry_attach (vcl_worker_t *wrk)
clib_spinlock_unlock (&vcm->workers_lock);
return;
}
+ vcl_worker_detached_stop_signal_mq (wrk);
vcl_set_reattach_counter ();
clib_spinlock_unlock (&vcm->workers_lock);
}