X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fservice.c;h=6a68a19b839105fcee64e50e3ff351baee0635b8;hb=301d76a71176c186129231ddd1323bae21100165;hp=acb23bcf047027152abf7d39cf5cbc09e2dbaf6c;hpb=b635a0435d13d8431a8344735322b84cb4613b68;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/service.c b/lustre/ptlrpc/service.c index acb23bc..6a68a19 100644 --- a/lustre/ptlrpc/service.c +++ b/lustre/ptlrpc/service.c @@ -27,7 +27,6 @@ */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. */ #define DEBUG_SUBSYSTEM S_RPC @@ -63,6 +62,8 @@ MODULE_PARM_DESC(at_extra, "How much extra time to give with each early reply"); static int ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt); static void ptlrpc_server_hpreq_fini(struct ptlrpc_request *req); static void ptlrpc_at_remove_timed(struct ptlrpc_request *req); +static int ptlrpc_start_threads(struct ptlrpc_service *svc); +static int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait); /** Holds a list of all PTLRPC services */ LIST_HEAD(ptlrpc_all_services); @@ -447,9 +448,9 @@ static int ptlrpc_server_post_idle_rqbds(struct ptlrpc_service_part *svcpt) return posted; } - rqbd = list_entry(svcpt->scp_rqbd_idle.next, - struct ptlrpc_request_buffer_desc, - rqbd_list); + rqbd = list_first_entry(&svcpt->scp_rqbd_idle, + struct ptlrpc_request_buffer_desc, + rqbd_list); /* assume we will post successfully */ svcpt->scp_nrqbds_posted++; @@ -948,9 +949,9 @@ void ptlrpc_server_drop_request(struct ptlrpc_request *req) * I expect only about 1 or 2 rqbds need to be recycled here */ while (svcpt->scp_hist_nrqbds > svc->srv_hist_nrqbds_cpt_max) { - rqbd = list_entry(svcpt->scp_hist_rqbds.next, - struct ptlrpc_request_buffer_desc, - rqbd_list); + rqbd = list_first_entry(&svcpt->scp_hist_rqbds, + struct ptlrpc_request_buffer_desc, + rqbd_list); list_del(&rqbd->rqbd_list); svcpt->scp_hist_nrqbds--; @@ -1351,7 +1352,8 @@ static int ptlrpc_at_send_early_reply(struct ptlrpc_request *req) ENTRY; - if (CFS_FAIL_CHECK(OBD_FAIL_TGT_REPLAY_RECONNECT)) { + if (CFS_FAIL_CHECK(OBD_FAIL_TGT_REPLAY_RECONNECT) || + CFS_FAIL_PRECHECK(OBD_FAIL_PTLRPC_ENQ_RESEND)) { /* don't send early reply */ RETURN(1); } @@ -1614,9 +1616,9 @@ static int ptlrpc_at_check_timed(struct ptlrpc_service_part *svcpt) * we took additional refcount so entries can't be deleted from list, no * locking is needed */ - while (!list_empty(&work_list)) { - rq = list_entry(work_list.next, struct ptlrpc_request, - rq_timed_list); + while ((rq = list_first_entry_or_null(&work_list, + struct ptlrpc_request, + rq_timed_list)) != NULL) { list_del_init(&rq->rq_timed_list); if (ptlrpc_at_send_early_reply(rq) == 0) @@ -1642,13 +1644,6 @@ ptlrpc_server_check_resend_in_progress(struct ptlrpc_request *req) return NULL; /* - * bulk request are aborted upon reconnect, don't try to - * find a match - */ - if (req->rq_bulk_write || req->rq_bulk_read) - return NULL; - - /* * This list should not be longer than max_requests in * flights on the client, so it is not all that long. * Also we only hit this codepath in case of a resent @@ -1857,6 +1852,7 @@ static int ptlrpc_server_request_add(struct ptlrpc_service_part *svcpt, ptlrpc_at_remove_timed(orig); spin_unlock(&orig->rq_rqbd->rqbd_svcpt->scp_at_lock); orig->rq_deadline = req->rq_deadline; + orig->rq_rep_mbits = req->rq_rep_mbits; if (likely(linked)) ptlrpc_at_add_timed(orig); ptlrpc_server_drop_request(orig); @@ -2050,6 +2046,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, struct ptlrpc_service *svc = svcpt->scp_service; struct ptlrpc_request *req; __u32 deadline; + __u32 opc; int rc; ENTRY; @@ -2060,8 +2057,8 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, RETURN(0); } - req = list_entry(svcpt->scp_req_incoming.next, - struct ptlrpc_request, rq_list); + req = list_first_entry(&svcpt->scp_req_incoming, + struct ptlrpc_request, rq_list); list_del_init(&req->rq_list); svcpt->scp_nreqs_incoming--; /* @@ -2106,8 +2103,9 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, goto err_req; } + opc = lustre_msg_get_opc(req->rq_reqmsg); if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_DROP_REQ_OPC) && - lustre_msg_get_opc(req->rq_reqmsg) == cfs_fail_val) { + opc == cfs_fail_val) { CERROR("drop incoming rpc opc %u, x%llu\n", cfs_fail_val, req->rq_xid); goto err_req; @@ -2121,7 +2119,7 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, goto err_req; } - switch (lustre_msg_get_opc(req->rq_reqmsg)) { + switch (opc) { case MDS_WRITEPAGE: case OST_WRITE: case OUT_UPDATE: @@ -2192,8 +2190,20 @@ static int ptlrpc_server_handle_req_in(struct ptlrpc_service_part *svcpt, thread->t_env->le_ses = &req->rq_session; } + + if (unlikely(OBD_FAIL_PRECHECK(OBD_FAIL_PTLRPC_ENQ_RESEND) && + (opc == LDLM_ENQUEUE) && + (lustre_msg_get_flags(req->rq_reqmsg) & MSG_RESENT))) + OBD_FAIL_TIMEOUT(OBD_FAIL_PTLRPC_ENQ_RESEND, 6); + ptlrpc_at_add_timed(req); + if (opc != OST_CONNECT && opc != MDS_CONNECT && + opc != MGS_CONNECT && req->rq_export != NULL) { + if (exp_connect_flags2(req->rq_export) & OBD_CONNECT2_REP_MBITS) + req->rq_rep_mbits = lustre_msg_get_mbits(req->rq_reqmsg); + } + /* Move it over to the request processing queue */ rc = ptlrpc_server_request_add(svcpt, req); if (rc) @@ -3011,7 +3021,7 @@ static void ptlrpc_stop_hr_threads(void) if (hrp->hrp_thrs == NULL) continue; /* uninitialized */ for (j = 0; j < hrp->hrp_nthrs; j++) - wake_up_all(&hrp->hrp_thrs[j].hrt_waitq); + wake_up(&hrp->hrp_thrs[j].hrt_waitq); } cfs_percpt_for_each(hrp, i, ptlrpc_hr.hr_partitions) { @@ -3080,9 +3090,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) wake_up_all(&svcpt->scp_waitq); - while (!list_empty(&svcpt->scp_threads)) { - thread = list_entry(svcpt->scp_threads.next, - struct ptlrpc_thread, t_link); + while ((thread = list_first_entry_or_null(&svcpt->scp_threads, + struct ptlrpc_thread, + t_link)) != NULL) { if (thread_is_stopped(thread)) { list_move(&thread->t_link, &zombie); continue; @@ -3099,9 +3109,9 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) spin_unlock(&svcpt->scp_lock); - while (!list_empty(&zombie)) { - thread = list_entry(zombie.next, - struct ptlrpc_thread, t_link); + while ((thread = list_first_entry_or_null(&zombie, + struct ptlrpc_thread, + t_link)) != NULL) { list_del(&thread->t_link); OBD_FREE_PTR(thread); } @@ -3111,7 +3121,7 @@ static void ptlrpc_svcpt_stop_threads(struct ptlrpc_service_part *svcpt) /** * Stops all threads of a particular service \a svc */ -void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) +static void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) { struct ptlrpc_service_part *svcpt; int i; @@ -3126,7 +3136,7 @@ void ptlrpc_stop_all_threads(struct ptlrpc_service *svc) EXIT; } -int ptlrpc_start_threads(struct ptlrpc_service *svc) +static int ptlrpc_start_threads(struct ptlrpc_service *svc) { int rc = 0; int i; @@ -3158,7 +3168,7 @@ int ptlrpc_start_threads(struct ptlrpc_service *svc) RETURN(rc); } -int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) +static int ptlrpc_start_thread(struct ptlrpc_service_part *svcpt, int wait) { struct ptlrpc_thread *thread; struct ptlrpc_service *svc; @@ -3457,9 +3467,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc) break; spin_lock(&svcpt->scp_rep_lock); - while (!list_empty(&svcpt->scp_rep_active)) { - rs = list_entry(svcpt->scp_rep_active.next, - struct ptlrpc_reply_state, rs_list); + while ((rs = list_first_entry_or_null(&svcpt->scp_rep_active, + struct ptlrpc_reply_state, + rs_list)) != NULL) { spin_lock(&rs->rs_lock); ptlrpc_schedule_difficult_reply(rs); spin_unlock(&rs->rs_lock); @@ -3471,10 +3481,9 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc) * all unlinked) and no service threads, so I'm the only * thread noodling the request queue now */ - while (!list_empty(&svcpt->scp_req_incoming)) { - req = list_entry(svcpt->scp_req_incoming.next, - struct ptlrpc_request, rq_list); - + while ((req = list_first_entry_or_null(&svcpt->scp_req_incoming, + struct ptlrpc_request, + rq_list)) != NULL) { list_del(&req->rq_list); svcpt->scp_nreqs_incoming--; ptlrpc_server_finish_request(svcpt, req); @@ -3514,19 +3523,16 @@ ptlrpc_service_purge_all(struct ptlrpc_service *svc) * Now free all the request buffers since nothing * references them any more... */ - - while (!list_empty(&svcpt->scp_rqbd_idle)) { - rqbd = list_entry(svcpt->scp_rqbd_idle.next, - struct ptlrpc_request_buffer_desc, - rqbd_list); + while ((rqbd = list_first_entry_or_null(&svcpt->scp_rqbd_idle, + struct ptlrpc_request_buffer_desc, + rqbd_list)) != NULL) ptlrpc_free_rqbd(rqbd); - } + ptlrpc_wait_replies(svcpt); - while (!list_empty(&svcpt->scp_rep_idle)) { - rs = list_entry(svcpt->scp_rep_idle.next, - struct ptlrpc_reply_state, - rs_list); + while ((rs = list_first_entry_or_null(&svcpt->scp_rep_idle, + struct ptlrpc_reply_state, + rs_list)) != NULL) { list_del(&rs->rs_list); OBD_FREE_LARGE(rs, svc->srv_max_reply_size); }