1d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
2d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER START
3d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
4d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
6d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is free software; you can redistribute it and/or modify
7d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * it under the terms of the GNU General Public License version 2 only,
8d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * as published by the Free Software Foundation.
9d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
10d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This program is distributed in the hope that it will be useful, but
11d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * WITHOUT ANY WARRANTY; without even the implied warranty of
12d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * General Public License version 2 for more details (a copy is included
14d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * in the LICENSE file that accompanied this code).
15d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
16d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * You should have received a copy of the GNU General Public License
17d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * version 2 along with this program; If not, see
18d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
20d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CA 95054 USA or visit www.sun.com if you need additional information or
22d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * have any questions.
23d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
24d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * GPL HEADER END
25d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
26d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
27d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
28d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Use is subject to license terms.
29d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
30d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Copyright (c) 2011, 2012, Intel Corporation.
31d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
32d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
33d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * This file is part of Lustre, http://www.lustre.org/
34d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Lustre is a trademark of Sun Microsystems, Inc.
35d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
36d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define DEBUG_SUBSYSTEM S_CLASS
37d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
38d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
39e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd_support.h"
40e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd.h"
41e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/lprocfs_status.h"
42e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/lustre/lustre_idl.h"
43e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/lustre_net.h"
44e27db14919269176ec040479d199225a37aafb8cGreg Kroah-Hartman#include "../include/obd_class.h"
45d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#include "ptlrpc_internal.h"
46d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
47d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
48d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ll_rpc_opcode {
492a763282df786aa8470a1e52c653dc3dcc574ed7Kristina Martsenko	__u32       opcode;
502a763282df786aa8470a1e52c653dc3dcc574ed7Kristina Martsenko	const char *opname;
51d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} ll_rpc_opcode_table[LUSTRE_MAX_OPCODES] = {
52d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_REPLY,	"ost_reply" },
53d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_GETATTR,      "ost_getattr" },
54d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_SETATTR,      "ost_setattr" },
55d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_READ,	 "ost_read" },
56d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_WRITE,	"ost_write" },
57d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_CREATE ,      "ost_create" },
58d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_DESTROY,      "ost_destroy" },
59d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_GET_INFO,     "ost_get_info" },
60d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_CONNECT,      "ost_connect" },
61d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_DISCONNECT,   "ost_disconnect" },
62d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_PUNCH,	"ost_punch" },
63d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_OPEN,	 "ost_open" },
64d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_CLOSE,	"ost_close" },
65d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_STATFS,       "ost_statfs" },
66d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ 14,		NULL },    /* formerly OST_SAN_READ */
67d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ 15,		NULL },    /* formerly OST_SAN_WRITE */
68d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_SYNC,	 "ost_sync" },
69d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_SET_INFO,     "ost_set_info" },
70d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_QUOTACHECK,   "ost_quotacheck" },
71d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_QUOTACTL,     "ost_quotactl" },
72d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OST_QUOTA_ADJUST_QUNIT, "ost_quota_adjust_qunit" },
73d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_GETATTR,      "mds_getattr" },
74d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_GETATTR_NAME, "mds_getattr_lock" },
75d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_CLOSE,	"mds_close" },
76d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT,	"mds_reint" },
77d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_READPAGE,     "mds_readpage" },
78d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_CONNECT,      "mds_connect" },
79d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_DISCONNECT,   "mds_disconnect" },
80d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_GETSTATUS,    "mds_getstatus" },
81d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_STATFS,       "mds_statfs" },
82d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_PIN,	  "mds_pin" },
83d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_UNPIN,	"mds_unpin" },
84d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_SYNC,	 "mds_sync" },
85d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_DONE_WRITING, "mds_done_writing" },
86d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_SET_INFO,     "mds_set_info" },
87d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_QUOTACHECK,   "mds_quotacheck" },
88d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_QUOTACTL,     "mds_quotactl" },
89d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_GETXATTR,     "mds_getxattr" },
90d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_SETXATTR,     "mds_setxattr" },
91d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_WRITEPAGE,    "mds_writepage" },
92d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_IS_SUBDIR,    "mds_is_subdir" },
93d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_GET_INFO,     "mds_get_info" },
94d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_STATE_GET, "mds_hsm_state_get" },
95d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_STATE_SET, "mds_hsm_state_set" },
96d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_ACTION,   "mds_hsm_action" },
97d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_PROGRESS, "mds_hsm_progress" },
98d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_REQUEST,  "mds_hsm_request" },
99d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_CT_REGISTER, "mds_hsm_ct_register" },
100d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_HSM_CT_UNREGISTER, "mds_hsm_ct_unregister" },
101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_SWAP_LAYOUTS,	"mds_swap_layouts" },
102d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_ENQUEUE,     "ldlm_enqueue" },
103d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_CONVERT,     "ldlm_convert" },
104d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_CANCEL,      "ldlm_cancel" },
105d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_BL_CALLBACK, "ldlm_bl_callback" },
106d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_CP_CALLBACK, "ldlm_cp_callback" },
107d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_GL_CALLBACK, "ldlm_gl_callback" },
108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_SET_INFO,    "ldlm_set_info" },
109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_CONNECT,      "mgs_connect" },
110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_DISCONNECT,   "mgs_disconnect" },
111d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_EXCEPTION,    "mgs_exception" },
112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_TARGET_REG,   "mgs_target_reg" },
113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_TARGET_DEL,   "mgs_target_del" },
114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_SET_INFO,     "mgs_set_info" },
115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MGS_CONFIG_READ,  "mgs_config_read" },
116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OBD_PING,	 "obd_ping" },
11765f1c7816db85db02b2069f9d0e5111de52f5ee3Mikhail Pershin	{ OBD_LOG_CANCEL,	"llog_cancel" },
118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OBD_QC_CALLBACK,  "obd_quota_callback" },
119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ OBD_IDX_READ,	    "dt_index_read" },
12065f1c7816db85db02b2069f9d0e5111de52f5ee3Mikhail Pershin	{ LLOG_ORIGIN_HANDLE_CREATE,	 "llog_origin_handle_open" },
121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_HANDLE_NEXT_BLOCK, "llog_origin_handle_next_block" },
1221d8cb70c7bdda47125ed551fc390aa9597c5f264Greg Donald	{ LLOG_ORIGIN_HANDLE_READ_HEADER, "llog_origin_handle_read_header" },
123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_HANDLE_WRITE_REC,  "llog_origin_handle_write_rec" },
124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_HANDLE_CLOSE,      "llog_origin_handle_close" },
125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_CONNECT,	   "llog_origin_connect" },
126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_CATINFO,		  "llog_catinfo" },
127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_HANDLE_PREV_BLOCK, "llog_origin_handle_prev_block" },
128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LLOG_ORIGIN_HANDLE_DESTROY,    "llog_origin_handle_destroy" },
129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ QUOTA_DQACQ,      "quota_acquire" },
130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ QUOTA_DQREL,      "quota_release" },
131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ SEQ_QUERY,	"seq_query" },
132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ SEC_CTX_INIT,     "sec_ctx_init" },
1331d8cb70c7bdda47125ed551fc390aa9597c5f264Greg Donald	{ SEC_CTX_INIT_CONT, "sec_ctx_init_cont" },
134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ SEC_CTX_FINI,     "sec_ctx_fini" },
135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ FLD_QUERY,	"fld_query" },
136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ UPDATE_OBJ,	    "update_obj" },
137d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ll_eopcode {
1402a763282df786aa8470a1e52c653dc3dcc574ed7Kristina Martsenko	__u32       opcode;
1412a763282df786aa8470a1e52c653dc3dcc574ed7Kristina Martsenko	const char *opname;
142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao} ll_eopcode_table[EXTRA_LAST_OPC] = {
143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_GLIMPSE_ENQUEUE, "ldlm_glimpse_enqueue" },
144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_PLAIN_ENQUEUE,   "ldlm_plain_enqueue" },
145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_EXTENT_ENQUEUE,  "ldlm_extent_enqueue" },
146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_FLOCK_ENQUEUE,   "ldlm_flock_enqueue" },
147d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ LDLM_IBITS_ENQUEUE,   "ldlm_ibits_enqueue" },
148d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_SETATTR,    "mds_reint_setattr" },
149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_CREATE,     "mds_reint_create" },
150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_LINK,       "mds_reint_link" },
151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_UNLINK,     "mds_reint_unlink" },
152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_RENAME,     "mds_reint_rename" },
153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_OPEN,       "mds_reint_open" },
154d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ MDS_REINT_SETXATTR,   "mds_reint_setxattr" },
155d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ BRW_READ_BYTES,       "read_bytes" },
156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	{ BRW_WRITE_BYTES,      "write_bytes" },
157d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
158d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
159d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst char *ll_opcode2str(__u32 opcode)
160d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
161d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* When one of the assertions below fail, chances are that:
162d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *     1) A new opcode was added in include/lustre/lustre_idl.h,
163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	but is missing from the table above.
164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * or  2) The opcode space was renumbered or rearranged,
165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	and the opcode_offset() function in
166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	ptlrpc_internal.h needs to be modified.
167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32 offset = opcode_offset(opcode);
169d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(offset < LUSTRE_MAX_OPCODES,
170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 "offset %u >= LUSTRE_MAX_OPCODES %u\n",
171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 offset, LUSTRE_MAX_OPCODES);
172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERTF(ll_rpc_opcode_table[offset].opcode == opcode,
173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 "ll_rpc_opcode_table[%u].opcode %u != opcode %u\n",
174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 offset, ll_rpc_opcode_table[offset].opcode, opcode);
175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ll_rpc_opcode_table[offset].opname;
176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoconst char* ll_eopcode2str(__u32 opcode)
179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(ll_eopcode_table[opcode].opcode == opcode);
181d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return ll_eopcode_table[opcode].opname;
182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
183f267cdb464bcab7be965fa2a513675d9ad1e90f6Greg Kroah-Hartman#if defined (CONFIG_PROC_FS)
184d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_register(struct proc_dir_entry *root, char *dir,
185d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     char *name, struct proc_dir_entry **procroot_ret,
186d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     struct lprocfs_stats **stats_ret)
187d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct proc_dir_entry *svc_procroot;
189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lprocfs_stats *svc_stats;
190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int i, rc;
191d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int svc_counter_config = LPROCFS_CNTR_AVGMINMAX |
192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					  LPROCFS_CNTR_STDDEV;
193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(*procroot_ret == NULL);
195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(*stats_ret == NULL);
196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1971d8cb70c7bdda47125ed551fc390aa9597c5f264Greg Donald	svc_stats = lprocfs_alloc_stats(EXTRA_MAX_OPCODES+LUSTRE_MAX_OPCODES,
1981d8cb70c7bdda47125ed551fc390aa9597c5f264Greg Donald					0);
199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc_stats == NULL)
200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (dir) {
203d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		svc_procroot = lprocfs_register(dir, root, NULL, NULL);
204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (IS_ERR(svc_procroot)) {
205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lprocfs_free_stats(&svc_stats);
206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return;
207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
209d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		svc_procroot = root;
210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
211d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_init(svc_stats, PTLRPC_REQWAIT_CNTR,
213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     svc_counter_config, "req_waittime", "usec");
214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_init(svc_stats, PTLRPC_REQQDEPTH_CNTR,
215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     svc_counter_config, "req_qdepth", "reqs");
216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_init(svc_stats, PTLRPC_REQACTIVE_CNTR,
217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     svc_counter_config, "req_active", "reqs");
218d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_init(svc_stats, PTLRPC_TIMEOUT,
219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     svc_counter_config, "req_timeout", "sec");
220d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_init(svc_stats, PTLRPC_REQBUF_AVAIL_CNTR,
221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			     svc_counter_config, "reqbuf_avail", "bufs");
222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (i = 0; i < EXTRA_LAST_OPC; i++) {
223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		char *units;
224d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
2253949015e4dc169e738bb6f04ef5cbd26253b1cf9Kristina Martsenko		switch (i) {
226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		case BRW_WRITE_BYTES:
227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		case BRW_READ_BYTES:
228d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			units = "bytes";
229d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		default:
231d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			units = "reqs";
232d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			break;
233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_counter_init(svc_stats, PTLRPC_LAST_CNTR + i,
235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     svc_counter_config,
236d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     ll_eopcode2str(i), units);
237d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
238d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (i = 0; i < LUSTRE_MAX_OPCODES; i++) {
239d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 opcode = ll_rpc_opcode_table[i].opcode;
240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_counter_init(svc_stats,
241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     EXTRA_MAX_OPCODES + i, svc_counter_config,
242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     ll_opcode2str(opcode), "usec");
243d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = lprocfs_register_stats(svc_procroot, name, svc_stats);
246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0) {
247d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (dir)
248d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			lprocfs_remove(&svc_procroot);
249d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_free_stats(&svc_stats);
250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (dir)
252d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			*procroot_ret = svc_procroot;
253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*stats_ret = svc_stats;
254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
255d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
257d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
25873bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_req_history_len_seq_show(struct seq_file *m, void *v)
259d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
26073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part *svcpt;
262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	total = 0;
263d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	i;
264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc)
266d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		total += svcpt->scp_hist_nrqbds;
267d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
26873bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d\n", total);
269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
27073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_req_history_len);
271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
27373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_req_history_max_seq_show(struct seq_file *m, void *n)
274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
27573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
276d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part *svcpt;
277d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	total = 0;
278d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	i;
279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc)
281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		total += svc->srv_hist_nrqbds_cpt_max;
282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
28373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d\n", total);
284d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
285d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
28673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic ssize_t
28773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_req_history_max_seq_write(struct file *file, const char *buffer,
28873bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao					 size_t count, loff_t *off)
289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
29073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			    bufpages;
292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			    val;
293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			    rc;
294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = lprocfs_write_helper(buffer, count, &val);
296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
299d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val < 0)
300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* This sanity check is more of an insanity check; we can still
303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * hose a kernel by allowing the request history to grow too
304d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * far. */
305d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bufpages = (svc->srv_buf_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
3064f6cc9ab5337879c4a79564b3aed4fa429d1cd12Peng Tao	if (val > totalram_pages / (2 * bufpages))
307d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
308d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&svc->srv_lock);
310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
311d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val == 0)
312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		svc->srv_hist_nrqbds_cpt_max = 0;
313d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		svc->srv_hist_nrqbds_cpt_max = max(1, (val / svc->srv_ncpts));
315d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
316d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&svc->srv_lock);
317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
32073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS(ptlrpc_lprocfs_req_history_max);
321d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
322d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
32373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_threads_min_seq_show(struct seq_file *m, void *n)
324d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
32573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
32773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d\n",
328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			svc->srv_nthrs_cpt_init * svc->srv_ncpts);
329d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
33173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic ssize_t
33273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_threads_min_seq_write(struct file *file, const char *buffer,
33373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao				     size_t count, loff_t *off)
334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
33573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	val;
337d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	rc = lprocfs_write_helper(buffer, count, &val);
338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
339d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
340d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&svc->srv_lock);
346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val > svc->srv_nthrs_cpt_limit * svc->srv_ncpts) {
347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_unlock(&svc->srv_lock);
348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svc->srv_nthrs_cpt_init = val / svc->srv_ncpts;
352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&svc->srv_lock);
354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
355d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
35773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_min);
358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
36073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_threads_started_seq_show(struct seq_file *m, void *n)
361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
36273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
363d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part *svcpt;
364d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	total = 0;
365d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	i;
366d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
367d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc)
368d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		total += svcpt->scp_nthrs_running;
369d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
37073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d\n", total);
371d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
37273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_threads_started);
373d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
374d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
37573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_threads_max_seq_show(struct seq_file *m, void *n)
376d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
37773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
378d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
37973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d\n",
380d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			svc->srv_nthrs_cpt_limit * svc->srv_ncpts);
381d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
382d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
38373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic ssize_t
38473bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoptlrpc_lprocfs_threads_max_seq_write(struct file *file, const char *buffer,
38573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao				     size_t count, loff_t *off)
386d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
38773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
388d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	val;
389d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	rc = lprocfs_write_helper(buffer, count, &val);
390d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
391d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
392d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
393d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
394d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val / svc->srv_ncpts < PTLRPC_NTHRS_INIT)
395d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
396d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
397d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&svc->srv_lock);
398d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val < svc->srv_nthrs_cpt_init * svc->srv_ncpts) {
399d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_unlock(&svc->srv_lock);
400d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
401d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
402d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
403d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svc->srv_nthrs_cpt_limit = val / svc->srv_ncpts;
404d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
405d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&svc->srv_lock);
406d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
407d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
408d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
40973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS(ptlrpc_lprocfs_threads_max);
410d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
411d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
412d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \addtogoup nrs
413d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * @{
414d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
415d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoextern struct nrs_core nrs_core;
416d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
417d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
418d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Translates \e ptlrpc_nrs_pol_state values to human-readable strings.
419d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
420d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param[in] state The policy state
421d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
422d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic const char *nrs_state2str(enum ptlrpc_nrs_pol_state state)
423d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
424d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	switch (state) {
425d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	default:
426d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LBUG();
427d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case NRS_POL_STATE_INVALID:
428d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return "invalid";
429d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case NRS_POL_STATE_STOPPED:
430d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return "stopped";
431d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case NRS_POL_STATE_STOPPING:
432d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return "stopping";
433d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case NRS_POL_STATE_STARTING:
434d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return "starting";
435d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case NRS_POL_STATE_STARTED:
436d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return "started";
437d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
438d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
439d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
440d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
441d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Obtains status information for \a policy.
442d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
443d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Information is copied in \a info.
444d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
445d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param[in] policy The policy
446d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * \param[out] info  Holds returned status information
447d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
448d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid nrs_policy_get_info_locked(struct ptlrpc_nrs_policy *policy,
449d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				struct ptlrpc_nrs_pol_info *info)
450d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
451d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(policy != NULL);
452d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(info != NULL);
4535e42bc9deb5fb43ae44b7f8192c16612e6b1d6bcLi Xi	assert_spin_locked(&policy->pol_nrs->nrs_lock);
454d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
455d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	memcpy(info->pi_name, policy->pol_desc->pd_name, NRS_POL_NAME_MAX);
456d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
457d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	info->pi_fallback    = !!(policy->pol_flags & PTLRPC_NRS_FL_FALLBACK);
458d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	info->pi_state	     = policy->pol_state;
459d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
460d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * XXX: These are accessed without holding
461d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * ptlrpc_service_part::scp_req_lock.
462d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
463d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	info->pi_req_queued  = policy->pol_req_queued;
464d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	info->pi_req_started = policy->pol_req_started;
465d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
466d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
467d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
468d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Reads and prints policy status information for all policies of a PTLRPC
469d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * service.
470d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
47173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic int ptlrpc_lprocfs_nrs_seq_show(struct seq_file *m, void *n)
472d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
47373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service	       *svc = m->private;
474d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part     *svcpt;
475d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_nrs	       *nrs;
476d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_nrs_policy       *policy;
477d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_nrs_pol_info     *infos;
478d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_nrs_pol_info	tmp;
479d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned			num_pols;
480d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned			pol_idx = 0;
481d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	bool				hp = false;
482d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				i;
483d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				rc = 0;
484d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
485d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
486d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Serialize NRS core lprocfs operations with policy registration/
487d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * unregistration.
488d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
489d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	mutex_lock(&nrs_core.nrs_mutex);
490d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
491d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
492d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Use the first service partition's regular NRS head in order to obtain
493d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * the number of policies registered with NRS heads of this service. All
494d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * service partitions will have the same number of policies.
495d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
496d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	nrs = nrs_svcpt2nrs(svc->srv_parts[0], false);
497d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
498d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&nrs->nrs_lock);
499d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	num_pols = svc->srv_parts[0]->scp_nrs_reg.nrs_num_pols;
500d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&nrs->nrs_lock);
501d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
502d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC(infos, num_pols * sizeof(*infos));
503a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (infos == NULL) {
504a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -ENOMEM;
505a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
506a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
507d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoagain:
508d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
509d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc) {
510d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		nrs = nrs_svcpt2nrs(svcpt, hp);
511d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_lock(&nrs->nrs_lock);
512d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
513d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		pol_idx = 0;
514d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
515d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		list_for_each_entry(policy, &nrs->nrs_policy_list,
516d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					pol_list) {
517d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			LASSERT(pol_idx < num_pols);
518d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
519d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			nrs_policy_get_info_locked(policy, &tmp);
520d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			/**
521d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 * Copy values when handling the first service
522d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 * partition.
523d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 */
524d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			if (i == 0) {
525d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				memcpy(infos[pol_idx].pi_name, tmp.pi_name,
526d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				       NRS_POL_NAME_MAX);
527d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				memcpy(&infos[pol_idx].pi_state, &tmp.pi_state,
528d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				       sizeof(tmp.pi_state));
529d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				infos[pol_idx].pi_fallback = tmp.pi_fallback;
530d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				/**
531d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * For the rest of the service partitions
532d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * sanity-check the values we get.
533d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 */
534d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			} else {
535d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				LASSERT(strncmp(infos[pol_idx].pi_name,
536d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						tmp.pi_name,
537d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao						NRS_POL_NAME_MAX) == 0);
538d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				/**
539d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * Not asserting ptlrpc_nrs_pol_info::pi_state,
540d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * because it may be different between
541d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * instances of the same policy in different
542d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 * service partitions.
543d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				 */
544d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				LASSERT(infos[pol_idx].pi_fallback ==
545d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao					tmp.pi_fallback);
546d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			}
547d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
548d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			infos[pol_idx].pi_req_queued += tmp.pi_req_queued;
549d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			infos[pol_idx].pi_req_started += tmp.pi_req_started;
550d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
551d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			pol_idx++;
552d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
553d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_unlock(&nrs->nrs_lock);
554d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
555d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
556d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
557d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Policy status information output is in YAML format.
558d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * For example:
559d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
560d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	regular_requests:
561d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	  - name: fifo
562d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    state: started
563d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    fallback: yes
564d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    queued: 0
565d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    active: 0
566d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
567d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	  - name: crrn
568d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    state: started
569d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    fallback: no
570d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    queued: 2015
571d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    active: 384
572d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
573d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	high_priority_requests:
574d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	  - name: fifo
575d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    state: started
576d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    fallback: yes
577d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    queued: 0
578d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    active: 2
579d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *
580d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	  - name: crrn
581d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    state: stopped
582d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    fallback: no
583d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    queued: 0
584d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 *	    active: 0
585d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
58673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	seq_printf(m, "%s\n",
58773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		      !hp ?  "\nregular_requests:" : "high_priority_requests:");
588d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
589d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (pol_idx = 0; pol_idx < num_pols; pol_idx++) {
59073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		seq_printf(m,  "  - name: %s\n"
591d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "    state: %s\n"
592d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "    fallback: %s\n"
593d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "    queued: %-20d\n"
594d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "    active: %-20d\n\n",
595d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       infos[pol_idx].pi_name,
596d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       nrs_state2str(infos[pol_idx].pi_state),
597d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       infos[pol_idx].pi_fallback ? "yes" : "no",
598d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       (int)infos[pol_idx].pi_req_queued,
599d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       (int)infos[pol_idx].pi_req_started);
600d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
601d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
602d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!hp && nrs_svc_has_hp(svc)) {
603d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		memset(infos, 0, num_pols * sizeof(*infos));
604d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
605d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/**
606d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * Redo the processing for the service's HP NRS heads' policies.
607d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 */
608d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		hp = true;
609d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto again;
610d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
611d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
612d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
613d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (infos)
614d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE(infos, num_pols * sizeof(*infos));
615d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
616d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	mutex_unlock(&nrs_core.nrs_mutex);
617d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
6180a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return rc;
619d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
620d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
621d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
622b6da17f31934372c982bda87258a297bc6ee8950Masanari Iida * The longest valid command string is the maximum policy name size, plus the
623d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * length of the " reg" substring
624d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
625d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define LPROCFS_NRS_WR_MAX_CMD	(NRS_POL_NAME_MAX + sizeof(" reg") - 1)
626d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
627d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/**
628d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Starts and stops a given policy on a PTLRPC service.
629d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao *
630d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * Commands consist of the policy name, followed by an optional [reg|hp] token;
631d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * if the optional token is omitted, the operation is performed on both the
632d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * regular and high-priority (if the service has one) NRS head.
633d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
63429dd4f9be63befafbedeb816f6954148f29592bfAnil Belurstatic ssize_t ptlrpc_lprocfs_nrs_seq_write(struct file *file,
63529dd4f9be63befafbedeb816f6954148f29592bfAnil Belur					const char __user *buffer,
63673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao					size_t count, loff_t *off)
637d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
63873bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
639d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	enum ptlrpc_nrs_queue_type	queue = PTLRPC_NRS_QUEUE_BOTH;
640d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char			       *cmd;
641d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char			       *cmd_copy = NULL;
642d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char			       *token;
643d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				rc = 0;
644d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
645a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (count >= LPROCFS_NRS_WR_MAX_CMD) {
646a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -EINVAL;
647a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
648a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
649d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
650d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC(cmd, LPROCFS_NRS_WR_MAX_CMD);
651a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (cmd == NULL) {
652a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -ENOMEM;
653a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
654a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
655d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
656d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * strsep() modifies its argument, so keep a copy
657d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
658d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cmd_copy = cmd;
659d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
660a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (copy_from_user(cmd, buffer, count)) {
661a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -EFAULT;
662a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
663a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
664d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
665d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cmd[count] = '\0';
666d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
667d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	token = strsep(&cmd, " ");
668d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
669a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (strlen(token) > NRS_POL_NAME_MAX - 1) {
670a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -EINVAL;
671a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
672a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
673d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
674d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
675d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * No [reg|hp] token has been specified
676d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
677d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (cmd == NULL)
678d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto default_queue;
679d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
680d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
681d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * The second token is either NULL, or an optional [reg|hp] string
682d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
683d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (strcmp(cmd, "reg") == 0)
684d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		queue = PTLRPC_NRS_QUEUE_REG;
685d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (strcmp(cmd, "hp") == 0)
686d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		queue = PTLRPC_NRS_QUEUE_HP;
687a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	else {
688a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -EINVAL;
689a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
690a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
691d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
692d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taodefault_queue:
693d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
694a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (queue == PTLRPC_NRS_QUEUE_HP && !nrs_svc_has_hp(svc)) {
695a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		rc = -ENODEV;
696a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
697a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
698d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (queue == PTLRPC_NRS_QUEUE_BOTH && !nrs_svc_has_hp(svc))
699d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		queue = PTLRPC_NRS_QUEUE_REG;
700d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
701d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/**
702d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Serialize NRS core lprocfs operations with policy registration/
703d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * unregistration.
704d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
705d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	mutex_lock(&nrs_core.nrs_mutex);
706d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
707d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = ptlrpc_nrs_policy_control(svc, queue, token, PTLRPC_NRS_CTL_START,
708d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				       false, NULL);
709d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
710d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	mutex_unlock(&nrs_core.nrs_mutex);
711d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
712d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (cmd_copy)
713d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE(cmd_copy, LPROCFS_NRS_WR_MAX_CMD);
714d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
7150a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return rc < 0 ? rc : count;
716d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
71773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS(ptlrpc_lprocfs_nrs);
718d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
719d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/** @} nrs */
720d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
721d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostruct ptlrpc_srh_iterator {
722d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int			srhi_idx;
723d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u64			srhi_seq;
724d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_request	*srhi_req;
725d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao};
726d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
727d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint
728d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoptlrpc_lprocfs_svc_req_history_seek(struct ptlrpc_service_part *svcpt,
729d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    struct ptlrpc_srh_iterator *srhi,
730d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    __u64 seq)
731d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
732d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct list_head		*e;
733d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_request	*req;
734d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
735d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (srhi->srhi_req != NULL &&
736d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    srhi->srhi_seq > svcpt->scp_hist_seq_culled &&
737d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	    srhi->srhi_seq <= seq) {
738d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* If srhi_req was set previously, hasn't been culled and
739d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * we're searching for a seq on or after it (i.e. more
740d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * recent), search from it onwards.
741d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * Since the service history is LRU (i.e. culled reqs will
742d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * be near the head), we shouldn't have to do long
743d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * re-scans */
744d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERTF(srhi->srhi_seq == srhi->srhi_req->rq_history_seq,
745b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman			 "%s:%d: seek seq %llu, request seq %llu\n",
746d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 svcpt->scp_service->srv_name, svcpt->scp_cpt,
747d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 srhi->srhi_seq, srhi->srhi_req->rq_history_seq);
748d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERTF(!list_empty(&svcpt->scp_hist_reqs),
749b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman			 "%s:%d: seek offset %llu, request seq %llu, "
750b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman			 "last culled %llu\n",
751d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 svcpt->scp_service->srv_name, svcpt->scp_cpt,
752d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			 seq, srhi->srhi_seq, svcpt->scp_hist_seq_culled);
753d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		e = &srhi->srhi_req->rq_history_list;
754d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	} else {
755d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* search from start */
756d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		e = svcpt->scp_hist_reqs.next;
757d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
758d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
759d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	while (e != &svcpt->scp_hist_reqs) {
760d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req = list_entry(e, struct ptlrpc_request, rq_history_list);
761d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
762d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (req->rq_history_seq >= seq) {
763d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			srhi->srhi_seq = req->rq_history_seq;
764d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			srhi->srhi_req = req;
765d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return 0;
766d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
767d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		e = e->next;
768d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
769d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
770d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return -ENOENT;
771d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
772d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
773d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/*
774d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * ptlrpc history sequence is used as "position" of seq_file, in some case,
775d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * seq_read() will increase "position" to indicate reading the next
776d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * element, however, low bits of history sequence are reserved for CPT id
777d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * (check the details from comments before ptlrpc_req_add_history), which
778d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * means seq_read() might change CPT id of history sequence and never
779d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * finish reading of requests on a CPT. To make it work, we have to shift
780d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * CPT id to high bits and timestamp to low bits, so seq_read() will only
781d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * increase timestamp which can correctly indicate the next position.
782d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
783d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
784d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* convert seq_file pos to cpt */
785d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PTLRPC_REQ_POS2CPT(svc, pos)			\
786d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	((svc)->srv_cpt_bits == 0 ? 0 :			\
787d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 (__u64)(pos) >> (64 - (svc)->srv_cpt_bits))
788d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
789d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* make up seq_file pos from cpt */
790d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PTLRPC_REQ_CPT2POS(svc, cpt)			\
791d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	((svc)->srv_cpt_bits == 0 ? 0 :			\
792d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 (cpt) << (64 - (svc)->srv_cpt_bits))
793d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
794d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* convert sequence to position */
795d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PTLRPC_REQ_SEQ2POS(svc, seq)			\
796d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	((svc)->srv_cpt_bits == 0 ? (seq) :		\
797d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 ((seq) >> (svc)->srv_cpt_bits) |		\
798d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 ((seq) << (64 - (svc)->srv_cpt_bits)))
799d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
800d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* convert position to sequence */
801d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define PTLRPC_REQ_POS2SEQ(svc, pos)			\
802d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	((svc)->srv_cpt_bits == 0 ? (pos) :		\
803d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 ((__u64)(pos) << (svc)->srv_cpt_bits) |	\
804d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 ((__u64)(pos) >> (64 - (svc)->srv_cpt_bits)))
805d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
806d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void *
807d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoptlrpc_lprocfs_svc_req_history_start(struct seq_file *s, loff_t *pos)
808d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
809d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service		*svc = s->private;
810d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part	*svcpt;
811d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_srh_iterator	*srhi;
812d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int			cpt;
813d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				rc;
814d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				i;
815d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
816d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (sizeof(loff_t) != sizeof(__u64)) { /* can't support */
817d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CWARN("Failed to read request history because size of loff_t "
818d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		      "%d can't match size of u64\n", (int)sizeof(loff_t));
819d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return NULL;
820d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
821d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
822d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC(srhi, sizeof(*srhi));
823d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (srhi == NULL)
824d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return NULL;
825d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
826d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	srhi->srhi_seq = 0;
827d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	srhi->srhi_req = NULL;
828d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
829d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	cpt = PTLRPC_REQ_POS2CPT(svc, *pos);
830d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
831d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc) {
832d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (i < cpt) /* skip */
833d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			continue;
834d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (i > cpt) /* make up the lowest position for this CPT */
835d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			*pos = PTLRPC_REQ_CPT2POS(svc, i);
836d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
837d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_lock(&svcpt->scp_lock);
838d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi,
839d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				PTLRPC_REQ_POS2SEQ(svc, *pos));
840d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_unlock(&svcpt->scp_lock);
841d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc == 0) {
842d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			*pos = PTLRPC_REQ_SEQ2POS(svc, srhi->srhi_seq);
843d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			srhi->srhi_idx = i;
844d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return srhi;
845d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
846d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
847d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
848d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE(srhi, sizeof(*srhi));
849d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return NULL;
850d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
851d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
852d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void
853d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoptlrpc_lprocfs_svc_req_history_stop(struct seq_file *s, void *iter)
854d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
855d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_srh_iterator *srhi = iter;
856d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
857d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (srhi != NULL)
858d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		OBD_FREE(srhi, sizeof(*srhi));
859d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
860d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
861d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic void *
862d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoptlrpc_lprocfs_svc_req_history_next(struct seq_file *s,
863d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				    void *iter, loff_t *pos)
864d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
865d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service		*svc = s->private;
866d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_srh_iterator	*srhi = iter;
867d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part	*svcpt;
868d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u64				seq;
869d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				rc;
870d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				i;
871d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
872d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	for (i = srhi->srhi_idx; i < svc->srv_ncpts; i++) {
873d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		svcpt = svc->srv_parts[i];
874d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
875d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (i > srhi->srhi_idx) { /* reset iterator for a new CPT */
876d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			srhi->srhi_req = NULL;
877d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			seq = srhi->srhi_seq = 0;
878d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} else { /* the next sequence */
879d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			seq = srhi->srhi_seq + (1 << svc->srv_cpt_bits);
880d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
881d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
882d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_lock(&svcpt->scp_lock);
883d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, seq);
884d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		spin_unlock(&svcpt->scp_lock);
885d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (rc == 0) {
886d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			*pos = PTLRPC_REQ_SEQ2POS(svc, srhi->srhi_seq);
887d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			srhi->srhi_idx = i;
888d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			return srhi;
889d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
890d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
891d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
892d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE(srhi, sizeof(*srhi));
893d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return NULL;
894d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
895d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
896d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* common ost/mdt so_req_printer */
897d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid target_print_req(void *seq_file, struct ptlrpc_request *req)
898d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
899d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Called holding srv_lock with irqs disabled.
900d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * Print specific req contents and a newline.
901d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * CAVEAT EMPTOR: check request message length before printing!!!
902d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * You might have received any old crap so you must be just as
903d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * careful here as the service's request parser!!! */
904d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct seq_file *sf = seq_file;
905d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
906d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	switch (req->rq_phase) {
907d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case RQ_PHASE_NEW:
908d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* still awaiting a service thread's attention, or rejected
909d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * because the generic request message didn't unpack */
910d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		seq_printf(sf, "<not swabbed>\n");
911d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
912d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case RQ_PHASE_INTERPRET:
913d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* being handled, so basic msg swabbed, and opc is valid
914d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * but racing with mds_handle() */
915d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case RQ_PHASE_COMPLETE:
916d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* been handled by mds_handle() reply state possibly still
917d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * volatile */
918d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		seq_printf(sf, "opc %d\n", lustre_msg_get_opc(req->rq_reqmsg));
919d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
920d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	default:
921d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		DEBUG_REQ(D_ERROR, req, "bad phase %d", req->rq_phase);
922d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
923d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
924d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(target_print_req);
925d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
926d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int ptlrpc_lprocfs_svc_req_history_show(struct seq_file *s, void *iter)
927d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
928d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service		*svc = s->private;
929d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_srh_iterator	*srhi = iter;
930d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part	*svcpt;
931d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_request		*req;
932d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				rc;
933d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
934d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(srhi->srhi_idx < svc->srv_ncpts);
935d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
936d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svcpt = svc->srv_parts[srhi->srhi_idx];
937d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
938d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&svcpt->scp_lock);
939d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
940d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = ptlrpc_lprocfs_svc_req_history_seek(svcpt, srhi, srhi->srhi_seq);
941d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
942d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc == 0) {
943d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		req = srhi->srhi_req;
944d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
945d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		/* Print common req fields.
946d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * CAVEAT EMPTOR: we're racing with the service handler
947d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * here.  The request could contain any old crap, so you
948d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * must be just as careful as the service's request
949d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * parser. Currently I only print stuff here I know is OK
950d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 * to look at coz it was set up in request_in_callback()!!! */
951b0f5aad587ea1fc3563d056609ee54a961ee1256Greg Kroah-Hartman		seq_printf(s, "%lld:%s:%s:x%llu:%d:%s:%ld:%lds(%+lds) ",
952d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   req->rq_history_seq, libcfs_nid2str(req->rq_self),
953d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   libcfs_id2str(req->rq_peer), req->rq_xid,
954d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   req->rq_reqlen, ptlrpc_rqphase2str(req),
955d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   req->rq_arrival_time.tv_sec,
956d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   req->rq_sent - req->rq_arrival_time.tv_sec,
957d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			   req->rq_sent - req->rq_deadline);
958d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (svc->srv_ops.so_req_printer == NULL)
959d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			seq_printf(s, "\n");
960d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		else
961d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			svc->srv_ops.so_req_printer(s, srhi->srhi_req);
962d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
963d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
964d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&svcpt->scp_lock);
965d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
966d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
967d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
968d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taostatic int
969d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoptlrpc_lprocfs_svc_req_history_open(struct inode *inode, struct file *file)
970d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
971d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	static struct seq_operations sops = {
972d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.start = ptlrpc_lprocfs_svc_req_history_start,
973d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.stop  = ptlrpc_lprocfs_svc_req_history_stop,
974d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.next  = ptlrpc_lprocfs_svc_req_history_next,
975d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.show  = ptlrpc_lprocfs_svc_req_history_show,
976d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	};
977d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct seq_file       *seqf;
978d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		    rc;
979d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
980d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = seq_open(file, &sops);
98173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	if (rc)
982d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
983d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
984d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	seqf = file->private_data;
98573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	seqf->private = PDE_DATA(inode);
986d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return 0;
987d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
988d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
989d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* See also lprocfs_rd_timeouts */
99073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic int ptlrpc_lprocfs_timeouts_seq_show(struct seq_file *m, void *n)
991d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
99273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service		*svc = m->private;
993d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_service_part	*svcpt;
994d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct dhms			ts;
995d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	time_t				worstt;
996d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int			cur;
997d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	unsigned int			worst;
998d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int				i;
999d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1000d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (AT_OFF) {
100173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		seq_printf(m, "adaptive timeouts off, using obd_timeout %u\n",
1002d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       obd_timeout);
100373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		return 0;
1004d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1005d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1006d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_service_for_each_part(svcpt, i, svc) {
1007d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		cur	= at_get(&svcpt->scp_at_estimate);
1008d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		worst	= svcpt->scp_at_estimate.at_worst_ever;
1009d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		worstt	= svcpt->scp_at_estimate.at_worst_time;
10107264b8a5db30b717b39394234fd3bb7dabdbda92Greg Kroah-Hartman		s2dhms(&ts, get_seconds() - worstt);
1011d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
101273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		seq_printf(m, "%10s : cur %3u  worst %3u (at %ld, "
101373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao			      DHMS_FMT" ago) ", "service",
101473bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao			      cur, worst, worstt, DHMS_VARS(&ts));
101573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao
101673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		lprocfs_at_hist_helper(m, &svcpt->scp_at_estimate);
1017d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1018d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
101973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return 0;
1020d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
102173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS_RO(ptlrpc_lprocfs_timeouts);
1022d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
102373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic int ptlrpc_lprocfs_hp_ratio_seq_show(struct seq_file *m, void *v)
1024d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
102573bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = m->private;
102673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	return seq_printf(m, "%d", svc->srv_hpreq_ratio);
1027d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1028d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
102973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taostatic ssize_t ptlrpc_lprocfs_hp_ratio_seq_write(struct file *file,
103073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao					     const char *buffer,
103173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao					     size_t count,
103273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao					     loff_t *off)
1033d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
103473bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct ptlrpc_service *svc = ((struct seq_file *)file->private_data)->private;
1035d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	rc;
1036d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int	val;
1037d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1038d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = lprocfs_write_helper(buffer, count, &val);
1039d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
1040d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
1041d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1042d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val < 0)
1043d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
1044d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1045d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&svc->srv_lock);
1046d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svc->srv_hpreq_ratio = val;
1047d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&svc->srv_lock);
1048d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1049d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
1050d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
105173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng TaoLPROC_SEQ_FOPS(ptlrpc_lprocfs_hp_ratio);
1052d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1053d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_register_service(struct proc_dir_entry *entry,
1054d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				     struct ptlrpc_service *svc)
1055d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1056d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lprocfs_vars lproc_vars[] = {
1057d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "high_priority_ratio",
105873bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_hp_ratio_fops,
1059d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1060d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "req_buffer_history_len",
106173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_req_history_len_fops,
1062d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1063d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "req_buffer_history_max",
106473bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_req_history_max_fops,
1065d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1066d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "threads_min",
106773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_threads_min_fops,
1068d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1069d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "threads_max",
107073bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_threads_max_fops,
1071d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1072d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "threads_started",
107373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_threads_started_fops,
1074d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1075d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "timeouts",
107673bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_timeouts_fops,
1077d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data       = svc},
1078d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{.name       = "nrs_policies",
107973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		 .fops	     = &ptlrpc_lprocfs_nrs_fops,
1080d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		 .data	     = svc},
1081d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		{NULL}
1082d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	};
1083d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	static struct file_operations req_history_fops = {
1084d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.owner       = THIS_MODULE,
1085d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.open	= ptlrpc_lprocfs_svc_req_history_open,
1086d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.read	= seq_read,
1087d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.llseek      = seq_lseek,
1088d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		.release     = lprocfs_seq_release,
1089d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	};
1090d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1091d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
1092d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1093d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_lprocfs_register(entry, svc->srv_name,
1094d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				"stats", &svc->srv_procroot,
1095d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				&svc->srv_stats);
1096d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1097d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc->srv_procroot == NULL)
1098d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
1099d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1100d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_add_vars(svc->srv_procroot, lproc_vars, NULL);
1101d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1102d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = lprocfs_seq_create(svc->srv_procroot, "req_history",
1103d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				0400, &req_history_fops, svc);
1104d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc)
1105d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		CWARN("Error adding the req_history file\n");
1106d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1107d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1108d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_register_obd(struct obd_device *obddev)
1109d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1110d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_lprocfs_register(obddev->obd_proc_entry, NULL, "stats",
1111d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				&obddev->obd_svc_procroot,
1112d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao				&obddev->obd_svc_stats);
1113d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1114d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(ptlrpc_lprocfs_register_obd);
1115d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1116d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_rpc_sent(struct ptlrpc_request *req, long amount)
1117d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1118d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lprocfs_stats *svc_stats;
1119d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	__u32 op = lustre_msg_get_opc(req->rq_reqmsg);
1120d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int opc = opcode_offset(op);
1121d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1122d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svc_stats = req->rq_import->imp_obd->obd_svc_stats;
1123d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc_stats == NULL || opc <= 0)
1124d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
1125d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LASSERT(opc < LUSTRE_MAX_OPCODES);
1126d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!(op == LDLM_ENQUEUE || op == MDS_REINT))
1127d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_counter_add(svc_stats, opc + EXTRA_MAX_OPCODES, amount);
1128d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1129d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1130d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_brw(struct ptlrpc_request *req, int bytes)
1131d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1132d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct lprocfs_stats *svc_stats;
1133d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int idx;
1134d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1135d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!req->rq_import)
1136d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
1137d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	svc_stats = req->rq_import->imp_obd->obd_svc_stats;
1138d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (!svc_stats)
1139d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return;
1140d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	idx = lustre_msg_get_opc(req->rq_reqmsg);
1141d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	switch (idx) {
1142d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case OST_READ:
1143d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		idx = BRW_READ_BYTES + PTLRPC_LAST_CNTR;
1144d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
1145d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	case OST_WRITE:
1146d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		idx = BRW_WRITE_BYTES + PTLRPC_LAST_CNTR;
1147d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
1148d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	default:
1149d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		LASSERTF(0, "unsupported opcode %u\n", idx);
1150d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		break;
1151d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1152d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1153d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	lprocfs_counter_add(svc_stats, idx, bytes);
1154d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1155d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1156d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(ptlrpc_lprocfs_brw);
1157d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1158d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_unregister_service(struct ptlrpc_service *svc)
1159d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1160d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc->srv_procroot != NULL)
1161d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_remove(&svc->srv_procroot);
1162d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1163d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (svc->srv_stats)
1164d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_free_stats(&svc->srv_stats);
1165d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1166d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1167d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taovoid ptlrpc_lprocfs_unregister_obd(struct obd_device *obd)
1168d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
1169d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (obd->obd_svc_procroot)
1170d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_remove(&obd->obd_svc_procroot);
1171d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1172d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (obd->obd_svc_stats)
1173d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		lprocfs_free_stats(&obd->obd_svc_stats);
1174d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1175d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(ptlrpc_lprocfs_unregister_obd);
1176d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1177d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1178d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#define BUFLEN (UUID_MAX + 5)
1179d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1180d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_wr_evict_client(struct file *file, const char *buffer,
118173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao			    size_t count, loff_t *off)
1182d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
118373bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
1184d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char	      *kbuf;
1185d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char	      *tmpbuf;
1186d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1187d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC(kbuf, BUFLEN);
1188d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (kbuf == NULL)
1189d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ENOMEM;
1190d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1191d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/*
1192d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * OBD_ALLOC() will zero kbuf, but we only copy BUFLEN - 1
1193d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * bytes into kbuf, to ensure that the string is NUL-terminated.
1194d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * UUID_MAX should include a trailing NUL already.
1195d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 */
1196d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (copy_from_user(kbuf, buffer,
1197d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       min_t(unsigned long, BUFLEN - 1, count))) {
1198d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		count = -EFAULT;
1199d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		goto out;
1200d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1201d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	tmpbuf = cfs_firststr(kbuf, min_t(unsigned long, BUFLEN - 1, count));
1202d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* Kludge code(deadlock situation): the lprocfs lock has been held
1203b6da17f31934372c982bda87258a297bc6ee8950Masanari Iida	 * since the client is evicted by writing client's
1204d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * uuid/nid to procfs "evict_client" entry. However,
1205d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * obd_export_evict_by_uuid() will call lprocfs_remove() to destroy
1206d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * the proc entries under the being destroyed export{}, so I have
1207d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * to drop the lock at first here.
1208d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	 * - jay, jxiong@clusterfs.com */
1209f9bd9c1a08f852cd6ba6102d15ad94db2d6b595fChristoph Jaeger	class_incref(obd, __func__, current);
1210d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1211d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (strncmp(tmpbuf, "nid:", 4) == 0)
1212d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obd_export_evict_by_nid(obd, tmpbuf + 4);
1213d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else if (strncmp(tmpbuf, "uuid:", 5) == 0)
1214d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obd_export_evict_by_uuid(obd, tmpbuf + 5);
1215d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	else
1216d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		obd_export_evict_by_uuid(obd, tmpbuf);
1217d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1218f9bd9c1a08f852cd6ba6102d15ad94db2d6b595fChristoph Jaeger	class_decref(obd, __func__, current);
1219d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1220d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
1221d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE(kbuf, BUFLEN);
1222d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
1223d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1224d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_wr_evict_client);
1225d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1226d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao#undef BUFLEN
1227d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1228d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_wr_ping(struct file *file, const char *buffer,
122973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		    size_t count, loff_t *off)
1230d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
123173bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
1232d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct ptlrpc_request *req;
1233d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int		    rc;
1234d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1235d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_CHECK(obd);
1236d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req = ptlrpc_prep_ping(obd->u.cli.cl_import);
1237d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_EXIT(obd);
1238d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (req == NULL)
12390a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return -ENOMEM;
1240d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1241d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	req->rq_send_state = LUSTRE_IMP_FULL;
1242d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1243d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = ptlrpc_queue_wait(req);
1244d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1245d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptlrpc_req_finished(req);
1246d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc >= 0)
12470a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman		return count;
12480a3bdb00710bf253ba8ba8f645645f22297c7a04Greg Kroah-Hartman	return rc;
1249d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1250d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_wr_ping);
1251d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1252d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao/* Write the connection UUID to this file to attempt to connect to that node.
1253d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * The connection UUID is a node's primary NID. For example,
1254d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao * "echo connection=192.168.0.1@tcp0::instance > .../import".
1255d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao */
1256d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_wr_import(struct file *file, const char *buffer,
125773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		      size_t count, loff_t *off)
1258d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
125973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
1260d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_import *imp = obd->u.cli.cl_import;
1261d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *kbuf = NULL;
1262d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *uuid;
1263d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	char *ptr;
1264d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int do_reconn = 1;
1265d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const char prefix[] = "connection=";
1266d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	const int prefix_len = sizeof(prefix) - 1;
1267d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1268d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (count > PAGE_CACHE_SIZE - 1 || count <= prefix_len)
1269d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -EINVAL;
1270d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1271d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_ALLOC(kbuf, count + 1);
1272d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (kbuf == NULL)
1273d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ENOMEM;
1274d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1275a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (copy_from_user(kbuf, buffer, count)) {
1276a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		count = -EFAULT;
1277a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
1278a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
1279d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1280d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	kbuf[count] = 0;
1281d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1282d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	/* only support connection=uuid::instance now */
1283a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	if (strncmp(prefix, kbuf, prefix_len) != 0) {
1284a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		count = -EINVAL;
1285a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall		goto out;
1286a9b3e8f30e33d3542b00edcf0641d031b80967cbJulia Lawall	}
1287d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1288d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	uuid = kbuf + prefix_len;
1289d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	ptr = strstr(uuid, "::");
1290d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (ptr) {
1291d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		__u32 inst;
1292d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		char *endptr;
1293d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1294d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		*ptr = 0;
1295d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		do_reconn = 0;
1296d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ptr += strlen("::");
1297d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		inst = simple_strtol(ptr, &endptr, 10);
1298d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		if (*endptr) {
1299d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CERROR("config: wrong instance # %s\n", ptr);
1300d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} else if (inst != imp->imp_connect_data.ocd_instance) {
1301d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CDEBUG(D_INFO, "IR: %s is connecting to an obsoleted "
1302d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "target(%u/%u), reconnecting...\n",
1303d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       imp->imp_obd->obd_name,
1304d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       imp->imp_connect_data.ocd_instance, inst);
1305d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			do_reconn = 1;
1306d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		} else {
1307d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			CDEBUG(D_INFO, "IR: %s has already been connecting to "
1308d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       "new target(%u)\n",
1309d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao			       imp->imp_obd->obd_name, inst);
1310d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		}
1311d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	}
1312d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1313d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (do_reconn)
1314d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		ptlrpc_recover_import(imp, uuid, 1);
1315d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1316d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoout:
1317d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	OBD_FREE(kbuf, count + 1);
1318d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
1319d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1320d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_wr_import);
1321d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
132273bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Taoint lprocfs_rd_pinger_recov(struct seq_file *m, void *n)
1323d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
132473bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct obd_device *obd = m->private;
1325d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_import *imp = obd->u.cli.cl_import;
1326d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc;
1327d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1328d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_CHECK(obd);
132973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	rc = seq_printf(m, "%d\n", !imp->imp_no_pinger_recover);
1330d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_EXIT(obd);
1331d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1332d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return rc;
1333d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1334d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_rd_pinger_recov);
1335d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1336d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Taoint lprocfs_wr_pinger_recov(struct file *file, const char *buffer,
133773bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao		      size_t count, loff_t *off)
1338d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao{
133973bb1da692d0dc3e93b9c9e29084d6a5dcbc37a6Peng Tao	struct obd_device *obd = ((struct seq_file *)file->private_data)->private;
1340d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct client_obd *cli = &obd->u.cli;
1341d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	struct obd_import *imp = cli->cl_import;
1342d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	int rc, val;
1343d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1344d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	rc = lprocfs_write_helper(buffer, count, &val);
1345d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (rc < 0)
1346d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return rc;
1347d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1348d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	if (val != 0 && val != 1)
1349d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao		return -ERANGE;
1350d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1351d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_CHECK(obd);
1352d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_lock(&imp->imp_lock);
1353d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	imp->imp_no_pinger_recover = !val;
1354d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	spin_unlock(&imp->imp_lock);
1355d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	LPROCFS_CLIMP_EXIT(obd);
1356d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1357d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao	return count;
1358d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1359d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao}
1360d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng TaoEXPORT_SYMBOL(lprocfs_wr_pinger_recov);
1361d7e09d0397e84eefbabfd9cb353221f3c6448d83Peng Tao
1362f267cdb464bcab7be965fa2a513675d9ad1e90f6Greg Kroah-Hartman#endif /* CONFIG_PROC_FS */
1363