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 */
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);
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.
/* 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)) {