Blame view

block/blk-mq-debugfs.c 24.5 KB
8c16567d8   Christoph Hellwig   block: switch all...
1
  // SPDX-License-Identifier: GPL-2.0
07e4fead4   Omar Sandoval   blk-mq: create de...
2
3
  /*
   * Copyright (C) 2017 Facebook
07e4fead4   Omar Sandoval   blk-mq: create de...
4
5
6
7
8
9
10
   */
  
  #include <linux/kernel.h>
  #include <linux/blkdev.h>
  #include <linux/debugfs.h>
  
  #include <linux/blk-mq.h>
18fbda91c   Omar Sandoval   block: use same b...
11
  #include "blk.h"
07e4fead4   Omar Sandoval   blk-mq: create de...
12
  #include "blk-mq.h"
d173a2516   Omar Sandoval   blk-mq: move debu...
13
  #include "blk-mq-debugfs.h"
d96b37c0a   Omar Sandoval   blk-mq: move tags...
14
  #include "blk-mq-tag.h"
cc56694f1   Ming Lei   blk-mq-debugfs: s...
15
  #include "blk-rq-qos.h"
07e4fead4   Omar Sandoval   blk-mq: create de...
16

1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
17
18
19
  static void print_stat(struct seq_file *m, struct blk_rq_stat *stat)
  {
  	if (stat->nr_samples) {
315eb6566   Pavel Begunkov   blk-mq/debugfs: F...
20
  		seq_printf(m, "samples=%d, mean=%llu, min=%llu, max=%llu",
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
21
22
23
24
25
26
27
28
29
30
  			   stat->nr_samples, stat->mean, stat->min, stat->max);
  	} else {
  		seq_puts(m, "samples=0");
  	}
  }
  
  static int queue_poll_stat_show(void *data, struct seq_file *m)
  {
  	struct request_queue *q = data;
  	int bucket;
243d9f78d   Chaitanya Kulkarni   block: code clean...
31
32
33
  	for (bucket = 0; bucket < (BLK_MQ_POLL_STATS_BKTS / 2); bucket++) {
  		seq_printf(m, "read  (%d Bytes): ", 1 << (9 + bucket));
  		print_stat(m, &q->poll_stat[2 * bucket]);
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
34
35
  		seq_puts(m, "
  ");
243d9f78d   Chaitanya Kulkarni   block: code clean...
36
37
  		seq_printf(m, "write (%d Bytes): ",  1 << (9 + bucket));
  		print_stat(m, &q->poll_stat[2 * bucket + 1]);
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  		seq_puts(m, "
  ");
  	}
  	return 0;
  }
  
  static void *queue_requeue_list_start(struct seq_file *m, loff_t *pos)
  	__acquires(&q->requeue_lock)
  {
  	struct request_queue *q = m->private;
  
  	spin_lock_irq(&q->requeue_lock);
  	return seq_list_start(&q->requeue_list, *pos);
  }
  
  static void *queue_requeue_list_next(struct seq_file *m, void *v, loff_t *pos)
  {
  	struct request_queue *q = m->private;
  
  	return seq_list_next(v, &q->requeue_list, pos);
  }
  
  static void queue_requeue_list_stop(struct seq_file *m, void *v)
  	__releases(&q->requeue_lock)
  {
  	struct request_queue *q = m->private;
  
  	spin_unlock_irq(&q->requeue_lock);
  }
  
  static const struct seq_operations queue_requeue_list_seq_ops = {
  	.start	= queue_requeue_list_start,
  	.next	= queue_requeue_list_next,
  	.stop	= queue_requeue_list_stop,
  	.show	= blk_mq_debugfs_rq_show,
  };
91d68905a   Bart Van Assche   blk-mq: Export qu...
74
75
76
77
78
79
80
81
82
83
  static int blk_flags_show(struct seq_file *m, const unsigned long flags,
  			  const char *const *flag_name, int flag_name_count)
  {
  	bool sep = false;
  	int i;
  
  	for (i = 0; i < sizeof(flags) * BITS_PER_BYTE; i++) {
  		if (!(flags & BIT(i)))
  			continue;
  		if (sep)
bec03d6b9   Omar Sandoval   blk-mq-debugfs: s...
84
  			seq_puts(m, "|");
91d68905a   Bart Van Assche   blk-mq: Export qu...
85
86
87
88
89
90
  		sep = true;
  		if (i < flag_name_count && flag_name[i])
  			seq_puts(m, flag_name[i]);
  		else
  			seq_printf(m, "%d", i);
  	}
91d68905a   Bart Van Assche   blk-mq: Export qu...
91
92
  	return 0;
  }
cd84a62e0   Bart Van Assche   block, scsi: Chan...
93
94
95
96
97
98
99
100
  static int queue_pm_only_show(void *data, struct seq_file *m)
  {
  	struct request_queue *q = data;
  
  	seq_printf(m, "%d
  ", atomic_read(&q->pm_only));
  	return 0;
  }
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
101
  #define QUEUE_FLAG_NAME(name) [QUEUE_FLAG_##name] = #name
91d68905a   Bart Van Assche   blk-mq: Export qu...
102
  static const char *const blk_queue_flag_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
103
  	QUEUE_FLAG_NAME(STOPPED),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
104
  	QUEUE_FLAG_NAME(DYING),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
105
106
107
  	QUEUE_FLAG_NAME(NOMERGES),
  	QUEUE_FLAG_NAME(SAME_COMP),
  	QUEUE_FLAG_NAME(FAIL_IO),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
108
109
110
111
112
113
114
115
116
  	QUEUE_FLAG_NAME(NONROT),
  	QUEUE_FLAG_NAME(IO_STAT),
  	QUEUE_FLAG_NAME(DISCARD),
  	QUEUE_FLAG_NAME(NOXMERGES),
  	QUEUE_FLAG_NAME(ADD_RANDOM),
  	QUEUE_FLAG_NAME(SECERASE),
  	QUEUE_FLAG_NAME(SAME_FORCE),
  	QUEUE_FLAG_NAME(DEAD),
  	QUEUE_FLAG_NAME(INIT_DONE),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
117
118
119
  	QUEUE_FLAG_NAME(POLL),
  	QUEUE_FLAG_NAME(WC),
  	QUEUE_FLAG_NAME(FUA),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
120
121
122
123
  	QUEUE_FLAG_NAME(DAX),
  	QUEUE_FLAG_NAME(STATS),
  	QUEUE_FLAG_NAME(POLL_STATS),
  	QUEUE_FLAG_NAME(REGISTERED),
22d538213   Bart Van Assche   blk-mq-debugfs: A...
124
125
  	QUEUE_FLAG_NAME(SCSI_PASSTHROUGH),
  	QUEUE_FLAG_NAME(QUIESCED),
c3adbd37c   Hou Tao   blk-mq-debugfs: u...
126
127
128
  	QUEUE_FLAG_NAME(PCI_P2PDMA),
  	QUEUE_FLAG_NAME(ZONE_RESETALL),
  	QUEUE_FLAG_NAME(RQ_ALLOC_TIME),
91d68905a   Bart Van Assche   blk-mq: Export qu...
129
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
130
  #undef QUEUE_FLAG_NAME
91d68905a   Bart Van Assche   blk-mq: Export qu...
131

f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
132
  static int queue_state_show(void *data, struct seq_file *m)
91d68905a   Bart Van Assche   blk-mq: Export qu...
133
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
134
  	struct request_queue *q = data;
91d68905a   Bart Van Assche   blk-mq: Export qu...
135
136
137
  
  	blk_flags_show(m, q->queue_flags, blk_queue_flag_name,
  		       ARRAY_SIZE(blk_queue_flag_name));
fd07dc818   Bart Van Assche   blk-mq: Make blk_...
138
139
  	seq_puts(m, "
  ");
91d68905a   Bart Van Assche   blk-mq: Export qu...
140
141
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
142
143
  static ssize_t queue_state_write(void *data, const char __user *buf,
  				 size_t count, loff_t *ppos)
91d68905a   Bart Van Assche   blk-mq: Export qu...
144
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
145
  	struct request_queue *q = data;
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
146
  	char opbuf[16] = { }, *op;
91d68905a   Bart Van Assche   blk-mq: Export qu...
147

18d4d7d05   Bart Van Assche   blk-mq: Do not in...
148
149
150
151
152
153
154
  	/*
  	 * The "state" attribute is removed after blk_cleanup_queue() has called
  	 * blk_mq_free_queue(). Return if QUEUE_FLAG_DEAD has been set to avoid
  	 * triggering a use-after-free.
  	 */
  	if (blk_queue_dead(q))
  		return -ENOENT;
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
155
  	if (count >= sizeof(opbuf)) {
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
156
157
158
159
  		pr_err("%s: operation too long
  ", __func__);
  		goto inval;
  	}
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
160
  	if (copy_from_user(opbuf, buf, count))
91d68905a   Bart Van Assche   blk-mq: Export qu...
161
  		return -EFAULT;
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
162
  	op = strstrip(opbuf);
91d68905a   Bart Van Assche   blk-mq: Export qu...
163
164
165
166
  	if (strcmp(op, "run") == 0) {
  		blk_mq_run_hw_queues(q, true);
  	} else if (strcmp(op, "start") == 0) {
  		blk_mq_start_stopped_hw_queues(q, true);
edea55abb   Bart Van Assche   blk-mq-debugfs: A...
167
168
  	} else if (strcmp(op, "kick") == 0) {
  		blk_mq_kick_requeue_list(q);
91d68905a   Bart Van Assche   blk-mq: Export qu...
169
  	} else {
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
170
171
172
  		pr_err("%s: unsupported operation '%s'
  ", __func__, op);
  inval:
edea55abb   Bart Van Assche   blk-mq-debugfs: A...
173
174
  		pr_err("%s: use 'run', 'start' or 'kick'
  ", __func__);
91d68905a   Bart Van Assche   blk-mq: Export qu...
175
176
  		return -EINVAL;
  	}
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
177
  	return count;
91d68905a   Bart Van Assche   blk-mq: Export qu...
178
  }
f793dfd3f   Jens Axboe   blk-mq: expose wr...
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
  static int queue_write_hint_show(void *data, struct seq_file *m)
  {
  	struct request_queue *q = data;
  	int i;
  
  	for (i = 0; i < BLK_MAX_WRITE_HINTS; i++)
  		seq_printf(m, "hint%d: %llu
  ", i, q->write_hints[i]);
  
  	return 0;
  }
  
  static ssize_t queue_write_hint_store(void *data, const char __user *buf,
  				      size_t count, loff_t *ppos)
  {
  	struct request_queue *q = data;
  	int i;
  
  	for (i = 0; i < BLK_MAX_WRITE_HINTS; i++)
  		q->write_hints[i] = 0;
  
  	return count;
  }
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
202
203
204
  static const struct blk_mq_debugfs_attr blk_mq_debugfs_queue_attrs[] = {
  	{ "poll_stat", 0400, queue_poll_stat_show },
  	{ "requeue_list", 0400, .seq_ops = &queue_requeue_list_seq_ops },
cd84a62e0   Bart Van Assche   block, scsi: Chan...
205
  	{ "pm_only", 0600, queue_pm_only_show, NULL },
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
206
207
  	{ "state", 0600, queue_state_show, queue_state_write },
  	{ "write_hints", 0600, queue_write_hint_show, queue_write_hint_store },
18bc42308   Bart Van Assche   blk-mq-debugfs: S...
208
  	{ "zone_wlock", 0400, queue_zone_wlock_show, NULL },
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
209
210
  	{ },
  };
34dbad5d2   Omar Sandoval   blk-stat: convert...
211

1a435111f   Omar Sandoval   blk-mq-debugfs: c...
212
  #define HCTX_STATE_NAME(name) [BLK_MQ_S_##name] = #name
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
213
  static const char *const hctx_state_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
214
215
216
  	HCTX_STATE_NAME(STOPPED),
  	HCTX_STATE_NAME(TAG_ACTIVE),
  	HCTX_STATE_NAME(SCHED_RESTART),
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
217
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
218
  #undef HCTX_STATE_NAME
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
219
  static int hctx_state_show(void *data, struct seq_file *m)
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
220
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
221
  	struct blk_mq_hw_ctx *hctx = data;
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
222

f5c0b0910   Bart Van Assche   blk-mq: Show symb...
223
224
  	blk_flags_show(m, hctx->state, hctx_state_name,
  		       ARRAY_SIZE(hctx_state_name));
fd07dc818   Bart Van Assche   blk-mq: Make blk_...
225
226
  	seq_puts(m, "
  ");
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
227
228
  	return 0;
  }
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
229
  #define BLK_TAG_ALLOC_NAME(name) [BLK_TAG_ALLOC_##name] = #name
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
230
  static const char *const alloc_policy_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
231
232
  	BLK_TAG_ALLOC_NAME(FIFO),
  	BLK_TAG_ALLOC_NAME(RR),
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
233
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
234
  #undef BLK_TAG_ALLOC_NAME
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
235

1a435111f   Omar Sandoval   blk-mq-debugfs: c...
236
  #define HCTX_FLAG_NAME(name) [ilog2(BLK_MQ_F_##name)] = #name
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
237
  static const char *const hctx_flag_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
238
239
  	HCTX_FLAG_NAME(SHOULD_MERGE),
  	HCTX_FLAG_NAME(TAG_SHARED),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
240
241
  	HCTX_FLAG_NAME(BLOCKING),
  	HCTX_FLAG_NAME(NO_SCHED),
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
242
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
243
  #undef HCTX_FLAG_NAME
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
244

f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
245
  static int hctx_flags_show(void *data, struct seq_file *m)
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
246
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
247
  	struct blk_mq_hw_ctx *hctx = data;
f5c0b0910   Bart Van Assche   blk-mq: Show symb...
248
  	const int alloc_policy = BLK_MQ_FLAG_TO_ALLOC_POLICY(hctx->flags);
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
249

f5c0b0910   Bart Van Assche   blk-mq: Show symb...
250
251
252
253
254
255
256
257
258
259
  	seq_puts(m, "alloc_policy=");
  	if (alloc_policy < ARRAY_SIZE(alloc_policy_name) &&
  	    alloc_policy_name[alloc_policy])
  		seq_puts(m, alloc_policy_name[alloc_policy]);
  	else
  		seq_printf(m, "%d", alloc_policy);
  	seq_puts(m, " ");
  	blk_flags_show(m,
  		       hctx->flags ^ BLK_ALLOC_POLICY_TO_MQ_FLAG(alloc_policy),
  		       hctx_flag_name, ARRAY_SIZE(hctx_flag_name));
fd07dc818   Bart Van Assche   blk-mq: Make blk_...
260
261
  	seq_puts(m, "
  ");
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
262
263
  	return 0;
  }
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
264
  #define CMD_FLAG_NAME(name) [__REQ_##name] = #name
8658dca8b   Bart Van Assche   blk-mq: Show oper...
265
  static const char *const cmd_flag_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
266
267
268
269
270
271
272
273
274
275
276
277
278
  	CMD_FLAG_NAME(FAILFAST_DEV),
  	CMD_FLAG_NAME(FAILFAST_TRANSPORT),
  	CMD_FLAG_NAME(FAILFAST_DRIVER),
  	CMD_FLAG_NAME(SYNC),
  	CMD_FLAG_NAME(META),
  	CMD_FLAG_NAME(PRIO),
  	CMD_FLAG_NAME(NOMERGE),
  	CMD_FLAG_NAME(IDLE),
  	CMD_FLAG_NAME(INTEGRITY),
  	CMD_FLAG_NAME(FUA),
  	CMD_FLAG_NAME(PREFLUSH),
  	CMD_FLAG_NAME(RAHEAD),
  	CMD_FLAG_NAME(BACKGROUND),
22d538213   Bart Van Assche   blk-mq-debugfs: A...
279
  	CMD_FLAG_NAME(NOWAIT),
1c26010c5   Jianchao Wang   blk-mq: fix the c...
280
281
  	CMD_FLAG_NAME(NOUNMAP),
  	CMD_FLAG_NAME(HIPRI),
8658dca8b   Bart Van Assche   blk-mq: Show oper...
282
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
283
  #undef CMD_FLAG_NAME
8658dca8b   Bart Van Assche   blk-mq: Show oper...
284

1a435111f   Omar Sandoval   blk-mq-debugfs: c...
285
  #define RQF_NAME(name) [ilog2((__force u32)RQF_##name)] = #name
8658dca8b   Bart Van Assche   blk-mq: Show oper...
286
  static const char *const rqf_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
287
  	RQF_NAME(SORTED),
85ba3effc   Jens Axboe   blk-mq: add missi...
288
  	RQF_NAME(STARTED),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
  	RQF_NAME(SOFTBARRIER),
  	RQF_NAME(FLUSH_SEQ),
  	RQF_NAME(MIXED_MERGE),
  	RQF_NAME(MQ_INFLIGHT),
  	RQF_NAME(DONTPREP),
  	RQF_NAME(PREEMPT),
  	RQF_NAME(COPY_USER),
  	RQF_NAME(FAILED),
  	RQF_NAME(QUIET),
  	RQF_NAME(ELVPRIV),
  	RQF_NAME(IO_STAT),
  	RQF_NAME(ALLOCED),
  	RQF_NAME(PM),
  	RQF_NAME(HASHED),
  	RQF_NAME(STATS),
  	RQF_NAME(SPECIAL_PAYLOAD),
5d75d3f2e   Jens Axboe   blk-mq: add a few...
305
  	RQF_NAME(ZONE_WRITE_LOCKED),
76a86f9d0   Jens Axboe   block: remove REQ...
306
  	RQF_NAME(MQ_POLL_SLEPT),
8658dca8b   Bart Van Assche   blk-mq: Show oper...
307
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
308
  #undef RQF_NAME
8658dca8b   Bart Van Assche   blk-mq: Show oper...
309

ec6dcf63c   Bart Van Assche   blk-mq-debugfs: S...
310
311
312
313
314
315
316
317
  static const char *const blk_mq_rq_state_name_array[] = {
  	[MQ_RQ_IDLE]		= "idle",
  	[MQ_RQ_IN_FLIGHT]	= "in_flight",
  	[MQ_RQ_COMPLETE]	= "complete",
  };
  
  static const char *blk_mq_rq_state_name(enum mq_rq_state rq_state)
  {
a1e791886   Dan Carpenter   blk-mq-debugfs: O...
318
  	if (WARN_ON_ONCE((unsigned int)rq_state >=
ec6dcf63c   Bart Van Assche   blk-mq-debugfs: S...
319
320
321
322
  			 ARRAY_SIZE(blk_mq_rq_state_name_array)))
  		return "(?)";
  	return blk_mq_rq_state_name_array[rq_state];
  }
daaadb3e9   Omar Sandoval   mq-deadline: add ...
323
  int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
324
  {
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
325
  	const struct blk_mq_ops *const mq_ops = rq->q->mq_ops;
f9bc64a0f   Chaitanya Kulkarni   block: use req_op...
326
  	const unsigned int op = req_op(rq);
874c893bf   Chaitanya Kulkarni   block: use blk_op...
327
  	const char *op_str = blk_op_str(op);
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
328

8658dca8b   Bart Van Assche   blk-mq: Show oper...
329
  	seq_printf(m, "%p {.op=", rq);
874c893bf   Chaitanya Kulkarni   block: use blk_op...
330
  	if (strcmp(op_str, "UNKNOWN") == 0)
3f6d385f8   Chaitanya Kulkarni   block: use right ...
331
  		seq_printf(m, "%u", op);
8658dca8b   Bart Van Assche   blk-mq: Show oper...
332
  	else
874c893bf   Chaitanya Kulkarni   block: use blk_op...
333
  		seq_printf(m, "%s", op_str);
8658dca8b   Bart Van Assche   blk-mq: Show oper...
334
335
336
337
338
339
  	seq_puts(m, ", .cmd_flags=");
  	blk_flags_show(m, rq->cmd_flags & ~REQ_OP_MASK, cmd_flag_name,
  		       ARRAY_SIZE(cmd_flag_name));
  	seq_puts(m, ", .rq_flags=");
  	blk_flags_show(m, (__force unsigned int)rq->rq_flags, rqf_name,
  		       ARRAY_SIZE(rqf_name));
ec6dcf63c   Bart Van Assche   blk-mq-debugfs: S...
340
  	seq_printf(m, ", .state=%s", blk_mq_rq_state_name(blk_mq_rq_state(rq)));
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
341
  	seq_printf(m, ", .tag=%d, .internal_tag=%d", rq->tag,
8658dca8b   Bart Van Assche   blk-mq: Show oper...
342
  		   rq->internal_tag);
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
343
344
345
346
  	if (mq_ops->show_rq)
  		mq_ops->show_rq(m, rq);
  	seq_puts(m, "}
  ");
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
347
348
  	return 0;
  }
daaadb3e9   Omar Sandoval   mq-deadline: add ...
349
350
351
352
353
354
  EXPORT_SYMBOL_GPL(__blk_mq_debugfs_rq_show);
  
  int blk_mq_debugfs_rq_show(struct seq_file *m, void *v)
  {
  	return __blk_mq_debugfs_rq_show(m, list_entry_rq(v));
  }
16b738f65   Omar Sandoval   kyber: add debugf...
355
  EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show);
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
356
357
  
  static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos)
f3bcb0e60   Bart Van Assche   blk-mq-debugfs: A...
358
  	__acquires(&hctx->lock)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
  {
  	struct blk_mq_hw_ctx *hctx = m->private;
  
  	spin_lock(&hctx->lock);
  	return seq_list_start(&hctx->dispatch, *pos);
  }
  
  static void *hctx_dispatch_next(struct seq_file *m, void *v, loff_t *pos)
  {
  	struct blk_mq_hw_ctx *hctx = m->private;
  
  	return seq_list_next(v, &hctx->dispatch, pos);
  }
  
  static void hctx_dispatch_stop(struct seq_file *m, void *v)
f3bcb0e60   Bart Van Assche   blk-mq-debugfs: A...
374
  	__releases(&hctx->lock)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
375
376
377
378
379
380
381
382
383
384
385
386
  {
  	struct blk_mq_hw_ctx *hctx = m->private;
  
  	spin_unlock(&hctx->lock);
  }
  
  static const struct seq_operations hctx_dispatch_seq_ops = {
  	.start	= hctx_dispatch_start,
  	.next	= hctx_dispatch_next,
  	.stop	= hctx_dispatch_stop,
  	.show	= blk_mq_debugfs_rq_show,
  };
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
387
388
389
390
391
392
393
  struct show_busy_params {
  	struct seq_file		*m;
  	struct blk_mq_hw_ctx	*hctx;
  };
  
  /*
   * Note: the state of a request may change while this function is in progress,
7baa85727   Jens Axboe   blk-mq-tag: chang...
394
395
   * e.g. due to a concurrent blk_mq_finish_request() call. Returns true to
   * keep iterating requests.
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
396
   */
7baa85727   Jens Axboe   blk-mq-tag: chang...
397
  static bool hctx_show_busy_rq(struct request *rq, void *data, bool reserved)
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
398
399
  {
  	const struct show_busy_params *params = data;
ea4f995ee   Jens Axboe   blk-mq: cache req...
400
  	if (rq->mq_hctx == params->hctx)
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
401
402
  		__blk_mq_debugfs_rq_show(params->m,
  					 list_entry_rq(&rq->queuelist));
7baa85727   Jens Axboe   blk-mq-tag: chang...
403
404
  
  	return true;
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
405
406
407
408
409
410
411
412
413
414
415
416
  }
  
  static int hctx_busy_show(void *data, struct seq_file *m)
  {
  	struct blk_mq_hw_ctx *hctx = data;
  	struct show_busy_params params = { .m = m, .hctx = hctx };
  
  	blk_mq_tagset_busy_iter(hctx->queue->tag_set, hctx_show_busy_rq,
  				&params);
  
  	return 0;
  }
346fc1089   Ming Lei   blk-mq: export hc...
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
  static const char *const hctx_types[] = {
  	[HCTX_TYPE_DEFAULT]	= "default",
  	[HCTX_TYPE_READ]	= "read",
  	[HCTX_TYPE_POLL]	= "poll",
  };
  
  static int hctx_type_show(void *data, struct seq_file *m)
  {
  	struct blk_mq_hw_ctx *hctx = data;
  
  	BUILD_BUG_ON(ARRAY_SIZE(hctx_types) != HCTX_MAX_TYPES);
  	seq_printf(m, "%s
  ", hctx_types[hctx->type]);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
432
  static int hctx_ctx_map_show(void *data, struct seq_file *m)
0bfa5288a   Omar Sandoval   blk-mq: export so...
433
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
434
  	struct blk_mq_hw_ctx *hctx = data;
0bfa5288a   Omar Sandoval   blk-mq: export so...
435
436
437
438
  
  	sbitmap_bitmap_show(&hctx->ctx_map, m);
  	return 0;
  }
d96b37c0a   Omar Sandoval   blk-mq: move tags...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
  static void blk_mq_debugfs_tags_show(struct seq_file *m,
  				     struct blk_mq_tags *tags)
  {
  	seq_printf(m, "nr_tags=%u
  ", tags->nr_tags);
  	seq_printf(m, "nr_reserved_tags=%u
  ", tags->nr_reserved_tags);
  	seq_printf(m, "active_queues=%d
  ",
  		   atomic_read(&tags->active_queues));
  
  	seq_puts(m, "
  bitmap_tags:
  ");
  	sbitmap_queue_show(&tags->bitmap_tags, m);
  
  	if (tags->nr_reserved_tags) {
  		seq_puts(m, "
  breserved_tags:
  ");
  		sbitmap_queue_show(&tags->breserved_tags, m);
  	}
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
462
  static int hctx_tags_show(void *data, struct seq_file *m)
d96b37c0a   Omar Sandoval   blk-mq: move tags...
463
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
464
  	struct blk_mq_hw_ctx *hctx = data;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
465
  	struct request_queue *q = hctx->queue;
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
466
  	int res;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
467

8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
468
469
470
  	res = mutex_lock_interruptible(&q->sysfs_lock);
  	if (res)
  		goto out;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
471
472
473
  	if (hctx->tags)
  		blk_mq_debugfs_tags_show(m, hctx->tags);
  	mutex_unlock(&q->sysfs_lock);
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
474
475
  out:
  	return res;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
476
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
477
  static int hctx_tags_bitmap_show(void *data, struct seq_file *m)
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
478
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
479
  	struct blk_mq_hw_ctx *hctx = data;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
480
  	struct request_queue *q = hctx->queue;
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
481
  	int res;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
482

8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
483
484
485
  	res = mutex_lock_interruptible(&q->sysfs_lock);
  	if (res)
  		goto out;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
486
487
488
  	if (hctx->tags)
  		sbitmap_bitmap_show(&hctx->tags->bitmap_tags.sb, m);
  	mutex_unlock(&q->sysfs_lock);
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
489
490
491
  
  out:
  	return res;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
492
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
493
  static int hctx_sched_tags_show(void *data, struct seq_file *m)
d96b37c0a   Omar Sandoval   blk-mq: move tags...
494
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
495
  	struct blk_mq_hw_ctx *hctx = data;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
496
  	struct request_queue *q = hctx->queue;
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
497
  	int res;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
498

8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
499
500
501
  	res = mutex_lock_interruptible(&q->sysfs_lock);
  	if (res)
  		goto out;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
502
503
504
  	if (hctx->sched_tags)
  		blk_mq_debugfs_tags_show(m, hctx->sched_tags);
  	mutex_unlock(&q->sysfs_lock);
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
505
506
  out:
  	return res;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
507
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
508
  static int hctx_sched_tags_bitmap_show(void *data, struct seq_file *m)
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
509
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
510
  	struct blk_mq_hw_ctx *hctx = data;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
511
  	struct request_queue *q = hctx->queue;
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
512
  	int res;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
513

8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
514
515
516
  	res = mutex_lock_interruptible(&q->sysfs_lock);
  	if (res)
  		goto out;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
517
518
519
  	if (hctx->sched_tags)
  		sbitmap_bitmap_show(&hctx->sched_tags->bitmap_tags.sb, m);
  	mutex_unlock(&q->sysfs_lock);
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
520
521
522
  
  out:
  	return res;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
523
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
524
  static int hctx_io_poll_show(void *data, struct seq_file *m)
be2154731   Omar Sandoval   blk-mq: move hctx...
525
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
526
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
527
528
529
530
531
532
533
534
535
  
  	seq_printf(m, "considered=%lu
  ", hctx->poll_considered);
  	seq_printf(m, "invoked=%lu
  ", hctx->poll_invoked);
  	seq_printf(m, "success=%lu
  ", hctx->poll_success);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
536
  static ssize_t hctx_io_poll_write(void *data, const char __user *buf,
be2154731   Omar Sandoval   blk-mq: move hctx...
537
538
  				  size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
539
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
540
541
542
543
  
  	hctx->poll_considered = hctx->poll_invoked = hctx->poll_success = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
544
  static int hctx_dispatched_show(void *data, struct seq_file *m)
be2154731   Omar Sandoval   blk-mq: move hctx...
545
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
546
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
  	int i;
  
  	seq_printf(m, "%8u\t%lu
  ", 0U, hctx->dispatched[0]);
  
  	for (i = 1; i < BLK_MQ_MAX_DISPATCH_ORDER - 1; i++) {
  		unsigned int d = 1U << (i - 1);
  
  		seq_printf(m, "%8u\t%lu
  ", d, hctx->dispatched[i]);
  	}
  
  	seq_printf(m, "%8u+\t%lu
  ", 1U << (i - 1), hctx->dispatched[i]);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
563
  static ssize_t hctx_dispatched_write(void *data, const char __user *buf,
be2154731   Omar Sandoval   blk-mq: move hctx...
564
565
  				     size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
566
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
567
568
569
570
571
572
  	int i;
  
  	for (i = 0; i < BLK_MQ_MAX_DISPATCH_ORDER; i++)
  		hctx->dispatched[i] = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
573
  static int hctx_queued_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
574
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
575
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
576
577
578
579
580
  
  	seq_printf(m, "%lu
  ", hctx->queued);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
581
  static ssize_t hctx_queued_write(void *data, const char __user *buf,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
582
583
  				 size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
584
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
585
586
587
588
  
  	hctx->queued = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
589
  static int hctx_run_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
590
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
591
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
592
593
594
595
596
  
  	seq_printf(m, "%lu
  ", hctx->run);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
597
598
  static ssize_t hctx_run_write(void *data, const char __user *buf, size_t count,
  			      loff_t *ppos)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
599
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
600
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
601
602
603
604
  
  	hctx->run = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
605
  static int hctx_active_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
606
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
607
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
608
609
610
611
612
  
  	seq_printf(m, "%d
  ", atomic_read(&hctx->nr_active));
  	return 0;
  }
6e7687173   Ming Lei   blk-mq: dequeue r...
613
614
615
616
617
618
619
620
  static int hctx_dispatch_busy_show(void *data, struct seq_file *m)
  {
  	struct blk_mq_hw_ctx *hctx = data;
  
  	seq_printf(m, "%u
  ", hctx->dispatch_busy);
  	return 0;
  }
c16d6b5a9   Ming Lei   blk-mq: fix dispa...
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
  #define CTX_RQ_SEQ_OPS(name, type)					\
  static void *ctx_##name##_rq_list_start(struct seq_file *m, loff_t *pos) \
  	__acquires(&ctx->lock)						\
  {									\
  	struct blk_mq_ctx *ctx = m->private;				\
  									\
  	spin_lock(&ctx->lock);						\
  	return seq_list_start(&ctx->rq_lists[type], *pos);		\
  }									\
  									\
  static void *ctx_##name##_rq_list_next(struct seq_file *m, void *v,	\
  				     loff_t *pos)			\
  {									\
  	struct blk_mq_ctx *ctx = m->private;				\
  									\
  	return seq_list_next(v, &ctx->rq_lists[type], pos);		\
  }									\
  									\
  static void ctx_##name##_rq_list_stop(struct seq_file *m, void *v)	\
  	__releases(&ctx->lock)						\
  {									\
  	struct blk_mq_ctx *ctx = m->private;				\
  									\
  	spin_unlock(&ctx->lock);					\
  }									\
  									\
  static const struct seq_operations ctx_##name##_rq_list_seq_ops = {	\
  	.start	= ctx_##name##_rq_list_start,				\
  	.next	= ctx_##name##_rq_list_next,				\
  	.stop	= ctx_##name##_rq_list_stop,				\
  	.show	= blk_mq_debugfs_rq_show,				\
  }
  
  CTX_RQ_SEQ_OPS(default, HCTX_TYPE_DEFAULT);
  CTX_RQ_SEQ_OPS(read, HCTX_TYPE_READ);
  CTX_RQ_SEQ_OPS(poll, HCTX_TYPE_POLL);
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
657

f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
658
  static int ctx_dispatched_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
659
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
660
  	struct blk_mq_ctx *ctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
661
662
663
664
665
  
  	seq_printf(m, "%lu %lu
  ", ctx->rq_dispatched[1], ctx->rq_dispatched[0]);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
666
  static ssize_t ctx_dispatched_write(void *data, const char __user *buf,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
667
668
  				    size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
669
  	struct blk_mq_ctx *ctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
670
671
672
673
  
  	ctx->rq_dispatched[0] = ctx->rq_dispatched[1] = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
674
  static int ctx_merged_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
675
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
676
  	struct blk_mq_ctx *ctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
677
678
679
680
681
  
  	seq_printf(m, "%lu
  ", ctx->rq_merged);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
682
683
  static ssize_t ctx_merged_write(void *data, const char __user *buf,
  				size_t count, loff_t *ppos)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
684
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
685
  	struct blk_mq_ctx *ctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
686
687
688
689
  
  	ctx->rq_merged = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
690
  static int ctx_completed_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
691
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
692
  	struct blk_mq_ctx *ctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
693
694
695
696
697
  
  	seq_printf(m, "%lu %lu
  ", ctx->rq_completed[1], ctx->rq_completed[0]);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
698
699
  static ssize_t ctx_completed_write(void *data, const char __user *buf,
  				   size_t count, loff_t *ppos)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
700
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
701
702
703
704
  	struct blk_mq_ctx *ctx = data;
  
  	ctx->rq_completed[0] = ctx->rq_completed[1] = 0;
  	return count;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
705
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
706
707
708
709
710
711
712
713
714
715
  static int blk_mq_debugfs_show(struct seq_file *m, void *v)
  {
  	const struct blk_mq_debugfs_attr *attr = m->private;
  	void *data = d_inode(m->file->f_path.dentry->d_parent)->i_private;
  
  	return attr->show(data, m);
  }
  
  static ssize_t blk_mq_debugfs_write(struct file *file, const char __user *buf,
  				    size_t count, loff_t *ppos)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
716
717
  {
  	struct seq_file *m = file->private_data;
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
718
719
  	const struct blk_mq_debugfs_attr *attr = m->private;
  	void *data = d_inode(file->f_path.dentry->d_parent)->i_private;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
720

6b136a24b   Eryu Guan   blk-mq-debugfs: d...
721
722
723
724
725
  	/*
  	 * Attributes that only implement .seq_ops are read-only and 'attr' is
  	 * the same with 'data' in this case.
  	 */
  	if (attr == data || !attr->write)
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
  		return -EPERM;
  
  	return attr->write(data, buf, count, ppos);
  }
  
  static int blk_mq_debugfs_open(struct inode *inode, struct file *file)
  {
  	const struct blk_mq_debugfs_attr *attr = inode->i_private;
  	void *data = d_inode(file->f_path.dentry->d_parent)->i_private;
  	struct seq_file *m;
  	int ret;
  
  	if (attr->seq_ops) {
  		ret = seq_open(file, attr->seq_ops);
  		if (!ret) {
  			m = file->private_data;
  			m->private = data;
  		}
  		return ret;
  	}
  
  	if (WARN_ON_ONCE(!attr->show))
  		return -EPERM;
  
  	return single_open(file, blk_mq_debugfs_show, inode->i_private);
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
751
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
752
753
754
755
756
757
  static int blk_mq_debugfs_release(struct inode *inode, struct file *file)
  {
  	const struct blk_mq_debugfs_attr *attr = inode->i_private;
  
  	if (attr->show)
  		return single_release(inode, file);
ee1e03598   Chaitanya Kulkarni   block: get rid of...
758
759
  
  	return seq_release(inode, file);
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
760
  }
f84659339   Bart Van Assche   blk-mq-debugfs: D...
761
  static const struct file_operations blk_mq_debugfs_fops = {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
762
  	.open		= blk_mq_debugfs_open,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
763
  	.read		= seq_read,
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
764
  	.write		= blk_mq_debugfs_write,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
765
  	.llseek		= seq_lseek,
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
766
  	.release	= blk_mq_debugfs_release,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
767
  };
07e4fead4   Omar Sandoval   blk-mq: create de...
768
  static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
769
770
771
  	{"state", 0400, hctx_state_show},
  	{"flags", 0400, hctx_flags_show},
  	{"dispatch", 0400, .seq_ops = &hctx_dispatch_seq_ops},
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
772
  	{"busy", 0400, hctx_busy_show},
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
773
774
775
776
777
778
779
780
781
782
  	{"ctx_map", 0400, hctx_ctx_map_show},
  	{"tags", 0400, hctx_tags_show},
  	{"tags_bitmap", 0400, hctx_tags_bitmap_show},
  	{"sched_tags", 0400, hctx_sched_tags_show},
  	{"sched_tags_bitmap", 0400, hctx_sched_tags_bitmap_show},
  	{"io_poll", 0600, hctx_io_poll_show, hctx_io_poll_write},
  	{"dispatched", 0600, hctx_dispatched_show, hctx_dispatched_write},
  	{"queued", 0600, hctx_queued_show, hctx_queued_write},
  	{"run", 0600, hctx_run_show, hctx_run_write},
  	{"active", 0400, hctx_active_show},
6e7687173   Ming Lei   blk-mq: dequeue r...
783
  	{"dispatch_busy", 0400, hctx_dispatch_busy_show},
346fc1089   Ming Lei   blk-mq: export hc...
784
  	{"type", 0400, hctx_type_show},
72f2f8f69   Bart Van Assche   blk-mq-debug: Int...
785
  	{},
07e4fead4   Omar Sandoval   blk-mq: create de...
786
787
788
  };
  
  static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
c16d6b5a9   Ming Lei   blk-mq: fix dispa...
789
790
791
  	{"default_rq_list", 0400, .seq_ops = &ctx_default_rq_list_seq_ops},
  	{"read_rq_list", 0400, .seq_ops = &ctx_read_rq_list_seq_ops},
  	{"poll_rq_list", 0400, .seq_ops = &ctx_poll_rq_list_seq_ops},
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
792
793
794
  	{"dispatched", 0600, ctx_dispatched_show, ctx_dispatched_write},
  	{"merged", 0600, ctx_merged_show, ctx_merged_write},
  	{"completed", 0600, ctx_completed_show, ctx_completed_write},
72f2f8f69   Bart Van Assche   blk-mq-debug: Int...
795
  	{},
07e4fead4   Omar Sandoval   blk-mq: create de...
796
  };
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
797
  static void debugfs_create_files(struct dentry *parent, void *data,
9c1051aac   Omar Sandoval   blk-mq: untangle ...
798
799
  				 const struct blk_mq_debugfs_attr *attr)
  {
36991ca68   Greg Kroah-Hartman   blk-mq: protect d...
800
  	if (IS_ERR_OR_NULL(parent))
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
801
  		return;
36991ca68   Greg Kroah-Hartman   blk-mq: protect d...
802

9c1051aac   Omar Sandoval   blk-mq: untangle ...
803
  	d_inode(parent)->i_private = data;
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
804
805
806
  	for (; attr->name; attr++)
  		debugfs_create_file(attr->name, attr->mode, parent,
  				    (void *)attr, &blk_mq_debugfs_fops);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
807
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
808
  void blk_mq_debugfs_register(struct request_queue *q)
07e4fead4   Omar Sandoval   blk-mq: create de...
809
  {
9c1051aac   Omar Sandoval   blk-mq: untangle ...
810
811
  	struct blk_mq_hw_ctx *hctx;
  	int i;
4c9e4019f   Bart Van Assche   blk-mq: Let blk_m...
812
813
  	q->debugfs_dir = debugfs_create_dir(kobject_name(q->kobj.parent),
  					    blk_debugfs_root);
07e4fead4   Omar Sandoval   blk-mq: create de...
814

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
815
  	debugfs_create_files(q->debugfs_dir, q, blk_mq_debugfs_queue_attrs);
07e4fead4   Omar Sandoval   blk-mq: create de...
816

9c1051aac   Omar Sandoval   blk-mq: untangle ...
817
  	/*
70e62f4ba   Omar Sandoval   blk-mq-debugfs: f...
818
  	 * blk_mq_init_sched() attempted to do this already, but q->debugfs_dir
9c1051aac   Omar Sandoval   blk-mq: untangle ...
819
820
821
  	 * didn't exist yet (because we don't know what to name the directory
  	 * until the queue is registered to a gendisk).
  	 */
70e62f4ba   Omar Sandoval   blk-mq-debugfs: f...
822
823
824
825
  	if (q->elevator && !q->sched_debugfs_dir)
  		blk_mq_debugfs_register_sched(q);
  
  	/* Similarly, blk_mq_init_hctx() couldn't do this previously. */
9c1051aac   Omar Sandoval   blk-mq: untangle ...
826
  	queue_for_each_hw_ctx(q, hctx, i) {
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
827
828
829
830
  		if (!hctx->debugfs_dir)
  			blk_mq_debugfs_register_hctx(q, hctx);
  		if (q->elevator && !hctx->sched_debugfs_dir)
  			blk_mq_debugfs_register_sched_hctx(q, hctx);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
831
  	}
cc56694f1   Ming Lei   blk-mq-debugfs: s...
832
833
834
835
836
837
838
839
  	if (q->rq_qos) {
  		struct rq_qos *rqos = q->rq_qos;
  
  		while (rqos) {
  			blk_mq_debugfs_register_rqos(rqos);
  			rqos = rqos->next;
  		}
  	}
07e4fead4   Omar Sandoval   blk-mq: create de...
840
841
842
843
844
  }
  
  void blk_mq_debugfs_unregister(struct request_queue *q)
  {
  	debugfs_remove_recursive(q->debugfs_dir);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
845
  	q->sched_debugfs_dir = NULL;
07e4fead4   Omar Sandoval   blk-mq: create de...
846
847
  	q->debugfs_dir = NULL;
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
848
849
  static void blk_mq_debugfs_register_ctx(struct blk_mq_hw_ctx *hctx,
  					struct blk_mq_ctx *ctx)
07e4fead4   Omar Sandoval   blk-mq: create de...
850
851
852
  {
  	struct dentry *ctx_dir;
  	char name[20];
07e4fead4   Omar Sandoval   blk-mq: create de...
853
854
  
  	snprintf(name, sizeof(name), "cpu%u", ctx->cpu);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
855
  	ctx_dir = debugfs_create_dir(name, hctx->debugfs_dir);
07e4fead4   Omar Sandoval   blk-mq: create de...
856

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
857
  	debugfs_create_files(ctx_dir, ctx, blk_mq_debugfs_ctx_attrs);
07e4fead4   Omar Sandoval   blk-mq: create de...
858
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
859
860
  void blk_mq_debugfs_register_hctx(struct request_queue *q,
  				  struct blk_mq_hw_ctx *hctx)
07e4fead4   Omar Sandoval   blk-mq: create de...
861
862
  {
  	struct blk_mq_ctx *ctx;
07e4fead4   Omar Sandoval   blk-mq: create de...
863
864
  	char name[20];
  	int i;
88aabbd7e   Omar Sandoval   blk-mq-debugfs: r...
865
  	snprintf(name, sizeof(name), "hctx%u", hctx->queue_num);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
866
  	hctx->debugfs_dir = debugfs_create_dir(name, q->debugfs_dir);
07e4fead4   Omar Sandoval   blk-mq: create de...
867

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
868
  	debugfs_create_files(hctx->debugfs_dir, hctx, blk_mq_debugfs_hctx_attrs);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
869

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
870
871
  	hctx_for_each_ctx(hctx, ctx, i)
  		blk_mq_debugfs_register_ctx(hctx, ctx);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
872
873
874
875
876
  }
  
  void blk_mq_debugfs_unregister_hctx(struct blk_mq_hw_ctx *hctx)
  {
  	debugfs_remove_recursive(hctx->debugfs_dir);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
877
  	hctx->sched_debugfs_dir = NULL;
9c1051aac   Omar Sandoval   blk-mq: untangle ...
878
  	hctx->debugfs_dir = NULL;
07e4fead4   Omar Sandoval   blk-mq: create de...
879
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
880
  void blk_mq_debugfs_register_hctxs(struct request_queue *q)
07e4fead4   Omar Sandoval   blk-mq: create de...
881
882
883
  {
  	struct blk_mq_hw_ctx *hctx;
  	int i;
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
884
885
  	queue_for_each_hw_ctx(q, hctx, i)
  		blk_mq_debugfs_register_hctx(q, hctx);
07e4fead4   Omar Sandoval   blk-mq: create de...
886
  }
9c1051aac   Omar Sandoval   blk-mq: untangle ...
887
  void blk_mq_debugfs_unregister_hctxs(struct request_queue *q)
07e4fead4   Omar Sandoval   blk-mq: create de...
888
  {
9c1051aac   Omar Sandoval   blk-mq: untangle ...
889
890
891
892
893
  	struct blk_mq_hw_ctx *hctx;
  	int i;
  
  	queue_for_each_hw_ctx(q, hctx, i)
  		blk_mq_debugfs_unregister_hctx(hctx);
07e4fead4   Omar Sandoval   blk-mq: create de...
894
  }
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
895

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
896
  void blk_mq_debugfs_register_sched(struct request_queue *q)
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
897
898
  {
  	struct elevator_type *e = q->elevator->type;
7e41c3c9b   Greg Kroah-Hartman   blk-mq: fix up pl...
899
900
901
902
903
904
  	/*
  	 * If the parent directory has not been created yet, return, we will be
  	 * called again later on and the directory/files will be created then.
  	 */
  	if (!q->debugfs_dir)
  		return;
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
905
  	if (!e->queue_debugfs_attrs)
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
906
  		return;
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
907
908
  
  	q->sched_debugfs_dir = debugfs_create_dir("sched", q->debugfs_dir);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
909

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
910
  	debugfs_create_files(q->sched_debugfs_dir, q, e->queue_debugfs_attrs);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
911
912
913
914
915
916
917
  }
  
  void blk_mq_debugfs_unregister_sched(struct request_queue *q)
  {
  	debugfs_remove_recursive(q->sched_debugfs_dir);
  	q->sched_debugfs_dir = NULL;
  }
cc56694f1   Ming Lei   blk-mq-debugfs: s...
918
919
920
921
922
  void blk_mq_debugfs_unregister_rqos(struct rq_qos *rqos)
  {
  	debugfs_remove_recursive(rqos->debugfs_dir);
  	rqos->debugfs_dir = NULL;
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
923
  void blk_mq_debugfs_register_rqos(struct rq_qos *rqos)
cc56694f1   Ming Lei   blk-mq-debugfs: s...
924
925
926
  {
  	struct request_queue *q = rqos->q;
  	const char *dir_name = rq_qos_id_to_name(rqos->id);
cc56694f1   Ming Lei   blk-mq-debugfs: s...
927
  	if (rqos->debugfs_dir || !rqos->ops->debugfs_attrs)
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
928
  		return;
cc56694f1   Ming Lei   blk-mq-debugfs: s...
929

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
930
  	if (!q->rqos_debugfs_dir)
cc56694f1   Ming Lei   blk-mq-debugfs: s...
931
932
  		q->rqos_debugfs_dir = debugfs_create_dir("rqos",
  							 q->debugfs_dir);
cc56694f1   Ming Lei   blk-mq-debugfs: s...
933
934
935
  
  	rqos->debugfs_dir = debugfs_create_dir(dir_name,
  					       rqos->q->rqos_debugfs_dir);
cc56694f1   Ming Lei   blk-mq-debugfs: s...
936

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
937
  	debugfs_create_files(rqos->debugfs_dir, rqos, rqos->ops->debugfs_attrs);
cc56694f1   Ming Lei   blk-mq-debugfs: s...
938
939
940
941
942
943
944
  }
  
  void blk_mq_debugfs_unregister_queue_rqos(struct request_queue *q)
  {
  	debugfs_remove_recursive(q->rqos_debugfs_dir);
  	q->rqos_debugfs_dir = NULL;
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
945
946
  void blk_mq_debugfs_register_sched_hctx(struct request_queue *q,
  					struct blk_mq_hw_ctx *hctx)
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
947
948
  {
  	struct elevator_type *e = q->elevator->type;
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
949
  	if (!e->hctx_debugfs_attrs)
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
950
  		return;
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
951
952
953
  
  	hctx->sched_debugfs_dir = debugfs_create_dir("sched",
  						     hctx->debugfs_dir);
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
954
955
  	debugfs_create_files(hctx->sched_debugfs_dir, hctx,
  			     e->hctx_debugfs_attrs);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
956
957
958
959
960
961
962
  }
  
  void blk_mq_debugfs_unregister_sched_hctx(struct blk_mq_hw_ctx *hctx)
  {
  	debugfs_remove_recursive(hctx->sched_debugfs_dir);
  	hctx->sched_debugfs_dir = NULL;
  }