X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fldp.c;h=dfbb383f04647adc45f167efaaf58882f1f9d6a6;hb=30e273b3055174f0b6fefd240a39fe93253669cd;hp=96a7c36acef66e46dcd37b83b8c8076aa6247d68;hpb=6917b94f2146aa51195a6a2a1ccd8416a1d74bf3;p=vpp.git diff --git a/src/vcl/ldp.c b/src/vcl/ldp.c index 96a7c36acef..dfbb383f046 100644 --- a/src/vcl/ldp.c +++ b/src/vcl/ldp.c @@ -29,6 +29,9 @@ #include #include #include +#include +#include +#include #define HAVE_CONSTRUCTOR_ATTRIBUTE #ifdef HAVE_CONSTRUCTOR_ATTRIBUTE @@ -46,6 +49,13 @@ #define DESTRUCTOR_ATTRIBUTE #endif +typedef struct ldp_fd_entry_ +{ + u32 sid; + u32 fd; + u32 fd_index; +} ldp_fd_entry_t; + typedef struct { int init; @@ -72,7 +82,9 @@ typedef struct u8 vcl_needs_real_epoll; /*< vcl needs next epoll_create to go to libc_epoll */ int vcl_mq_epfd; - + ldp_fd_entry_t *fd_pool; + clib_rwlock_t fd_table_lock; + uword *sid_to_fd_table; } ldp_main_t; #define LDP_DEBUG ldp->debug @@ -110,26 +122,94 @@ ldp_get_app_name () return ldp->app_name; } +static int +ldp_fd_alloc (u32 sid) +{ + ldp_fd_entry_t *fde; + + clib_rwlock_writer_lock (&ldp->fd_table_lock); + if (pool_elts (ldp->fd_pool) >= (1ULL << 32) - ldp->sid_bit_val) + { + clib_rwlock_writer_unlock (&ldp->fd_table_lock); + return -1; + } + pool_get (ldp->fd_pool, fde); + fde->sid = sid; + fde->fd_index = fde - ldp->fd_pool; + fde->fd = fde->fd_index + ldp->sid_bit_val; + hash_set (ldp->sid_to_fd_table, sid, fde->fd); + clib_rwlock_writer_unlock (&ldp->fd_table_lock); + return fde->fd; +} + +static ldp_fd_entry_t * +ldp_fd_entry_get_w_lock (u32 fd_index) +{ + clib_rwlock_reader_lock (&ldp->fd_table_lock); + if (pool_is_free_index (ldp->fd_pool, fd_index)) + return 0; + + return pool_elt_at_index (ldp->fd_pool, fd_index); +} + static inline int ldp_fd_from_sid (u32 sid) { - if (PREDICT_FALSE (sid >= ldp->sid_bit_val)) - return -EMFILE; - else - return (sid | ldp->sid_bit_val); + uword *fdp; + int fd; + + clib_rwlock_reader_lock (&ldp->fd_table_lock); + fdp = hash_get (ldp->sid_to_fd_table, sid); + fd = fdp ? *fdp : -EMFILE; + clib_rwlock_reader_unlock (&ldp->fd_table_lock); + + return fd; } static inline int ldp_fd_is_sid (int fd) { - return ((u32) fd & ldp->sid_bit_val) ? 1 : 0; + return fd >= ldp->sid_bit_val; } static inline u32 ldp_sid_from_fd (int fd) { - return (ldp_fd_is_sid (fd) ? ((u32) fd & ldp->sid_bit_mask) : - INVALID_SESSION_ID); + ldp_fd_entry_t *fde; + u32 fd_index, sid; + + if (!ldp_fd_is_sid (fd)) + return INVALID_SESSION_ID; + + fd_index = fd - ldp->sid_bit_val; + fde = ldp_fd_entry_get_w_lock (fd_index); + sid = fde ? fde->sid : INVALID_SESSION_ID; + clib_rwlock_reader_unlock (&ldp->fd_table_lock); + + /* Handle forks */ + sid = vppcom_session_handle (vppcom_session_index (sid)); + return sid; +} + +static void +ldp_fd_free_w_sid (u32 sid) +{ + ldp_fd_entry_t *fde; + u32 fd_index; + int fd; + + fd = ldp_fd_from_sid (sid); + if (!fd) + return; + + fd_index = fd - ldp->sid_bit_val; + fde = ldp_fd_entry_get_w_lock (fd_index); + if (fde) + { + hash_unset (ldp->sid_to_fd_table, fde->sid); + pool_put (ldp->fd_pool, fde); + } + clib_rwlock_writer_unlock (&ldp->fd_table_lock); } static inline int @@ -222,6 +302,7 @@ ldp_init (void) } clib_time_init (&ldp->clib_time); + clib_rwlock_init (&ldp->fd_table_lock); LDBG (0, "LDP<%d>: LDP initialization: done!", getpid ()); return 0; @@ -272,6 +353,7 @@ close (int fd) LDBG (0, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x)", getpid (), fd, fd, func_str, sid, sid); + ldp_fd_free_w_sid (sid); rv = vppcom_session_close (sid); if (rv != VPPCOM_OK) { @@ -612,36 +694,35 @@ fcntl (int fd, int cmd, ...) { case F_SETFL: func_str = "vppcom_session_attr[SET_FLAGS]"; - if (LDP_DEBUG > 2) - clib_warning ("LDP<%d>: fd %d (0x%x): calling %s(): " - "sid %u (0x%x) flags %d (0x%x), size %d", - getpid (), fd, fd, func_str, sid, sid, - flags, flags, size); + LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x) " + "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, + sid, flags, flags, size); - rv = - vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, &size); + rv = vppcom_session_attr (sid, VPPCOM_ATTR_SET_FLAGS, &flags, + &size); break; case F_GETFL: func_str = "vppcom_session_attr[GET_FLAGS]"; - if (LDP_DEBUG > 2) - clib_warning - ("LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), " - "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, - sid, flags, flags, size); + LDBG (2, "LDP<%d>: fd %d (0x%x): calling %s(): sid %u (0x%x), " + "flags %d (0x%x), size %d", getpid (), fd, fd, func_str, sid, + sid, flags, flags, size); - rv = - vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, &size); + rv = vppcom_session_attr (sid, VPPCOM_ATTR_GET_FLAGS, &flags, + &size); if (rv == VPPCOM_OK) { - if (LDP_DEBUG > 2) - clib_warning ("LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): " - "%s() returned flags %d (0x%x)", - getpid (), fd, fd, cmd, func_str, flags, flags); + LDBG (2, "LDP<%d>: fd %d (0x%x), cmd %d (F_GETFL): %s() " + "returned flags %d (0x%x)", getpid (), fd, fd, cmd, + func_str, flags, flags); rv = flags; } break; - + case F_SETFD: + /* TODO handle this */ + LDBG (0, "F_SETFD ignored flags %u", flags); + rv = 0; + break; default: rv = -EOPNOTSUPP; break; @@ -777,13 +858,11 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, const struct timespec *__restrict timeout, const __sigset_t * __restrict sigmask) { - int rv; + uword sid_bits, sid_bits_set, libc_bits, libc_bits_set; + u32 minbits = clib_max (nfds, BITS (uword)), sid; char *func_str = "##"; f64 time_out; - int fd; - uword sid_bits, sid_bits_set, libc_bits, libc_bits_set; - u32 minbits = clib_max (nfds, BITS (uword)); - u32 sid; + int rv, fd; if (nfds < 0) { @@ -800,9 +879,8 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* select as fine grained sleep */ if (!nfds) { - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: sleeping for %.02f seconds", - getpid (), time_out); + LDBG (3, "LDP<%d>: sleeping for %.02f seconds", getpid (), + time_out); time_out += clib_time_now (&ldp->clib_time); while (clib_time_now (&ldp->clib_time) < time_out) @@ -823,11 +901,9 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, { func_str = "libc_pselect"; - if (LDP_DEBUG > 3) - clib_warning - ("LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, " - "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds, - readfds, writefds, exceptfds, timeout, sigmask); + LDBG (3, "LDP<%d>: calling %s(): nfds %d, readfds %p, writefds %p, " + "exceptfds %p, timeout %p, sigmask %p", getpid (), func_str, nfds, + readfds, writefds, exceptfds, timeout, sigmask); rv = libc_pselect (nfds, readfds, writefds, exceptfds, timeout, sigmask); @@ -845,27 +921,28 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, } sid_bits = libc_bits = 0; + u32 n_bytes = nfds / 8 + ((nfds % 8) ? 1 : 0); if (readfds) { clib_bitmap_validate (ldp->sid_rd_bitmap, minbits); clib_bitmap_validate (ldp->libc_rd_bitmap, minbits); clib_bitmap_validate (ldp->rd_bitmap, minbits); - clib_memcpy (ldp->rd_bitmap, readfds, - vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (readfds); + clib_memcpy_fast (ldp->rd_bitmap, readfds, n_bytes); + memset (readfds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->rd_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_rd_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->rd_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: readfds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_rd_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_rd_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_rd_bitmap) + 1; @@ -874,32 +951,31 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_rd_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: readfds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), sid_bits_set, + sid_bits, libc_bits_set, libc_bits); } if (writefds) { clib_bitmap_validate (ldp->sid_wr_bitmap, minbits); clib_bitmap_validate (ldp->libc_wr_bitmap, minbits); clib_bitmap_validate (ldp->wr_bitmap, minbits); - clib_memcpy (ldp->wr_bitmap, writefds, - vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (writefds); + clib_memcpy_fast (ldp->wr_bitmap, writefds, n_bytes); + memset (writefds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->wr_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_wr_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->wr_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: writefds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_wr_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_wr_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_wr_bitmap) + 1; @@ -908,32 +984,31 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_wr_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: writefds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), + sid_bits_set, sid_bits, libc_bits_set, libc_bits); } if (exceptfds) { clib_bitmap_validate (ldp->sid_ex_bitmap, minbits); clib_bitmap_validate (ldp->libc_ex_bitmap, minbits); clib_bitmap_validate (ldp->ex_bitmap, minbits); - clib_memcpy (ldp->ex_bitmap, exceptfds, - vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t)); - FD_ZERO (exceptfds); + clib_memcpy_fast (ldp->ex_bitmap, exceptfds, n_bytes); + memset (exceptfds, 0, n_bytes); /* *INDENT-OFF* */ - clib_bitmap_foreach (fd, ldp->ex_bitmap, - ({ - sid = ldp_sid_from_fd (fd); - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)", - getpid (), fd, fd, sid, sid); - if (sid == INVALID_SESSION_ID) - clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1); - else - clib_bitmap_set_no_check (ldp->sid_ex_bitmap, sid, 1); - })); + clib_bitmap_foreach (fd, ldp->ex_bitmap, ({ + if (fd > nfds) + break; + sid = ldp_sid_from_fd (fd); + LDBG (3, "LDP<%d>: exceptfds: fd %d (0x%x), sid %u (0x%x)", + getpid (), fd, fd, sid, sid); + if (sid == INVALID_SESSION_ID) + clib_bitmap_set_no_check (ldp->libc_ex_bitmap, fd, 1); + else + clib_bitmap_set_no_check (ldp->sid_ex_bitmap, + vppcom_session_index (sid), 1); + })); /* *INDENT-ON* */ sid_bits_set = clib_bitmap_last_set (ldp->sid_ex_bitmap) + 1; @@ -942,10 +1017,9 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, libc_bits_set = clib_bitmap_last_set (ldp->libc_ex_bitmap) + 1; libc_bits = (libc_bits_set > libc_bits) ? libc_bits_set : libc_bits; - if (LDP_DEBUG > 3) - clib_warning ("LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, " - "libc_bits_set %d, libc_bits %d", getpid (), - sid_bits_set, sid_bits, libc_bits_set, libc_bits); + LDBG (3, "LDP<%d>: exceptfds: sid_bits_set %d, sid_bits %d, " + "libc_bits_set %d, libc_bits %d", getpid (), + sid_bits_set, sid_bits, libc_bits_set, libc_bits); } if (PREDICT_FALSE (!sid_bits && !libc_bits)) @@ -964,17 +1038,17 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, func_str = "vppcom_select"; if (readfds) - clib_memcpy (ldp->rd_bitmap, ldp->sid_rd_bitmap, - vec_len (ldp->rd_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->rd_bitmap, ldp->sid_rd_bitmap, + vec_len (ldp->rd_bitmap) * + sizeof (clib_bitmap_t)); if (writefds) - clib_memcpy (ldp->wr_bitmap, ldp->sid_wr_bitmap, - vec_len (ldp->wr_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->wr_bitmap, ldp->sid_wr_bitmap, + vec_len (ldp->wr_bitmap) * + sizeof (clib_bitmap_t)); if (exceptfds) - clib_memcpy (ldp->ex_bitmap, ldp->sid_ex_bitmap, - vec_len (ldp->ex_bitmap) * - sizeof (clib_bitmap_t)); + clib_memcpy_fast (ldp->ex_bitmap, ldp->sid_ex_bitmap, + vec_len (ldp->ex_bitmap) * + sizeof (clib_bitmap_t)); rv = vppcom_select (sid_bits, readfds ? ldp->rd_bitmap : NULL, @@ -992,7 +1066,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->rd_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1008,7 +1082,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->wr_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1024,7 +1098,7 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, /* *INDENT-OFF* */ clib_bitmap_foreach (sid, ldp->ex_bitmap, ({ - fd = ldp_fd_from_sid (sid); + fd = ldp_fd_from_sid (vppcom_session_handle (sid)); if (PREDICT_FALSE (fd < 0)) { errno = EBADFD; @@ -1049,14 +1123,17 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, func_str = "libc_pselect"; if (readfds) - clib_memcpy (readfds, ldp->libc_rd_bitmap, - vec_len (ldp->rd_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (readfds, ldp->libc_rd_bitmap, + vec_len (ldp->rd_bitmap) * + sizeof (clib_bitmap_t)); if (writefds) - clib_memcpy (writefds, ldp->libc_wr_bitmap, - vec_len (ldp->wr_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (writefds, ldp->libc_wr_bitmap, + vec_len (ldp->wr_bitmap) * + sizeof (clib_bitmap_t)); if (exceptfds) - clib_memcpy (exceptfds, ldp->libc_ex_bitmap, - vec_len (ldp->ex_bitmap) * sizeof (clib_bitmap_t)); + clib_memcpy_fast (exceptfds, ldp->libc_ex_bitmap, + vec_len (ldp->ex_bitmap) * + sizeof (clib_bitmap_t)); tspec.tv_sec = tspec.tv_nsec = 0; rv = libc_pselect (libc_bits, readfds ? readfds : NULL, @@ -1071,15 +1148,15 @@ ldp_pselect (int nfds, fd_set * __restrict readfds, done: /* TBD: set timeout to amount of time left */ - vec_reset_length (ldp->rd_bitmap); - vec_reset_length (ldp->sid_rd_bitmap); - vec_reset_length (ldp->libc_rd_bitmap); - vec_reset_length (ldp->wr_bitmap); - vec_reset_length (ldp->sid_wr_bitmap); - vec_reset_length (ldp->libc_wr_bitmap); - vec_reset_length (ldp->ex_bitmap); - vec_reset_length (ldp->sid_ex_bitmap); - vec_reset_length (ldp->libc_ex_bitmap); + clib_bitmap_zero (ldp->rd_bitmap); + clib_bitmap_zero (ldp->sid_rd_bitmap); + clib_bitmap_zero (ldp->libc_rd_bitmap); + clib_bitmap_zero (ldp->wr_bitmap); + clib_bitmap_zero (ldp->sid_wr_bitmap); + clib_bitmap_zero (ldp->libc_wr_bitmap); + clib_bitmap_zero (ldp->ex_bitmap); + clib_bitmap_zero (ldp->sid_ex_bitmap); + clib_bitmap_zero (ldp->libc_ex_bitmap); if (LDP_DEBUG > 3) { @@ -1159,7 +1236,7 @@ socket (int domain, int type, int protocol) else { func_str = "ldp_fd_from_sid"; - rv = ldp_fd_from_sid (sid); + rv = ldp_fd_alloc (sid); if (rv < 0) { (void) vppcom_session_close (sid); @@ -1224,10 +1301,9 @@ socketpair (int domain, int type, int protocol, int fds[2]) { func_str = "libc_socket"; - if (LDP_DEBUG > 1) - clib_warning ("LDP<%d>: : calling %s()", getpid (), func_str); + LDBG (1, "LDP<%d>: : calling %s()", getpid (), func_str); - rv = libc_socket (domain, type, protocol); + rv = libc_socketpair (domain, type, protocol, fds); } if (LDP_DEBUG > 1) @@ -2845,7 +2921,7 @@ ldp_accept4 (int listen_fd, __SOCKADDR_ARG addr, "accept sid %u (0x%x), ep %p, flags 0x%x", getpid (), listen_fd, listen_fd, func_str, accept_sid, accept_sid, ep, flags); - rv = ldp_fd_from_sid ((u32) accept_sid); + rv = ldp_fd_alloc ((u32) accept_sid); if (rv < 0) { (void) vppcom_session_close ((u32) accept_sid); @@ -2972,7 +3048,7 @@ epoll_create1 (int flags) rv = -1; } else - rv = ldp_fd_from_sid ((u32) rv); + rv = ldp_fd_alloc ((u32) rv); if (LDP_DEBUG > 1) {