<div dir="ltr"><div><div>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.<br><br></div>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]<br>

</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 29, 2014 at 4:17 PM, Alexandru Ardelean <span dir="ltr"><<a href="mailto:ardeleanalex@gmail.com" target="_blank">ardeleanalex@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Seems that every once in a while libubus takes up the whole CPU<br>
for certain processes.<br>
<br>
This could be bad code that I keep (re)writing.<br>
<br>
I don't know if it's ok to give up after a certain number of<br>
retries; high CPU usage could indicate I should look deeper<br>
at my logic.<br>
<br>
Which is why I've submitted this patch for review/opinions/comments.<br>
<br>
Can also be reviewed here:<br>
<a href="https://github.com/commodo/ubus/commits/max_retry_mechanism" target="_blank">https://github.com/commodo/ubus/commits/max_retry_mechanism</a><br>
<br>
Thanks<br>
<br>
---<br>
 libubus-io.c | 22 ++++++++++++++++------<br>
 1 file changed, 16 insertions(+), 6 deletions(-)<br>
<br>
diff --git a/libubus-io.c b/libubus-io.c<br>
index 31dad27..6bc06aa 100644<br>
--- a/libubus-io.c<br>
+++ b/libubus-io.c<br>
@@ -29,6 +29,7 @@<br>
 #define STATIC_IOV(_var) { .iov_base = (char *) &(_var), .iov_len = sizeof(_var) }<br>
<br>
 #define UBUS_MSGBUF_REDUCTION_INTERVAL 16<br>
+#define UBUS_MAX_RETRIES               256<br>
<br>
 static const struct blob_attr_info ubus_policy[UBUS_ATTR_MAX] = {<br>
        [UBUS_ATTR_STATUS] = { .type = BLOB_ATTR_INT32 },<br>
@@ -75,6 +76,7 @@ static int writev_retry(int fd, struct iovec *iov, int iov_len, int sock_fd)<br>
                .msg_controllen = sizeof(fd_buf),<br>
        };<br>
        int len = 0;<br>
+       int retries = UBUS_MAX_RETRIES;<br>
<br>
        do {<br>
                int cur_len;<br>
@@ -91,9 +93,9 @@ static int writev_retry(int fd, struct iovec *iov, int iov_len, int sock_fd)<br>
                        switch(errno) {<br>
                        case EAGAIN:<br>
                                wait_data(fd, true);<br>
-                               break;<br>
                        case EINTR:<br>
-                               break;<br>
+                               if (retries-- > 0)<br>
+                                       break;<br>
                        default:<br>
                                return -1;<br>
                        }<br>
@@ -115,6 +117,7 @@ static int writev_retry(int fd, struct iovec *iov, int iov_len, int sock_fd)<br>
                iov->iov_len -= cur_len;<br>
                msghdr.msg_iov = iov;<br>
                msghdr.msg_iovlen = iov_len;<br>
+               retries = UBUS_MAX_RETRIES;<br>
        } while (1);<br>
<br>
        /* Should never reach here */<br>
@@ -170,6 +173,7 @@ static int recv_retry(int fd, struct iovec *iov, bool wait, int *recv_fd)<br>
                .msg_iov = iov,<br>
                .msg_iovlen = 1,<br>
        };<br>
+       int retries = UBUS_MAX_RETRIES;<br>
<br>
        while (iov->iov_len > 0) {<br>
                if (wait)<br>
@@ -192,11 +196,16 @@ static int recv_retry(int fd, struct iovec *iov, bool wait, int *recv_fd)<br>
                        bytes = 0;<br>
                        if (uloop_cancelled)<br>
                                return 0;<br>
-                       if (errno == EINTR)<br>
-                               continue;<br>
-<br>
-                       if (errno != EAGAIN)<br>
+                       switch (errno) {<br>
+                       case EINTR:<br>
+                               if (retries-- > 0)<br>
+                                       continue;<br>
+                       case EAGAIN:<br>
+                               if (retries-- > 0)<br>
+                                       break;<br>
+                       default:<br>
                                return -1;<br>
+                       }<br>
                }<br>
                if (!wait && !bytes)<br>
                        return 0;<br>
@@ -210,6 +219,7 @@ static int recv_retry(int fd, struct iovec *iov, bool wait, int *recv_fd)<br>
                iov->iov_len -= bytes;<br>
                iov->iov_base += bytes;<br>
                total += bytes;<br>
+               retries = UBUS_MAX_RETRIES;<br>
        }<br>
<br>
        return total;<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4.5<br>
<br>
</font></span></blockquote></div><br></div>