vcl/ldp: fix poll
[vpp.git] / src / vcl / ldp.c
index ce243df..96a7c36 100644 (file)
@@ -65,11 +65,21 @@ typedef struct
   clib_bitmap_t *libc_wr_bitmap;
   clib_bitmap_t *libc_ex_bitmap;
   vcl_poll_t *vcl_poll;
+  struct pollfd *libc_poll;
+  u16 *libc_poll_idxs;
   u8 select_vcl;
   u8 epoll_wait_vcl;
+  u8 vcl_needs_real_epoll;     /*< vcl needs next epoll_create to
+                                  go to libc_epoll */
+  int vcl_mq_epfd;
+
 } ldp_main_t;
 #define LDP_DEBUG ldp->debug
 
+#define LDBG(_lvl, _fmt, _args...)                                     \
+  if (ldp->debug > _lvl)                                               \
+    clib_warning (_fmt, ##_args)
+
 static ldp_main_t ldp_main = {
   .sid_bit_val = (1 << LDP_SID_BIT_MIN),
   .sid_bit_mask = (1 << LDP_SID_BIT_MIN) - 1,
@@ -125,107 +135,96 @@ ldp_sid_from_fd (int fd)
 static inline int
 ldp_init (void)
 {
-  int rv = 0;
+  int rv;
+
+  if (PREDICT_TRUE (ldp->init))
+    return 0;
 
-  if (PREDICT_FALSE (!ldp->init))
+  ldp->init = 1;
+  ldp->vcl_needs_real_epoll = 1;
+  rv = vppcom_app_create (ldp_get_app_name ());
+  if (rv != VPPCOM_OK)
     {
-      ldp->init = 1;
-      rv = vppcom_app_create (ldp_get_app_name ());
-      if (rv == VPPCOM_OK)
+      fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
+              " failed!  rv = %d (%s)\n",
+              getpid (), rv, vppcom_retval_str (rv));
+      ldp->init = 0;
+      return rv;
+    }
+  ldp->vcl_needs_real_epoll = 0;
+
+  char *env_var_str = getenv (LDP_ENV_DEBUG);
+  if (env_var_str)
+    {
+      u32 tmp;
+      if (sscanf (env_var_str, "%u", &tmp) != 1)
+       clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level specified in"
+                     " the env var " LDP_ENV_DEBUG " (%s)!", getpid (),
+                     env_var_str);
+      else
        {
-         char *env_var_str = getenv (LDP_ENV_DEBUG);
-         if (env_var_str)
-           {
-             u32 tmp;
-             if (sscanf (env_var_str, "%u", &tmp) != 1)
-               clib_warning ("LDP<%d>: WARNING: Invalid LDP debug level "
-                             "specified in the env var " LDP_ENV_DEBUG
-                             " (%s)!", getpid (), env_var_str);
-             else
-               {
-                 ldp->debug = tmp;
-                 if (LDP_DEBUG > 0)
-                   clib_warning ("LDP<%d>: configured LDP debug level (%u) "
-                                 "from the env var " LDP_ENV_DEBUG "!",
-                                 getpid (), ldp->debug);
-               }
-           }
+         ldp->debug = tmp;
+         LDBG (0, "LDP<%d>: configured LDP debug level (%u) from env var "
+               LDP_ENV_DEBUG "!", getpid (), ldp->debug);
+       }
+    }
 
-         env_var_str = getenv (LDP_ENV_APP_NAME);
-         if (env_var_str)
-           {
-             ldp_set_app_name (env_var_str);
-             if (LDP_DEBUG > 0)
-               clib_warning ("LDP<%d>: configured LDP app name (%s) "
-                             "from the env var " LDP_ENV_APP_NAME "!",
-                             getpid (), ldp->app_name);
-           }
+  env_var_str = getenv (LDP_ENV_APP_NAME);
+  if (env_var_str)
+    {
+      ldp_set_app_name (env_var_str);
+      LDBG (0, "LDP<%d>: configured LDP app name (%s) from the env var "
+           LDP_ENV_APP_NAME "!", getpid (), ldp->app_name);
+    }
 
-         env_var_str = getenv (LDP_ENV_SID_BIT);
-         if (env_var_str)
-           {
-             u32 sb;
-             if (sscanf (env_var_str, "%u", &sb) != 1)
-               {
-                 clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit "
-                               "specified in the env var "
-                               LDP_ENV_SID_BIT " (%s)!"
-                               "sid bit value %d (0x%x)",
-                               getpid (), env_var_str,
-                               ldp->sid_bit_val, ldp->sid_bit_val);
-               }
-             else if (sb < LDP_SID_BIT_MIN)
-               {
-                 ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
-                 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
-
-                 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) "
-                               "specified in the env var "
-                               LDP_ENV_SID_BIT " (%s) is too small. "
-                               "Using LDP_SID_BIT_MIN (%d)! "
-                               "sid bit value %d (0x%x)",
-                               getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
-                               ldp->sid_bit_val, ldp->sid_bit_val);
-               }
-             else if (sb > LDP_SID_BIT_MAX)
-               {
-                 ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
-                 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
-
-                 clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) "
-                               "specified in the env var "
-                               LDP_ENV_SID_BIT " (%s) is too big. "
-                               "Using LDP_SID_BIT_MAX (%d)! "
-                               "sid bit value %d (0x%x)",
-                               getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
-                               ldp->sid_bit_val, ldp->sid_bit_val);
-               }
-             else
-               {
-                 ldp->sid_bit_val = (1 << sb);
-                 ldp->sid_bit_mask = ldp->sid_bit_val - 1;
-
-                 if (LDP_DEBUG > 0)
-                   clib_warning ("LDP<%d>: configured LDP sid bit (%u) "
-                                 "from " LDP_ENV_SID_BIT
-                                 "!  sid bit value %d (0x%x)", getpid (),
-                                 sb, ldp->sid_bit_val, ldp->sid_bit_val);
-               }
-           }
+  env_var_str = getenv (LDP_ENV_SID_BIT);
+  if (env_var_str)
+    {
+      u32 sb;
+      if (sscanf (env_var_str, "%u", &sb) != 1)
+       {
+         clib_warning ("LDP<%d>: WARNING: Invalid LDP sid bit specified in"
+                       " the env var " LDP_ENV_SID_BIT " (%s)! sid bit "
+                       "value %d (0x%x)", getpid (), env_var_str,
+                       ldp->sid_bit_val, ldp->sid_bit_val);
+       }
+      else if (sb < LDP_SID_BIT_MIN)
+       {
+         ldp->sid_bit_val = (1 << LDP_SID_BIT_MIN);
+         ldp->sid_bit_mask = ldp->sid_bit_val - 1;
+
+         clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
+                       " env var " LDP_ENV_SID_BIT " (%s) is too small. "
+                       "Using LDP_SID_BIT_MIN (%d)! sid bit value %d (0x%x)",
+                       getpid (), sb, env_var_str, LDP_SID_BIT_MIN,
+                       ldp->sid_bit_val, ldp->sid_bit_val);
+       }
+      else if (sb > LDP_SID_BIT_MAX)
+       {
+         ldp->sid_bit_val = (1 << LDP_SID_BIT_MAX);
+         ldp->sid_bit_mask = ldp->sid_bit_val - 1;
 
-         clib_time_init (&ldp->clib_time);
-         if (LDP_DEBUG > 0)
-           clib_warning ("LDP<%d>: LDP initialization: done!", getpid ());
+         clib_warning ("LDP<%d>: WARNING: LDP sid bit (%u) specified in the"
+                       " env var " LDP_ENV_SID_BIT " (%s) is too big. Using"
+                       " LDP_SID_BIT_MAX (%d)! sid bit value %d (0x%x)",
+                       getpid (), sb, env_var_str, LDP_SID_BIT_MAX,
+                       ldp->sid_bit_val, ldp->sid_bit_val);
        }
       else
        {
-         fprintf (stderr, "\nLDP<%d>: ERROR: ldp_init: vppcom_app_create()"
-                  " failed!  rv = %d (%s)\n",
-                  getpid (), rv, vppcom_retval_str (rv));
-         ldp->init = 0;
+         ldp->sid_bit_val = (1 << sb);
+         ldp->sid_bit_mask = ldp->sid_bit_val - 1;
+
+         LDBG (0, "LDP<%d>: configured LDP sid bit (%u) from "
+               LDP_ENV_SID_BIT "!  sid bit value %d (0x%x)", getpid (), sb,
+               ldp->sid_bit_val, ldp->sid_bit_val);
        }
     }
-  return rv;
+
+  clib_time_init (&ldp->clib_time);
+  LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ());
+
+  return 0;
 }
 
 int
@@ -248,10 +247,8 @@ close (int fd)
        {
          func_str = "libc_close";
 
-         if (LDP_DEBUG > 0)
-           clib_warning
-             ("LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
-              getpid (), fd, fd, func_str, epfd, epfd);
+         LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): epfd %u (0x%x)",
+               getpid (), fd, fd, func_str, epfd, epfd);
 
          rv = libc_close (epfd);
          if (rv < 0)
@@ -272,9 +269,8 @@ close (int fd)
 
       func_str = "vppcom_session_close";
 
-      if (LDP_DEBUG > 0)
-       clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
-                     getpid (), fd, fd, func_str, sid, sid);
+      LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)",
+           getpid (), fd, fd, func_str, sid, sid);
 
       rv = vppcom_session_close (sid);
       if (rv != VPPCOM_OK)
@@ -287,9 +283,8 @@ close (int fd)
     {
       func_str = "libc_close";
 
-      if (LDP_DEBUG > 0)
-       clib_warning ("LDP<%d>: fd %d (0x%x): calling %s()",
-                     getpid (), fd, fd, func_str);
+      LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s()", getpid (), fd, fd,
+           func_str);
 
       rv = libc_close (fd);
     }
@@ -1151,11 +1146,9 @@ socket (int domain, int type, int protocol)
 
       func_str = "vppcom_session_create";
 
-      if (LDP_DEBUG > 0)
-       clib_warning ("LDP<%d>: : calling %s(): "
-                     "proto %u (%s), is_nonblocking %u",
-                     getpid (), func_str, proto,
-                     vppcom_proto_str (proto), is_nonblocking);
+      LDBG (0, "LDP<%d>: : calling %s(): proto %u (%s), is_nonblocking %u",
+           getpid (), func_str, proto, vppcom_proto_str (proto),
+           is_nonblocking);
 
       sid = vppcom_session_create (proto, is_nonblocking);
       if (sid < 0)
@@ -1179,8 +1172,7 @@ socket (int domain, int type, int protocol)
     {
       func_str = "libc_socket";
 
-      if (LDP_DEBUG > 0)
-       clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str);
+      LDBG (0, "LDP<%d>: : calling %s()", getpid (), func_str);
 
       rv = libc_socket (domain, type, protocol);
     }
@@ -2765,10 +2757,8 @@ listen (int fd, int n)
     {
       func_str = "vppcom_session_listen";
 
-      if (LDP_DEBUG > 0)
-       clib_warning
-         ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
-          getpid (), fd, fd, func_str, sid, sid, n);
+      LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), n %d",
+           getpid (), fd, fd, func_str, sid, sid, n);
 
       rv = vppcom_session_listen (sid, n);
       if (rv != VPPCOM_OK)
@@ -2781,9 +2771,8 @@ listen (int fd, int n)
     {
       func_str = "libc_listen";
 
-      if (LDP_DEBUG > 0)
-       clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): n %d",
-                     getpid (), fd, fd, func_str, n);
+      LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): n %d", getpid (), fd,
+           fd, func_str, n);
 
       rv = libc_listen (fd, n);
     }
@@ -2922,11 +2911,8 @@ shutdown (int fd, int how)
 
   if (sid != INVALID_SESSION_ID)
     {
-      func_str = __func__;
-
-      clib_warning ("LDP<%d>: LDP-TBD", getpid ());
-      errno = ENOSYS;
-      rv = -1;
+      func_str = "vppcom_session_close[TODO]";
+      rv = close (fd);
     }
   else
     {
@@ -2966,10 +2952,17 @@ epoll_create1 (int flags)
   if ((errno = -ldp_init ()))
     return -1;
 
+  if (ldp->vcl_needs_real_epoll)
+    {
+      rv = libc_epoll_create1 (flags);
+      ldp->vcl_needs_real_epoll = 0;
+      ldp->vcl_mq_epfd = rv;
+      LDBG (0, "LDP<%d>: created vcl epfd %u", getpid (), rv);
+      return rv;
+    }
   func_str = "vppcom_epoll_create";
 
-  if (LDP_DEBUG > 1)
-    clib_warning ("LDP<%d>: calling %s()", getpid (), func_str);
+  LDBG (1, "LDP<%d>: calling %s()", getpid (), func_str);
 
   rv = vppcom_epoll_create ();
 
@@ -3007,121 +3000,105 @@ epoll_create (int size)
 int
 epoll_ctl (int epfd, int op, int fd, struct epoll_event *event)
 {
-  int rv;
+  u32 vep_idx = ldp_sid_from_fd (epfd), sid;
   const char *func_str;
-  u32 vep_idx = ldp_sid_from_fd (epfd);
+  int rv;
 
   if ((errno = -ldp_init ()))
     return -1;
 
-  if (PREDICT_TRUE (vep_idx != INVALID_SESSION_ID))
+  if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
     {
-      u32 sid = ldp_sid_from_fd (fd);
+      /* The LDP epoll_create1 always creates VCL epfd's.
+       * The app should never have a kernel base epoll fd unless it
+       * was acquired outside of the LD_PRELOAD process context.
+       * In any case, if we get one, punt it to libc_epoll_ctl.
+       */
+      func_str = "libc_epoll_ctl";
 
-      if (LDP_DEBUG > 1)
-       clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), "
-                     "sid %d (0x%x)", getpid (), epfd, epfd,
-                     vep_idx, vep_idx, sid, sid);
+      LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): op %d, fd %d (0x%x),"
+           " event %p", getpid (), epfd, epfd, func_str, op, fd, fd, event);
 
-      if (sid != INVALID_SESSION_ID)
-       {
-         func_str = "vppcom_epoll_ctl";
+      rv = libc_epoll_ctl (epfd, op, fd, event);
+      goto done;
+    }
 
-         if (LDP_DEBUG > 1)
-           clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                         "vep_idx %d (0x%x), op %d, sid %u (0x%x), event %p",
-                         getpid (), epfd, epfd, func_str, vep_idx, vep_idx,
-                         sid, sid, event);
+  sid = ldp_sid_from_fd (fd);
 
-         rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
-         if (rv != VPPCOM_OK)
-           {
-             errno = -rv;
-             rv = -1;
-           }
+  LDBG (0, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x), sid %d (0x%x)",
+       getpid (), epfd, epfd, vep_idx, vep_idx, sid, sid);
+
+  if (sid != INVALID_SESSION_ID)
+    {
+      func_str = "vppcom_epoll_ctl";
+
+      LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
+           " op %d, sid %u (0x%x), event %p", getpid (), epfd, epfd,
+           func_str, vep_idx, vep_idx, sid, sid, event);
+
+      rv = vppcom_epoll_ctl (vep_idx, op, sid, event);
+      if (rv != VPPCOM_OK)
+       {
+         errno = -rv;
+         rv = -1;
        }
-      else
+    }
+  else
+    {
+      int libc_epfd;
+      u32 size = sizeof (epfd);
+
+      func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
+      libc_epfd = vppcom_session_attr (vep_idx, VPPCOM_ATTR_GET_LIBC_EPFD, 0,
+                                      0);
+      LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): %s() "
+           "returned libc_epfd %d (0x%x)", getpid (), epfd, epfd,
+           vep_idx, vep_idx, func_str, libc_epfd, libc_epfd);
+
+      if (!libc_epfd)
        {
-         int libc_epfd;
-         u32 size = sizeof (epfd);
+         func_str = "libc_epoll_create1";
 
-         func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
-         libc_epfd = vppcom_session_attr (vep_idx,
-                                          VPPCOM_ATTR_GET_LIBC_EPFD, 0, 0);
-         if (LDP_DEBUG > 1)
-           clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
-                         "%s() returned libc_epfd %d (0x%x)",
-                         getpid (), epfd, epfd, vep_idx, vep_idx,
-                         func_str, libc_epfd, libc_epfd);
+         LDBG (1, "LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
+               "calling %s(): EPOLL_CLOEXEC", getpid (), epfd, epfd,
+               vep_idx, vep_idx, func_str);
 
-         if (!libc_epfd)
+         libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
+         if (libc_epfd < 0)
            {
-             func_str = "libc_epoll_create1";
-
-             if (LDP_DEBUG > 1)
-               clib_warning ("LDP<%d>: epfd %d (0x%x), vep_idx %d (0x%x): "
-                             "calling %s(): EPOLL_CLOEXEC",
-                             getpid (), epfd, epfd, vep_idx, vep_idx,
-                             func_str);
+             rv = libc_epfd;
+             goto done;
+           }
 
-             libc_epfd = libc_epoll_create1 (EPOLL_CLOEXEC);
-             if (libc_epfd < 0)
-               {
-                 rv = libc_epfd;
-                 goto done;
-               }
+         func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
+         LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
+               " VPPCOM_ATTR_SET_LIBC_EPFD, libc_epfd %d (0x%x), size %d",
+               getpid (), epfd, epfd, func_str, vep_idx, vep_idx, libc_epfd,
+               libc_epfd, size);
 
-             func_str = "vppcom_session_attr[SET_LIBC_EPFD]";
-             if (LDP_DEBUG > 1)
-               clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                             "vep_idx %d (0x%x), VPPCOM_ATTR_SET_LIBC_EPFD, "
-                             "libc_epfd %d (0x%x), size %d",
-                             getpid (), epfd, epfd, func_str,
-                             vep_idx, vep_idx, libc_epfd, libc_epfd, size);
-
-             rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
-                                       &libc_epfd, &size);
-             if (rv < 0)
-               {
-                 errno = -rv;
-                 rv = -1;
-                 goto done;
-               }
-           }
-         else if (PREDICT_FALSE (libc_epfd < 0))
+         rv = vppcom_session_attr (vep_idx, VPPCOM_ATTR_SET_LIBC_EPFD,
+                                   &libc_epfd, &size);
+         if (rv < 0)
            {
-             errno = -epfd;
+             errno = -rv;
              rv = -1;
              goto done;
            }
-
-         func_str = "libc_epoll_ctl";
-
-         if (LDP_DEBUG > 1)
-           clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                         "libc_epfd %d (0x%x), op %d, "
-                         "fd %d (0x%x), event %p",
-                         getpid (), epfd, epfd, func_str,
-                         libc_epfd, libc_epfd, op, fd, fd, event);
-
-         rv = libc_epoll_ctl (libc_epfd, op, fd, event);
        }
-    }
-  else
-    {
-      /* The LDP epoll_create1 always creates VCL epfd's.
-       * The app should never have a kernel base epoll fd unless it
-       * was acquired outside of the LD_PRELOAD process context.
-       * In any case, if we get one, punt it to libc_epoll_ctl.
-       */
+      else if (PREDICT_FALSE (libc_epfd < 0))
+       {
+         errno = -epfd;
+         rv = -1;
+         goto done;
+       }
+
       func_str = "libc_epoll_ctl";
 
-      if (LDP_DEBUG > 1)
-       clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                     "op %d, fd %d (0x%x), event %p",
-                     getpid (), epfd, epfd, func_str, op, fd, fd, event);
+      LDBG (1, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d (0x%x), "
+           "op %d, fd %d (0x%x), event %p", getpid (), epfd, epfd, func_str,
+           libc_epfd, libc_epfd, op, fd, fd, event);
 
-      rv = libc_epoll_ctl (epfd, op, fd, event);
+      rv = libc_epoll_ctl (libc_epfd, op, fd, event);
     }
 
 done:
@@ -3144,15 +3121,13 @@ done:
 }
 
 static inline int
-ldp_epoll_pwait (int epfd, struct epoll_event *events,
-                int maxevents, int timeout, const sigset_t * sigmask)
+ldp_epoll_pwait (int epfd, struct epoll_event *events, int maxevents,
+                int timeout, const sigset_t * sigmask)
 {
-  const char *func_str;
-  int rv = 0;
-  double time_to_wait = (double) 0;
-  double time_out, now = 0;
+  double time_to_wait = (double) 0, time_out, now = 0;
   u32 vep_idx = ldp_sid_from_fd (epfd);
-  int libc_epfd;
+  int libc_epfd, rv = 0;
+  const char *func_str;
 
   if ((errno = -ldp_init ()))
     return -1;
@@ -3163,6 +3138,9 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events,
       return -1;
     }
 
+  if (epfd == ldp->vcl_mq_epfd)
+    return libc_epoll_pwait (epfd, events, maxevents, timeout, sigmask);
+
   if (PREDICT_FALSE (vep_idx == INVALID_SESSION_ID))
     {
       clib_warning ("LDP<%d>: ERROR: epfd %d (0x%x): bad vep_idx %d (0x%x)!",
@@ -3171,7 +3149,7 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events,
       return -1;
     }
 
-  time_to_wait = ((timeout >= 0) ? (double) timeout / (double) 1000 : 0);
+  time_to_wait = ((timeout >= 0) ? (double) timeout : 0);
   time_out = clib_time_now (&ldp->clib_time) + time_to_wait;
 
   func_str = "vppcom_session_attr[GET_LIBC_EPFD]";
@@ -3183,24 +3161,19 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events,
       goto done;
     }
 
-  if (LDP_DEBUG > 2)
-    clib_warning ("LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), "
-                 "libc_epfd %d (0x%x), events %p, maxevents %d, "
-                 "timeout %d, sigmask %p: time_to_wait %.02f",
-                 getpid (), epfd, epfd, vep_idx, vep_idx,
-                 libc_epfd, libc_epfd, events, maxevents, timeout,
-                 sigmask, time_to_wait, time_out);
+  LDBG (2, "LDP<%d>: epfd %d (0x%x): vep_idx %d (0x%x), libc_epfd %d (0x%x), "
+       "events %p, maxevents %d, timeout %d, sigmask %p: time_to_wait %.02f",
+       getpid (), epfd, epfd, vep_idx, vep_idx, libc_epfd, libc_epfd, events,
+       maxevents, timeout, sigmask, time_to_wait, time_out);
   do
     {
       if (!ldp->epoll_wait_vcl)
        {
          func_str = "vppcom_epoll_wait";
 
-         if (LDP_DEBUG > 3)
-           clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                         "vep_idx %d (0x%x), events %p, maxevents %d",
-                         getpid (), epfd, epfd, func_str,
-                         vep_idx, vep_idx, events, maxevents);
+         LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): vep_idx %d (0x%x),"
+               " events %p, maxevents %d", getpid (), epfd, epfd, func_str,
+               vep_idx, vep_idx, events, maxevents);
 
          rv = vppcom_epoll_wait (vep_idx, events, maxevents, 0);
          if (rv > 0)
@@ -3222,12 +3195,10 @@ ldp_epoll_pwait (int epfd, struct epoll_event *events,
        {
          func_str = "libc_epoll_pwait";
 
-         if (LDP_DEBUG > 3)
-           clib_warning ("LDP<%d>: epfd %d (0x%x): calling %s(): "
-                         "libc_epfd %d (0x%x), events %p, "
-                         "maxevents %d, sigmask %p",
-                         getpid (), epfd, epfd, func_str,
-                         libc_epfd, libc_epfd, events, maxevents, sigmask);
+         LDBG (3, "LDP<%d>: epfd %d (0x%x): calling %s(): libc_epfd %d "
+               "(0x%x), events %p, maxevents %d, sigmask %p", getpid (),
+               epfd, epfd, func_str, libc_epfd, libc_epfd, events,
+               maxevents, sigmask);
 
          rv = libc_epoll_pwait (libc_epfd, events, maxevents, 1, sigmask);
          if (rv != 0)
@@ -3277,65 +3248,61 @@ int
 poll (struct pollfd *fds, nfds_t nfds, int timeout)
 {
   const char *func_str = __func__;
-  int rv, i, n_libc_fds, n_revents;
+  int rv, i, n_revents = 0;
   u32 sid;
   vcl_poll_t *vp;
   double wait_for_time;
 
-  if (LDP_DEBUG > 3)
-    clib_warning ("LDP<%d>: fds %p, nfds %d, timeout %d",
-                 getpid (), fds, nfds, timeout);
+  LDBG (3, "LDP<%d>: fds %p, nfds %d, timeout %d", getpid (), fds, nfds,
+       timeout);
 
   if (timeout >= 0)
     wait_for_time = (f64) timeout / 1000;
   else
     wait_for_time = -1;
 
-  n_libc_fds = 0;
   for (i = 0; i < nfds; i++)
     {
-      if (fds[i].fd >= 0)
-       {
-         if (LDP_DEBUG > 3)
-           clib_warning ("LDP<%d>: fds[%d].fd %d (0x%0x), .events = 0x%x, "
-                         ".revents = 0x%x", getpid (), i, fds[i].fd,
-                         fds[i].fd, fds[i].events, fds[i].revents);
+      if (fds[i].fd < 0)
+       continue;
 
-         sid = ldp_sid_from_fd (fds[i].fd);
-         if (sid != INVALID_SESSION_ID)
-           {
-             fds[i].fd = -fds[i].fd;
-             vec_add2 (ldp->vcl_poll, vp, 1);
-             vp->fds_ndx = i;
-             vp->sid = sid;
-             vp->events = fds[i].events;
+      LDBG (3, "LDP<%d>: fds[%d] fd %d (0x%0x) events = 0x%x revents = 0x%x",
+           getpid (), i, fds[i].fd, fds[i].fd, fds[i].events,
+           fds[i].revents);
+
+      sid = ldp_sid_from_fd (fds[i].fd);
+      if (sid != INVALID_SESSION_ID)
+       {
+         fds[i].fd = -fds[i].fd;
+         vec_add2 (ldp->vcl_poll, vp, 1);
+         vp->fds_ndx = i;
+         vp->sid = sid;
+         vp->events = fds[i].events;
 #ifdef __USE_XOPEN2K
-             if (fds[i].events & POLLRDNORM)
-               vp->events |= POLLIN;
-             if (fds[i].events & POLLWRNORM)
-               vp->events |= POLLOUT;
+         if (fds[i].events & POLLRDNORM)
+           vp->events |= POLLIN;
+         if (fds[i].events & POLLWRNORM)
+           vp->events |= POLLOUT;
 #endif
-             vp->revents = &fds[i].revents;
-           }
-         else
-           n_libc_fds++;
+         vp->revents = fds[i].revents;
+       }
+      else
+       {
+         vec_add1 (ldp->libc_poll, fds[i]);
+         vec_add1 (ldp->libc_poll_idxs, i);
        }
     }
 
-  n_revents = 0;
   do
     {
       if (vec_len (ldp->vcl_poll))
        {
          func_str = "vppcom_poll";
 
-         if (LDP_DEBUG > 3)
-           clib_warning ("LDP<%d>: calling %s(): "
-                         "vcl_poll %p, n_sids %u (0x%x): "
-                         "n_libc_fds %u",
-                         getpid (), func_str, ldp->vcl_poll,
-                         vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll),
-                         n_libc_fds);
+         LDBG (3, "LDP<%d>: calling %s(): vcl_poll %p, n_sids %u (0x%x): "
+               "n_libc_fds %u", getpid (), func_str, ldp->vcl_poll,
+               vec_len (ldp->vcl_poll), vec_len (ldp->vcl_poll),
+               vec_len (ldp->libc_poll));
 
          rv = vppcom_poll (ldp->vcl_poll, vec_len (ldp->vcl_poll), 0);
          if (rv < 0)
@@ -3348,15 +3315,14 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout)
            n_revents += rv;
        }
 
-      if (n_libc_fds)
+      if (vec_len (ldp->libc_poll))
        {
          func_str = "libc_poll";
 
-         if (LDP_DEBUG > 3)
-           clib_warning ("LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
-                         getpid (), fds, nfds, vec_len (ldp->vcl_poll));
+         LDBG (3, "LDP<%d>: calling %s(): fds %p, nfds %u: n_sids %u",
+               getpid (), fds, nfds, vec_len (ldp->vcl_poll));
 
-         rv = libc_poll (fds, nfds, 0);
+         rv = libc_poll (ldp->libc_poll, vec_len (ldp->libc_poll), 0);
          if (rv < 0)
            goto done;
          else
@@ -3377,6 +3343,7 @@ done:
   vec_foreach (vp, ldp->vcl_poll)
   {
     fds[vp->fds_ndx].fd = -fds[vp->fds_ndx].fd;
+    fds[vp->fds_ndx].revents = vp->revents;
 #ifdef __USE_XOPEN2K
     if ((fds[vp->fds_ndx].revents & POLLIN) &&
        (fds[vp->fds_ndx].events & POLLRDNORM))
@@ -3388,6 +3355,13 @@ done:
   }
   vec_reset_length (ldp->vcl_poll);
 
+  for (i = 0; i < vec_len (ldp->libc_poll); i++)
+    {
+      fds[ldp->libc_poll_idxs[i]].revents = ldp->libc_poll[i].revents;
+    }
+  vec_reset_length (ldp->libc_poll_idxs);
+  vec_reset_length (ldp->libc_poll);
+
   if (LDP_DEBUG > 3)
     {
       if (rv < 0)
@@ -3403,7 +3377,7 @@ done:
        {
          clib_warning ("LDP<%d>: returning %d (0x%x): n_sids %u, "
                        "n_libc_fds %d", getpid (), rv, rv,
-                       vec_len (ldp->vcl_poll), n_libc_fds);
+                       vec_len (ldp->vcl_poll), vec_len (ldp->libc_poll));
 
          for (i = 0; i < nfds; i++)
            {