X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fptlrpc%2Fclient.c;h=ffccc5ef2cd8320c7538dc9456df79f06bc7f914;hb=f625f670afbe954030ff81f0f8522137d6cdd335;hp=0dccb1abff204b90876092279a5b7d2af82e5bef;hpb=cfbfcc6ad9ebb5893be2d1e85fc959794fd914ed;p=fs%2Flustre-release.git diff --git a/lustre/ptlrpc/client.c b/lustre/ptlrpc/client.c index 0dccb1a..ffccc5e 100644 --- a/lustre/ptlrpc/client.c +++ b/lustre/ptlrpc/client.c @@ -27,7 +27,7 @@ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2013, Intel Corporation. + * Copyright (c) 2011, 2014, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -49,6 +49,7 @@ static int ptlrpc_send_new_req(struct ptlrpc_request *req); static int ptlrpcd_check_work(struct ptlrpc_request *req); +static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async); /** * Initialize passed in client structure \a cl. @@ -91,7 +92,6 @@ struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid) return c; } -EXPORT_SYMBOL(ptlrpc_uuid_to_connection); /** * Allocate and initialize new bulk descriptor on the sender. @@ -359,27 +359,29 @@ __must_hold(&req->rq_lock) rc = sptlrpc_cli_unwrap_early_reply(req, &early_req); if (rc) { spin_lock(&req->rq_lock); - RETURN(rc); - } - - rc = unpack_reply(early_req); - if (rc == 0) { - /* Expecting to increase the service time estimate here */ - ptlrpc_at_adj_service(req, - lustre_msg_get_timeout(early_req->rq_repmsg)); - ptlrpc_at_adj_net_latency(req, - lustre_msg_get_service_time(early_req->rq_repmsg)); - } - - sptlrpc_cli_finish_early_reply(early_req); + RETURN(rc); + } + rc = unpack_reply(early_req); if (rc != 0) { + sptlrpc_cli_finish_early_reply(early_req); spin_lock(&req->rq_lock); RETURN(rc); } - /* Adjust the local timeout for this req */ - ptlrpc_at_set_req_timeout(req); + /* Use new timeout value just to adjust the local value for this + * request, don't include it into at_history. It is unclear yet why + * service time increased and should it be counted or skipped, e.g. + * that can be recovery case or some error or server, the real reply + * will add all new data if it is worth to add. */ + req->rq_timeout = lustre_msg_get_timeout(early_req->rq_repmsg); + lustre_msg_set_timeout(req->rq_reqmsg, req->rq_timeout); + + /* Network latency can be adjusted, it is pure network delays */ + ptlrpc_at_adj_net_latency(req, + lustre_msg_get_service_time(early_req->rq_repmsg)); + + sptlrpc_cli_finish_early_reply(early_req); spin_lock(&req->rq_lock); olddl = req->rq_deadline; @@ -399,7 +401,7 @@ __must_hold(&req->rq_lock) RETURN(rc); } -struct kmem_cache *request_cache; +static struct kmem_cache *request_cache; int ptlrpc_request_cache_init(void) { @@ -834,7 +836,6 @@ ptlrpc_prep_req_pool(struct obd_import *imp, } return request; } -EXPORT_SYMBOL(ptlrpc_prep_req_pool); /** * Same as ptlrpc_prep_req_pool, but without pool @@ -846,7 +847,6 @@ ptlrpc_prep_req(struct obd_import *imp, __u32 version, int opcode, int count, return ptlrpc_prep_req_pool(imp, version, opcode, count, lengths, bufs, NULL); } -EXPORT_SYMBOL(ptlrpc_prep_req); /** * Allocate and initialize new request set structure. @@ -901,7 +901,6 @@ struct ptlrpc_request_set *ptlrpc_prep_fcset(int max, set_producer_func func, RETURN(set); } -EXPORT_SYMBOL(ptlrpc_prep_fcset); /** * Wind down and free request set structure previously allocated with @@ -983,7 +982,6 @@ int ptlrpc_set_add_cb(struct ptlrpc_request_set *set, RETURN(0); } -EXPORT_SYMBOL(ptlrpc_set_add_cb); /** * Add a new request to the general purpose request set. @@ -1045,7 +1043,6 @@ void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc, wake_up(&pc->pc_partners[i]->pc_set->set_waitq); } } -EXPORT_SYMBOL(ptlrpc_set_add_new_req); /** * Based on the current state of the import, determine if the request @@ -1116,35 +1113,40 @@ static int ptlrpc_import_delay_req(struct obd_import *imp, } /** - * Decide if the eror message regarding provided request \a req - * should be printed to the console or not. - * Makes it's decision on request status and other properties. - * Returns 1 to print error on the system console or 0 if not. + * Decide if the error message should be printed to the console or not. + * Makes its decision based on request type, status, and failure frequency. + * + * \param[in] req request that failed and may need a console message + * + * \retval false if no message should be printed + * \retval true if console message should be printed */ -static int ptlrpc_console_allow(struct ptlrpc_request *req) +static bool ptlrpc_console_allow(struct ptlrpc_request *req) { - __u32 opc; - int err; + __u32 opc; - LASSERT(req->rq_reqmsg != NULL); - opc = lustre_msg_get_opc(req->rq_reqmsg); + LASSERT(req->rq_reqmsg != NULL); + opc = lustre_msg_get_opc(req->rq_reqmsg); - /* Suppress particular reconnect errors which are to be expected. No - * errors are suppressed for the initial connection on an import */ - if ((lustre_handle_is_used(&req->rq_import->imp_remote_handle)) && - (opc == OST_CONNECT || opc == MDS_CONNECT || opc == MGS_CONNECT)) { + /* Suppress particular reconnect errors which are to be expected. */ + if (opc == OST_CONNECT || opc == MDS_CONNECT || opc == MGS_CONNECT) { + int err; - /* Suppress timed out reconnect requests */ - if (req->rq_timedout) - return 0; + /* Suppress timed out reconnect requests */ + if (lustre_handle_is_used(&req->rq_import->imp_remote_handle) || + req->rq_timedout) + return false; - /* Suppress unavailable/again reconnect requests */ - err = lustre_msg_get_status(req->rq_repmsg); - if (err == -ENODEV || err == -EAGAIN) - return 0; - } + /* Suppress most unavailable/again reconnect requests, but + * print occasionally so it is clear client is trying to + * connect to a server where no target is running. */ + err = lustre_msg_get_status(req->rq_repmsg); + if ((err == -ENODEV || err == -EAGAIN) && + req->rq_import->imp_conn_cnt % 30 != 20) + return false; + } - return 1; + return true; } /** @@ -1159,14 +1161,15 @@ static int ptlrpc_check_status(struct ptlrpc_request *req) err = lustre_msg_get_status(req->rq_repmsg); if (lustre_msg_get_type(req->rq_repmsg) == PTL_RPC_MSG_ERR) { struct obd_import *imp = req->rq_import; + lnet_nid_t nid = imp->imp_connection->c_peer.nid; __u32 opc = lustre_msg_get_opc(req->rq_reqmsg); + if (ptlrpc_console_allow(req)) - LCONSOLE_ERROR_MSG(0x011, "%s: Communicating with %s," - " operation %s failed with %d.\n", - imp->imp_obd->obd_name, - libcfs_nid2str( - imp->imp_connection->c_peer.nid), - ll_opcode2str(opc), err); + LCONSOLE_ERROR_MSG(0x11, "%s: operation %s to node %s " + "failed: rc = %d\n", + imp->imp_obd->obd_name, + ll_opcode2str(opc), + libcfs_nid2str(nid), err); RETURN(err < 0 ? err : -EINVAL); } @@ -1221,9 +1224,9 @@ static int after_reply(struct ptlrpc_request *req) LASSERT(obd != NULL); /* repbuf must be unlinked */ - LASSERT(!req->rq_receiving_reply && !req->rq_reply_unlink); + LASSERT(!req->rq_receiving_reply && req->rq_reply_unlinked); - if (req->rq_reply_truncate) { + if (req->rq_reply_truncated) { if (ptlrpc_no_resend(req)) { DEBUG_REQ(D_ERROR, req, "reply buffer overflow," " expected: %d, actual size: %d", @@ -1322,20 +1325,20 @@ static int after_reply(struct ptlrpc_request *req) rc = ptlrpc_check_status(req); imp->imp_connect_error = rc; - if (rc) { - /* - * Either we've been evicted, or the server has failed for - * some reason. Try to reconnect, and if that fails, punt to - * the upcall. - */ - if (ll_rpc_recoverable_error(rc)) { - if (req->rq_send_state != LUSTRE_IMP_FULL || - imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) { - RETURN(rc); - } - ptlrpc_request_handle_notconn(req); - RETURN(rc); - } + if (rc) { + /* + * Either we've been evicted, or the server has failed for + * some reason. Try to reconnect, and if that fails, punt to + * the upcall. + */ + if (ptlrpc_recoverable_error(rc)) { + if (req->rq_send_state != LUSTRE_IMP_FULL || + imp->imp_obd->obd_no_recov || imp->imp_dlm_fake) { + RETURN(rc); + } + ptlrpc_request_handle_notconn(req); + RETURN(rc); + } } else { /* * Let's look if server sent slv. Do it only for RPC with @@ -1650,7 +1653,7 @@ int ptlrpc_check_set(const struct lu_env *env, struct ptlrpc_request_set *set) /* ptlrpc_set_wait->l_wait_event sets lwi_allow_intr * so it sets rq_intr regardless of individual rpc - * timeouts. The synchronous IO waiting path sets + * timeouts. The synchronous IO waiting path sets * rq_intr irrespective of whether ptlrpcd * has seen a timeout. Our policy is to only interpret * interrupted rpcs after they have timed out, so we @@ -2030,7 +2033,6 @@ int ptlrpc_expired_set(void *data) */ RETURN(1); } -EXPORT_SYMBOL(ptlrpc_expired_set); /** * Sets rq_intr flag in \a req under spinlock. @@ -2047,7 +2049,7 @@ EXPORT_SYMBOL(ptlrpc_mark_interrupted); * Interrupts (sets interrupted flag) all uncompleted requests in * a set \a data. Callback for l_wait_event for interruptible waits. */ -void ptlrpc_interrupted_set(void *data) +static void ptlrpc_interrupted_set(void *data) { struct ptlrpc_request_set *set = data; struct list_head *tmp; @@ -2066,7 +2068,6 @@ void ptlrpc_interrupted_set(void *data) ptlrpc_mark_interrupted(req); } } -EXPORT_SYMBOL(ptlrpc_interrupted_set); /** * Get the smallest timeout in the set; this does NOT set a timeout. @@ -2117,7 +2118,6 @@ int ptlrpc_set_next_timeout(struct ptlrpc_request_set *set) } RETURN(timeout); } -EXPORT_SYMBOL(ptlrpc_set_next_timeout); /** * Send all unset request from the set and then wait untill all @@ -2161,14 +2161,14 @@ int ptlrpc_set_wait(struct ptlrpc_request_set *set) * We still want to block for a limited time, * so we allow interrupts during the timeout. */ - lwi = LWI_TIMEOUT_INTR_ALL(cfs_time_seconds(1), + lwi = LWI_TIMEOUT_INTR_ALL(cfs_time_seconds(1), ptlrpc_expired_set, ptlrpc_interrupted_set, set); else /* * At least one request is in flight, so no * interrupts are allowed. Wait until all - * complete, or an in-flight req times out. + * complete, or an in-flight req times out. */ lwi = LWI_TIMEOUT(cfs_time_seconds(timeout? timeout : 1), ptlrpc_expired_set, set); @@ -2312,14 +2312,13 @@ static void __ptlrpc_free_req(struct ptlrpc_request *request, int locked) static int __ptlrpc_req_finished(struct ptlrpc_request *request, int locked); /** * Drop one request reference. Must be called with import imp_lock held. - * When reference count drops to zero, reuqest is freed. + * When reference count drops to zero, request is freed. */ void ptlrpc_req_finished_with_imp_lock(struct ptlrpc_request *request) { assert_spin_locked(&request->rq_import->imp_lock); (void)__ptlrpc_req_finished(request, 1); } -EXPORT_SYMBOL(ptlrpc_req_finished_with_imp_lock); /** * Helper function @@ -2376,7 +2375,7 @@ EXPORT_SYMBOL(ptlrpc_req_xid); * The request owner (i.e. the thread doing the I/O) must call... * Returns 0 on success or 1 if unregistering cannot be made. */ -int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) +static int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) { int rc; struct l_wait_info lwi; @@ -2440,13 +2439,14 @@ int ptlrpc_unregister_reply(struct ptlrpc_request *request, int async) } LASSERT(rc == -ETIMEDOUT); - DEBUG_REQ(D_WARNING, request, "Unexpectedly long timeout " - "rvcng=%d unlnk=%d/%d", request->rq_receiving_reply, - request->rq_req_unlink, request->rq_reply_unlink); + DEBUG_REQ(D_WARNING, request, "Unexpectedly long timeout " + "receiving_reply=%d req_ulinked=%d reply_unlinked=%d", + request->rq_receiving_reply, + request->rq_req_unlinked, + request->rq_reply_unlinked); } RETURN(0); } -EXPORT_SYMBOL(ptlrpc_unregister_reply); static void ptlrpc_free_request(struct ptlrpc_request *req) { @@ -2573,7 +2573,6 @@ void ptlrpc_cleanup_client(struct obd_import *imp) ENTRY; EXIT; } -EXPORT_SYMBOL(ptlrpc_cleanup_client); /** * Schedule previously sent request for resend. @@ -2611,7 +2610,6 @@ void ptlrpc_resend_req(struct ptlrpc_request *req) ptlrpc_client_wake_req(req); spin_unlock(&req->rq_lock); } -EXPORT_SYMBOL(ptlrpc_resend_req); /* XXX: this function and rq_status are currently unused */ void ptlrpc_restart_req(struct ptlrpc_request *req) @@ -2625,7 +2623,6 @@ void ptlrpc_restart_req(struct ptlrpc_request *req) ptlrpc_client_wake_req(req); spin_unlock(&req->rq_lock); } -EXPORT_SYMBOL(ptlrpc_restart_req); /** * Grab additional reference on a request \a req @@ -2693,7 +2690,6 @@ void ptlrpc_retain_replayable_request(struct ptlrpc_request *req, list_add(&req->rq_replay_list, &imp->imp_replay_list); } -EXPORT_SYMBOL(ptlrpc_retain_replayable_request); /** * Send request and wait until it completes. @@ -2729,7 +2725,7 @@ EXPORT_SYMBOL(ptlrpc_queue_wait); /** * Callback used for replayed requests reply processing. - * In case of succesful reply calls registeresd request replay callback. + * In case of successful reply calls registered request replay callback. * In case of error restart replay process. */ static int ptlrpc_replay_interpret(const struct lu_env *env, @@ -2863,7 +2859,6 @@ int ptlrpc_replay_req(struct ptlrpc_request *req) ptlrpcd_add_req(req, PDL_POLICY_LOCAL, -1); RETURN(0); } -EXPORT_SYMBOL(ptlrpc_replay_req); /** * Aborts all in-flight request on import \a imp sending and delayed lists @@ -2923,7 +2918,6 @@ void ptlrpc_abort_inflight(struct obd_import *imp) EXIT; } -EXPORT_SYMBOL(ptlrpc_abort_inflight); /** * Abort all uncompleted requests in request set \a set @@ -3012,7 +3006,6 @@ __u64 ptlrpc_next_xid(void) return next; } -EXPORT_SYMBOL(ptlrpc_next_xid); /** * Get a glimpse at what next xid value might have been. @@ -3129,8 +3122,6 @@ void *ptlrpcd_alloc_work(struct obd_import *imp, req->rq_import = class_import_get(imp); req->rq_interpret_reply = work_interpreter; /* don't want reply */ - req->rq_receiving_reply = 0; - req->rq_req_unlink = req->rq_reply_unlink = 0; req->rq_no_delay = req->rq_no_resend = 1; req->rq_pill.rc_fmt = (void *)&worker_format;