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(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)) {
while (!cfs_test_bit(HRT_STOPPING, &t->hrt_flags)) {
- l_cfs_wait_event(t->hrt_wait, hrt_dont_sleep(t, &replies));
+ l_wait_condition(t->hrt_wait, hrt_dont_sleep(t, &replies));
while (!cfs_list_empty(&replies)) {
struct ptlrpc_reply_state *rs;
cfs_complete(&t->hrt_completion);
GOTO(out, rc);
}
- l_cfs_wait_event(t->hrt_wait, cfs_test_bit(HRT_RUNNING, &t->hrt_flags));
+ l_wait_condition(t->hrt_wait, cfs_test_bit(HRT_RUNNING, &t->hrt_flags));
RETURN(0);
out:
return rc;
for (i = 0; i < svc->srv_threads_min; i++) {
rc = ptlrpc_start_thread(svc);
/* We have enough threads, don't start more. b=15759 */
- if (rc == -EMFILE)
+ if (rc == -EMFILE) {
+ rc = 0;
break;
+ }
if (rc) {
CERROR("cannot start %s thread #%d: rc %d\n",
svc->srv_thread_name, i, rc);