summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorin Coras <fcoras@cisco.com>2023-03-05 11:45:38 -0800
committerDave Wallace <dwallacelf@gmail.com>2023-03-06 22:59:40 +0000
commitc86662a213ce751354ac513a3da95117fff31845 (patch)
tree8e236661a65fdebd484514057985b2b3163d9f88
parent87767d82d77b75e8b7bc5da11c94f29cb035ed47 (diff)
vcl: always drain libc epoll with eventfds in ldp
Otherwise if vcl epoll lt events are ignored by the app, libc and vcl mq events are never drained. Type: fix Signed-off-by: Florin Coras <fcoras@cisco.com> Change-Id: I1e22f6da46d56236c52714181f6c20dcb80a33a5
-rw-r--r--src/vcl/ldp.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c
index 9e01ac95bec..9876c1ea17a 100644
--- a/src/vcl/ldp.c
+++ b/src/vcl/ldp.c
@@ -2413,8 +2413,10 @@ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
* was acquired outside of the LD_PRELOAD process context.
* In any case, if we get one, punt it to libc_epoll_ctl.
*/
- LDBG (1, "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
- " event %p", epfd, op, fd, event);
+ LDBG (1,
+ "epfd %d: calling libc_epoll_ctl: op %d, fd %d"
+ " events 0x%x",
+ epfd, op, fd, event ? event->events : 0);
rv = libc_epoll_ctl (epfd, op, fd, event);
goto done;
@@ -2427,8 +2429,10 @@ epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
if (vlsh != VLS_INVALID_HANDLE)
{
- LDBG (1, "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
- " event %p", epfd, vep_vlsh, op, vlsh, event);
+ LDBG (1,
+ "epfd %d: calling vls_epoll_ctl: ep_vlsh %d op %d, vlsh %u,"
+ " events 0x%x",
+ epfd, vep_vlsh, op, vlsh, event ? event->events : 0);
rv = vls_epoll_ctl (vep_vlsh, op, vlsh, event);
if (rv != VPPCOM_OK)
@@ -2566,8 +2570,9 @@ static inline int
ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events,
int maxevents, int timeout, const sigset_t * sigmask)
{
+ int libc_epfd, rv = 0, num_ev, libc_num_ev, vcl_wups = 0;
+ struct epoll_event *libc_evts;
ldp_worker_ctx_t *ldpw;
- int libc_epfd, rv = 0, num_ev, vcl_wups = 0;
vls_handle_t ep_vlsh;
ldp_init_check ();
@@ -2643,7 +2648,11 @@ ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events,
/* Request to only drain unhandled to prevent libc_epoll_wait starved */
rv = vls_epoll_wait (ep_vlsh, events, maxevents, -2);
if (rv > 0)
- goto done;
+ {
+ timeout = 0;
+ if (rv >= maxevents)
+ goto done;
+ }
else if (PREDICT_FALSE (rv < 0))
{
errno = -rv;
@@ -2652,30 +2661,40 @@ ldp_epoll_pwait_eventfd (int epfd, struct epoll_event *events,
}
epoll_again:
- rv = libc_epoll_pwait (libc_epfd, events, maxevents, timeout, sigmask);
- if (rv <= 0)
- goto done;
- for (int i = 0; i < rv; i++)
+
+ libc_evts = &events[rv];
+ libc_num_ev =
+ libc_epoll_pwait (libc_epfd, libc_evts, maxevents - rv, timeout, sigmask);
+ if (libc_num_ev <= 0)
+ {
+ rv = rv >= 0 ? rv : -1;
+ goto done;
+ }
+
+ for (int i = 0; i < libc_num_ev; i++)
{
- if (events[i].data.fd == ldpw->vcl_mq_epfd)
+ if (libc_evts[i].data.fd == ldpw->vcl_mq_epfd)
{
/* We should remove mq epoll fd from events. */
- rv--;
- if (i != rv)
+ libc_num_ev--;
+ if (i != libc_num_ev)
{
- events[i].events = events[rv].events;
- events[i].data.u64 = events[rv].data.u64;
+ libc_evts[i].events = libc_evts[libc_num_ev].events;
+ libc_evts[i].data.u64 = libc_evts[libc_num_ev].data.u64;
}
- num_ev = vls_epoll_wait (ep_vlsh, &events[rv], maxevents - rv, 0);
+ num_ev = vls_epoll_wait (ep_vlsh, &libc_evts[libc_num_ev],
+ maxevents - libc_num_ev, 0);
if (PREDICT_TRUE (num_ev > 0))
rv += num_ev;
/* Woken up by vcl but no events generated. Accept it once */
- if (rv == 0 && vcl_wups++ < 1)
+ if (rv == 0 && libc_num_ev == 0 && timeout && vcl_wups++ < 1)
goto epoll_again;
break;
}
}
+ rv += libc_num_ev;
+
done:
return rv;
}