Whamcloud - gitweb
b=23701 uninline part of ptlrpc_main to reduce stack usage
[fs/lustre-release.git] / lustre / ptlrpc / service.c
index 3b9faab..b13b82b 100644 (file)
@@ -1477,6 +1477,11 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service *svc)
         svc->srv_n_queued_reqs--;
         /* Consider this still a "queued" request as far as stats are
            concerned */
+        /* ptlrpc_hpreq_init() inserts it to the export list and by the time
+         * of ptlrpc_server_request_add() it could be already handled and
+         * released. To not lose request in between, take an extra reference
+         * on the request. */
+        ptlrpc_request_addref(req);
         cfs_spin_unlock(&svc->srv_lock);
 
         /* go through security check/transform */
@@ -1586,9 +1591,11 @@ ptlrpc_server_handle_req_in(struct ptlrpc_service *svc)
         if (rc)
                 GOTO(err_req, rc);
         cfs_waitq_signal(&svc->srv_waitq);
+        ptlrpc_server_drop_request(req);
         RETURN(1);
 
 err_req:
+        ptlrpc_server_drop_request(req);
         cfs_spin_lock(&svc->srv_rq_lock);
         svc->srv_n_active_reqs++;
         cfs_spin_unlock(&svc->srv_rq_lock);
@@ -2063,6 +2070,33 @@ ptlrpc_server_request_waiting(struct ptlrpc_service *svc)
         return !cfs_list_empty(&svc->srv_req_in_queue);
 }
 
+static __attribute__((__noinline__)) int
+ptlrpc_wait_event(struct ptlrpc_service *svc,
+                  struct ptlrpc_thread *thread)
+{
+        /* Don't exit while there are replies to be handled */
+        struct l_wait_info lwi = LWI_TIMEOUT(svc->srv_rqbd_timeout,
+                                             ptlrpc_retry_rqbds, svc);
+
+        lc_watchdog_disable(thread->t_watchdog);
+
+        cfs_cond_resched();
+
+        l_wait_event_exclusive_head(svc->srv_waitq,
+                               ptlrpc_thread_stopping(thread) ||
+                               ptlrpc_server_request_waiting(svc) ||
+                               ptlrpc_server_request_pending(svc, 0) ||
+                               ptlrpc_rqbd_pending(svc) ||
+                               ptlrpc_at_check(svc), &lwi);
+
+        if (ptlrpc_thread_stopping(thread))
+                return -EINTR;
+
+        lc_watchdog_touch(thread->t_watchdog, CFS_GET_TIMEOUT(svc));
+
+        return 0;
+}
+
 /**
  * Main thread body for service threads.
  * Waits in a loop waiting for new requests to process to appear.
@@ -2169,26 +2203,9 @@ static int ptlrpc_main(void *arg)
 
         /* XXX maintain a list of all managed devices: insert here */
         while (!ptlrpc_thread_stopping(thread)) {
-                /* Don't exit while there are replies to be handled */
-                struct l_wait_info lwi = LWI_TIMEOUT(svc->srv_rqbd_timeout,
-                                                     ptlrpc_retry_rqbds, svc);
-
-                lc_watchdog_disable(thread->t_watchdog);
-
-                cfs_cond_resched();
-
-                l_wait_event_exclusive_head(svc->srv_waitq,
-                                       ptlrpc_thread_stopping(thread) ||
-                                       ptlrpc_server_request_waiting(svc) ||
-                                       ptlrpc_server_request_pending(svc, 0) ||
-                                       ptlrpc_rqbd_pending(svc) ||
-                                       ptlrpc_at_check(svc), &lwi);
-
-                if (ptlrpc_thread_stopping(thread))
+                if (ptlrpc_wait_event(svc, thread))
                         break;
 
-                lc_watchdog_touch(thread->t_watchdog, CFS_GET_TIMEOUT(svc));
-
                 ptlrpc_check_rqbd_pool(svc);
 
                 if (ptlrpc_threads_need_create(svc)) {