[OpenWrt-Devel] [PATCH][RFC] libubus: added max retry mechanism

Alexandru Ardelean ardeleanalex at gmail.com
Tue Jul 29 09:23:49 EDT 2014


Quick info follow-up:  strace-ing on the PIDs (with high CPU usage) shows a
lot of EAGAIN errors from recvfrom() and a lot of recvfrom() + poll() +
clock_gettime_monotonic() calls.

Thinking about it, would it make more sense to add a short wait instead [to
reduce the throttle] and let it "infinitely" loop ?  ["infinitely" loop ==
loop until it does not error with EAGAIN]


On Tue, Jul 29, 2014 at 4:17 PM, Alexandru Ardelean <ardeleanalex at gmail.com>
wrote:

> Seems that every once in a while libubus takes up the whole CPU
> for certain processes.
>
> This could be bad code that I keep (re)writing.
>
> I don't know if it's ok to give up after a certain number of
> retries; high CPU usage could indicate I should look deeper
> at my logic.
>
> Which is why I've submitted this patch for review/opinions/comments.
>
> Can also be reviewed here:
> https://github.com/commodo/ubus/commits/max_retry_mechanism
>
> Thanks
>
> ---
>  libubus-io.c | 22 ++++++++++++++++------
>  1 file changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/libubus-io.c b/libubus-io.c
> index 31dad27..6bc06aa 100644
> --- a/libubus-io.c
> +++ b/libubus-io.c
> @@ -29,6 +29,7 @@
>  #define STATIC_IOV(_var) { .iov_base = (char *) &(_var), .iov_len =
> sizeof(_var) }
>
>  #define UBUS_MSGBUF_REDUCTION_INTERVAL 16
> +#define UBUS_MAX_RETRIES               256
>
>  static const struct blob_attr_info ubus_policy[UBUS_ATTR_MAX] = {
>         [UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },
> @@ -75,6 +76,7 @@ static int writev_retry(int fd, struct iovec *iov, int
> iov_len, int sock_fd)
>                 .msg_controllen = sizeof(fd_buf),
>         };
>         int len = 0;
> +       int retries = UBUS_MAX_RETRIES;
>
>         do {
>                 int cur_len;
> @@ -91,9 +93,9 @@ static int writev_retry(int fd, struct iovec *iov, int
> iov_len, int sock_fd)
>                         switch(errno) {
>                         case EAGAIN:
>                                 wait_data(fd, true);
> -                               break;
>                         case EINTR:
> -                               break;
> +                               if (retries-- > 0)
> +                                       break;
>                         default:
>                                 return -1;
>                         }
> @@ -115,6 +117,7 @@ static int writev_retry(int fd, struct iovec *iov, int
> iov_len, int sock_fd)
>                 iov->iov_len -= cur_len;
>                 msghdr.msg_iov = iov;
>                 msghdr.msg_iovlen = iov_len;
> +               retries = UBUS_MAX_RETRIES;
>         } while (1);
>
>         /* Should never reach here */
> @@ -170,6 +173,7 @@ static int recv_retry(int fd, struct iovec *iov, bool
> wait, int *recv_fd)
>                 .msg_iov = iov,
>                 .msg_iovlen = 1,
>         };
> +       int retries = UBUS_MAX_RETRIES;
>
>         while (iov->iov_len > 0) {
>                 if (wait)
> @@ -192,11 +196,16 @@ static int recv_retry(int fd, struct iovec *iov,
> bool wait, int *recv_fd)
>                         bytes = 0;
>                         if (uloop_cancelled)
>                                 return 0;
> -                       if (errno == EINTR)
> -                               continue;
> -
> -                       if (errno != EAGAIN)
> +                       switch (errno) {
> +                       case EINTR:
> +                               if (retries-- > 0)
> +                                       continue;
> +                       case EAGAIN:
> +                               if (retries-- > 0)
> +                                       break;
> +                       default:
>                                 return -1;
> +                       }
>                 }
>                 if (!wait && !bytes)
>                         return 0;
> @@ -210,6 +219,7 @@ static int recv_retry(int fd, struct iovec *iov, bool
> wait, int *recv_fd)
>                 iov->iov_len -= bytes;
>                 iov->iov_base += bytes;
>                 total += bytes;
> +               retries = UBUS_MAX_RETRIES;
>         }
>
>         return total;
> --
> 1.8.4.5
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.infradead.org/pipermail/openwrt-devel/attachments/20140729/14be5321/attachment.htm>
-------------- next part --------------
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


More information about the openwrt-devel mailing list