epoll: pull all code between fetch_events and send_event into the loop
[linux-2.6-microblaze.git] / fs / eventpoll.c
index d8eef21..63a7a6e 100644 (file)
@@ -389,19 +389,24 @@ static bool ep_busy_loop_end(void *p, unsigned long start_time)
  *
  * we must do our busy polling with irqs enabled
  */
-static void ep_busy_loop(struct eventpoll *ep, int nonblock)
+static bool ep_busy_loop(struct eventpoll *ep, int nonblock)
 {
        unsigned int napi_id = READ_ONCE(ep->napi_id);
 
-       if ((napi_id >= MIN_NAPI_ID) && net_busy_loop_on())
+       if ((napi_id >= MIN_NAPI_ID) && net_busy_loop_on()) {
                napi_busy_loop(napi_id, nonblock ? NULL : ep_busy_loop_end, ep, false,
                               BUSY_POLL_BUDGET);
-}
-
-static inline void ep_reset_busy_poll_napi_id(struct eventpoll *ep)
-{
-       if (ep->napi_id)
+               if (ep_events_available(ep))
+                       return true;
+               /*
+                * Busy poll timed out.  Drop NAPI ID for now, we can add
+                * it back in when we have moved a socket with a valid NAPI
+                * ID onto the ready list.
+                */
                ep->napi_id = 0;
+               return false;
+       }
+       return false;
 }
 
 /*
@@ -441,12 +446,9 @@ static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
 
 #else
 
-static inline void ep_busy_loop(struct eventpoll *ep, int nonblock)
-{
-}
-
-static inline void ep_reset_busy_poll_napi_id(struct eventpoll *ep)
+static inline bool ep_busy_loop(struct eventpoll *ep, int nonblock)
 {
+       return false;
 }
 
 static inline void ep_set_busy_poll_napi_id(struct epitem *epi)
@@ -1772,22 +1774,14 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
        }
 
 fetch_events:
+       do {
+               eavail = ep_events_available(ep);
+               if (!eavail)
+                       eavail = ep_busy_loop(ep, timed_out);
 
-       if (!ep_events_available(ep))
-               ep_busy_loop(ep, timed_out);
-
-       eavail = ep_events_available(ep);
-       if (eavail)
-               goto send_events;
-
-       /*
-        * Busy poll timed out.  Drop NAPI ID for now, we can add
-        * it back in when we have moved a socket with a valid NAPI
-        * ID onto the ready list.
-        */
-       ep_reset_busy_poll_napi_id(ep);
+               if (eavail)
+                       goto send_events;
 
-       do {
                if (signal_pending(current))
                        return -EINTR;
 
@@ -1836,21 +1830,22 @@ fetch_events:
                 * carefully under lock, below.
                 */
                eavail = 1;
-       } while (0);
 
-       if (!list_empty_careful(&wait.entry)) {
-               write_lock_irq(&ep->lock);
-               /*
-                * If the thread timed out and is not on the wait queue, it
-                * means that the thread was woken up after its timeout expired
-                * before it could reacquire the lock. Thus, when wait.entry is
-                * empty, it needs to harvest events.
-                */
-               if (timed_out)
-                       eavail = list_empty(&wait.entry);
-               __remove_wait_queue(&ep->wq, &wait);
-               write_unlock_irq(&ep->lock);
-       }
+               if (!list_empty_careful(&wait.entry)) {
+                       write_lock_irq(&ep->lock);
+                       /*
+                        * If the thread timed out and is not on the wait queue,
+                        * it means that the thread was woken up after its
+                        * timeout expired before it could reacquire the lock.
+                        * Thus, when wait.entry is empty, it needs to harvest
+                        * events.
+                        */
+                       if (timed_out)
+                               eavail = list_empty(&wait.entry);
+                       __remove_wait_queue(&ep->wq, &wait);
+                       write_unlock_irq(&ep->lock);
+               }
+       } while (0);
 
 send_events:
        /*