/* forward ref */
static int ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt);
static void ptlrpc_hpreq_fini(struct ptlrpc_request *req);
+static void ptlrpc_at_remove_timed(struct ptlrpc_request *req);
static CFS_LIST_HEAD(ptlrpc_all_services);
cfs_spinlock_t ptlrpc_all_services_lock;
if (rc <= 0) {
CERROR("%s: failed to parse CPT array %s: %d\n",
conf->psc_name, cconf->cc_pattern, rc);
+ if (cpts != NULL)
+ OBD_FREE(cpts, sizeof(*cpts) * ncpts);
RETURN(ERR_PTR(rc < 0 ? rc : -EINVAL));
}
ncpts = rc;
return;
if (req->rq_at_linked) {
- struct ptlrpc_at_array *array = &svcpt->scp_at_array;
- __u32 index = req->rq_at_index;
-
cfs_spin_lock(&svcpt->scp_at_lock);
-
- LASSERT(!cfs_list_empty(&req->rq_timed_list));
- cfs_list_del_init(&req->rq_timed_list);
- cfs_spin_lock(&req->rq_lock);
- req->rq_at_linked = 0;
- cfs_spin_unlock(&req->rq_lock);
- array->paa_reqs_count[index]--;
- array->paa_count--;
-
+ /* recheck with lock, in case it's unlinked by
+ * ptlrpc_at_check_timed() */
+ if (likely(req->rq_at_linked))
+ ptlrpc_at_remove_timed(req);
cfs_spin_unlock(&svcpt->scp_at_lock);
- } else {
- LASSERT(cfs_list_empty(&req->rq_timed_list));
}
+ LASSERT(cfs_list_empty(&req->rq_timed_list));
+
/* finalize request */
if (req->rq_export) {
class_export_put(req->rq_export);
cfs_list_del(&req->rq_list);
cfs_list_del_init(&req->rq_history_list);
+ /* Track the highest culled req seq */
+ if (req->rq_history_seq > svcpt->scp_hist_seq_culled)
+ svcpt->scp_hist_seq_culled = req->rq_history_seq;
+
cfs_spin_unlock(&svcpt->scp_lock);
ptlrpc_server_free_request(req);
return 0;
}
+static void
+ptlrpc_at_remove_timed(struct ptlrpc_request *req)
+{
+ struct ptlrpc_at_array *array;
+
+ array = &req->rq_rqbd->rqbd_svcpt->scp_at_array;
+
+ /* NB: must call with hold svcpt::scp_at_lock */
+ LASSERT(!cfs_list_empty(&req->rq_timed_list));
+ cfs_list_del_init(&req->rq_timed_list);
+
+ cfs_spin_lock(&req->rq_lock);
+ req->rq_at_linked = 0;
+ cfs_spin_unlock(&req->rq_lock);
+
+ array->paa_reqs_count[req->rq_at_index]--;
+ array->paa_count--;
+}
+
static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req)
{
struct ptlrpc_service_part *svcpt = req->rq_rqbd->rqbd_svcpt;
cfs_list_for_each_entry_safe(rq, n,
&array->paa_reqs_array[index],
rq_timed_list) {
- if (rq->rq_deadline <= now + at_early_margin) {
- cfs_list_del_init(&rq->rq_timed_list);
- /**
- * ptlrpc_server_drop_request() may drop
- * refcount to 0 already. Let's check this and
- * don't add entry to work_list
- */
- if (likely(cfs_atomic_inc_not_zero(&rq->rq_refcount)))
- cfs_list_add(&rq->rq_timed_list, &work_list);
- counter++;
- array->paa_reqs_count[index]--;
- array->paa_count--;
- cfs_spin_lock(&rq->rq_lock);
- rq->rq_at_linked = 0;
- cfs_spin_unlock(&rq->rq_lock);
- continue;
- }
-
- /* update the earliest deadline */
- if (deadline == -1 || rq->rq_deadline < deadline)
- deadline = rq->rq_deadline;
+ if (rq->rq_deadline > now + at_early_margin) {
+ /* update the earliest deadline */
+ if (deadline == -1 ||
+ rq->rq_deadline < deadline)
+ deadline = rq->rq_deadline;
+ break;
+ }
- break;
+ ptlrpc_at_remove_timed(rq);
+ /**
+ * ptlrpc_server_drop_request() may drop
+ * refcount to 0 already. Let's check this and
+ * don't add entry to work_list
+ */
+ if (likely(cfs_atomic_inc_not_zero(&rq->rq_refcount)))
+ cfs_list_add(&rq->rq_timed_list, &work_list);
+ counter++;
}
if (++index >= array->paa_size)
req->rq_export = class_conn2export(
lustre_msg_get_handle(req->rq_reqmsg));
if (req->rq_export) {
+ class_export_rpc_get(req->rq_export);
rc = ptlrpc_check_req(req);
if (rc == 0) {
rc = sptlrpc_target_export_check(req->rq_export, req);
RETURN(1);
err_req:
+ if (req->rq_export)
+ class_export_rpc_put(req->rq_export);
cfs_spin_lock(&svcpt->scp_req_lock);
svcpt->scp_nreqs_active++;
cfs_spin_unlock(&svcpt->scp_req_lock);
at_get(&svcpt->scp_at_estimate));
}
+ export = request->rq_export;
rc = lu_context_init(&request->rq_session, LCT_SESSION | LCT_NOREF);
if (rc) {
CERROR("Failure to initialize session: %d\n", rc);
request->rq_svc_thread->t_env->le_ses = &request->rq_session;
if (likely(request->rq_export)) {
- if (unlikely(ptlrpc_check_req(request)))
- goto put_conn;
+ if (unlikely(ptlrpc_check_req(request)))
+ goto put_conn;
ptlrpc_update_export_timer(request->rq_export, timediff >> 19);
- export = class_export_rpc_get(request->rq_export);
}
/* Discard requests queued for longer than the deadline.
request->rq_arrival_time.tv_sec),
cfs_time_sub(cfs_time_current_sec(),
request->rq_deadline));
- goto put_rpc_export;
+ goto put_conn;
}
CDEBUG(D_RPCTRACE, "Handling RPC pname:cluuid+ref:pid:xid:nid:opc "
ptlrpc_rqphase_move(request, RQ_PHASE_COMPLETE);
-put_rpc_export:
- if (export != NULL)
- class_export_rpc_put(export);
put_conn:
lu_context_exit(&request->rq_session);
lu_context_fini(&request->rq_session);
}
out_req:
+ if (export != NULL)
+ class_export_rpc_put(export);
ptlrpc_server_finish_request(svcpt, request);
RETURN(1);
cfs_list_del(&req->rq_list);
svcpt->scp_nreqs_active++;
ptlrpc_hpreq_fini(req);
+
+ if (req->rq_export != NULL)
+ class_export_rpc_put(req->rq_export);
ptlrpc_server_finish_request(svcpt, req);
}