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