Blame view

block/blk-mq-debugfs.c 24.4 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),
91d68905a   Bart Van Assche   blk-mq: Export qu...
126
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
127
  #undef QUEUE_FLAG_NAME
91d68905a   Bart Van Assche   blk-mq: Export qu...
128

f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
129
  static int queue_state_show(void *data, struct seq_file *m)
91d68905a   Bart Van Assche   blk-mq: Export qu...
130
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
131
  	struct request_queue *q = data;
91d68905a   Bart Van Assche   blk-mq: Export qu...
132
133
134
  
  	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_...
135
136
  	seq_puts(m, "
  ");
91d68905a   Bart Van Assche   blk-mq: Export qu...
137
138
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
139
140
  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...
141
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
142
  	struct request_queue *q = data;
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
143
  	char opbuf[16] = { }, *op;
91d68905a   Bart Van Assche   blk-mq: Export qu...
144

18d4d7d05   Bart Van Assche   blk-mq: Do not in...
145
146
147
148
149
150
151
  	/*
  	 * 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...
152
  	if (count >= sizeof(opbuf)) {
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
153
154
155
156
  		pr_err("%s: operation too long
  ", __func__);
  		goto inval;
  	}
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
157
  	if (copy_from_user(opbuf, buf, count))
91d68905a   Bart Van Assche   blk-mq: Export qu...
158
  		return -EFAULT;
71b90511c   Omar Sandoval   blk-mq-debugfs: d...
159
  	op = strstrip(opbuf);
91d68905a   Bart Van Assche   blk-mq: Export qu...
160
161
162
163
  	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...
164
165
  	} else if (strcmp(op, "kick") == 0) {
  		blk_mq_kick_requeue_list(q);
91d68905a   Bart Van Assche   blk-mq: Export qu...
166
  	} else {
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
167
168
169
  		pr_err("%s: unsupported operation '%s'
  ", __func__, op);
  inval:
edea55abb   Bart Van Assche   blk-mq-debugfs: A...
170
171
  		pr_err("%s: use 'run', 'start' or 'kick'
  ", __func__);
91d68905a   Bart Van Assche   blk-mq: Export qu...
172
173
  		return -EINVAL;
  	}
c7e4145ae   Omar Sandoval   blk-mq-debugfs: e...
174
  	return count;
91d68905a   Bart Van Assche   blk-mq: Export qu...
175
  }
f793dfd3f   Jens Axboe   blk-mq: expose wr...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
  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...
199
200
201
  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...
202
  	{ "pm_only", 0600, queue_pm_only_show, NULL },
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
203
204
  	{ "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...
205
  	{ "zone_wlock", 0400, queue_zone_wlock_show, NULL },
1209cb7fa   Bart Van Assche   blk-mq-debugfs: R...
206
207
  	{ },
  };
34dbad5d2   Omar Sandoval   blk-stat: convert...
208

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

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

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

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

f5c0b0910   Bart Van Assche   blk-mq: Show symb...
247
248
249
250
251
252
253
254
255
256
  	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_...
257
258
  	seq_puts(m, "
  ");
9abb2ad21   Omar Sandoval   blk-mq: add hctx-...
259
260
  	return 0;
  }
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
261
  #define CMD_FLAG_NAME(name) [__REQ_##name] = #name
8658dca8b   Bart Van Assche   blk-mq: Show oper...
262
  static const char *const cmd_flag_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
263
264
265
266
267
268
269
270
271
272
273
274
275
  	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...
276
  	CMD_FLAG_NAME(NOWAIT),
1c26010c5   Jianchao Wang   blk-mq: fix the c...
277
278
  	CMD_FLAG_NAME(NOUNMAP),
  	CMD_FLAG_NAME(HIPRI),
8658dca8b   Bart Van Assche   blk-mq: Show oper...
279
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
280
  #undef CMD_FLAG_NAME
8658dca8b   Bart Van Assche   blk-mq: Show oper...
281

1a435111f   Omar Sandoval   blk-mq-debugfs: c...
282
  #define RQF_NAME(name) [ilog2((__force u32)RQF_##name)] = #name
8658dca8b   Bart Van Assche   blk-mq: Show oper...
283
  static const char *const rqf_name[] = {
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
284
  	RQF_NAME(SORTED),
85ba3effc   Jens Axboe   blk-mq: add missi...
285
  	RQF_NAME(STARTED),
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
  	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...
302
  	RQF_NAME(ZONE_WRITE_LOCKED),
76a86f9d0   Jens Axboe   block: remove REQ...
303
  	RQF_NAME(MQ_POLL_SLEPT),
8658dca8b   Bart Van Assche   blk-mq: Show oper...
304
  };
1a435111f   Omar Sandoval   blk-mq-debugfs: c...
305
  #undef RQF_NAME
8658dca8b   Bart Van Assche   blk-mq: Show oper...
306

ec6dcf63c   Bart Van Assche   blk-mq-debugfs: S...
307
308
309
310
311
312
313
314
  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...
315
  	if (WARN_ON_ONCE((unsigned int)rq_state >=
ec6dcf63c   Bart Van Assche   blk-mq-debugfs: S...
316
317
318
319
  			 ARRAY_SIZE(blk_mq_rq_state_name_array)))
  		return "(?)";
  	return blk_mq_rq_state_name_array[rq_state];
  }
daaadb3e9   Omar Sandoval   mq-deadline: add ...
320
  int __blk_mq_debugfs_rq_show(struct seq_file *m, struct request *rq)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
321
  {
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
322
  	const struct blk_mq_ops *const mq_ops = rq->q->mq_ops;
f9bc64a0f   Chaitanya Kulkarni   block: use req_op...
323
  	const unsigned int op = req_op(rq);
874c893bf   Chaitanya Kulkarni   block: use blk_op...
324
  	const char *op_str = blk_op_str(op);
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
325

8658dca8b   Bart Van Assche   blk-mq: Show oper...
326
  	seq_printf(m, "%p {.op=", rq);
874c893bf   Chaitanya Kulkarni   block: use blk_op...
327
  	if (strcmp(op_str, "UNKNOWN") == 0)
3f6d385f8   Chaitanya Kulkarni   block: use right ...
328
  		seq_printf(m, "%u", op);
8658dca8b   Bart Van Assche   blk-mq: Show oper...
329
  	else
874c893bf   Chaitanya Kulkarni   block: use blk_op...
330
  		seq_printf(m, "%s", op_str);
8658dca8b   Bart Van Assche   blk-mq: Show oper...
331
332
333
334
335
336
  	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...
337
  	seq_printf(m, ", .state=%s", blk_mq_rq_state_name(blk_mq_rq_state(rq)));
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
338
  	seq_printf(m, ", .tag=%d, .internal_tag=%d", rq->tag,
8658dca8b   Bart Van Assche   blk-mq: Show oper...
339
  		   rq->internal_tag);
2836ee4b1   Bart Van Assche   blk-mq: Add blk_m...
340
341
342
343
  	if (mq_ops->show_rq)
  		mq_ops->show_rq(m, rq);
  	seq_puts(m, "}
  ");
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
344
345
  	return 0;
  }
daaadb3e9   Omar Sandoval   mq-deadline: add ...
346
347
348
349
350
351
  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...
352
  EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show);
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
353
354
  
  static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos)
f3bcb0e60   Bart Van Assche   blk-mq-debugfs: A...
355
  	__acquires(&hctx->lock)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  {
  	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...
371
  	__releases(&hctx->lock)
950cd7e9f   Omar Sandoval   blk-mq: move hctx...
372
373
374
375
376
377
378
379
380
381
382
383
  {
  	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...
384
385
386
387
388
389
390
  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...
391
392
   * 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...
393
   */
7baa85727   Jens Axboe   blk-mq-tag: chang...
394
  static bool hctx_show_busy_rq(struct request *rq, void *data, bool reserved)
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
395
396
  {
  	const struct show_busy_params *params = data;
ea4f995ee   Jens Axboe   blk-mq: cache req...
397
  	if (rq->mq_hctx == params->hctx)
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
398
399
  		__blk_mq_debugfs_rq_show(params->m,
  					 list_entry_rq(&rq->queuelist));
7baa85727   Jens Axboe   blk-mq-tag: chang...
400
401
  
  	return true;
2720bab50   Bart Van Assche   blk-mq-debugfs: S...
402
403
404
405
406
407
408
409
410
411
412
413
  }
  
  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...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
  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...
429
  static int hctx_ctx_map_show(void *data, struct seq_file *m)
0bfa5288a   Omar Sandoval   blk-mq: export so...
430
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
431
  	struct blk_mq_hw_ctx *hctx = data;
0bfa5288a   Omar Sandoval   blk-mq: export so...
432
433
434
435
  
  	sbitmap_bitmap_show(&hctx->ctx_map, m);
  	return 0;
  }
d96b37c0a   Omar Sandoval   blk-mq: move tags...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  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...
459
  static int hctx_tags_show(void *data, struct seq_file *m)
d96b37c0a   Omar Sandoval   blk-mq: move tags...
460
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
461
  	struct blk_mq_hw_ctx *hctx = data;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
462
  	struct request_queue *q = hctx->queue;
8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
463
  	int res;
d96b37c0a   Omar Sandoval   blk-mq: move tags...
464

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

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

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

8c0f14eab   Bart Van Assche   blk-mq-debug: Mak...
511
512
513
  	res = mutex_lock_interruptible(&q->sysfs_lock);
  	if (res)
  		goto out;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
514
515
516
  	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...
517
518
519
  
  out:
  	return res;
d7e3621ad   Omar Sandoval   blk-mq: add tags ...
520
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
521
  static int hctx_io_poll_show(void *data, struct seq_file *m)
be2154731   Omar Sandoval   blk-mq: move hctx...
522
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
523
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
524
525
526
527
528
529
530
531
532
  
  	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...
533
  static ssize_t hctx_io_poll_write(void *data, const char __user *buf,
be2154731   Omar Sandoval   blk-mq: move hctx...
534
535
  				  size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
536
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
537
538
539
540
  
  	hctx->poll_considered = hctx->poll_invoked = hctx->poll_success = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
541
  static int hctx_dispatched_show(void *data, struct seq_file *m)
be2154731   Omar Sandoval   blk-mq: move hctx...
542
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
543
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
  	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...
560
  static ssize_t hctx_dispatched_write(void *data, const char __user *buf,
be2154731   Omar Sandoval   blk-mq: move hctx...
561
562
  				     size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
563
  	struct blk_mq_hw_ctx *hctx = data;
be2154731   Omar Sandoval   blk-mq: move hctx...
564
565
566
567
568
569
  	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...
570
  static int hctx_queued_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
571
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
572
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
573
574
575
576
577
  
  	seq_printf(m, "%lu
  ", hctx->queued);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
578
  static ssize_t hctx_queued_write(void *data, const char __user *buf,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
579
580
  				 size_t count, loff_t *ppos)
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
581
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
582
583
584
585
  
  	hctx->queued = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
586
  static int hctx_run_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
587
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
588
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
589
590
591
592
593
  
  	seq_printf(m, "%lu
  ", hctx->run);
  	return 0;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
594
595
  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...
596
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
597
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
598
599
600
601
  
  	hctx->run = 0;
  	return count;
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
602
  static int hctx_active_show(void *data, struct seq_file *m)
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
603
  {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
604
  	struct blk_mq_hw_ctx *hctx = data;
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
605
606
607
608
609
  
  	seq_printf(m, "%d
  ", atomic_read(&hctx->nr_active));
  	return 0;
  }
6e7687173   Ming Lei   blk-mq: dequeue r...
610
611
612
613
614
615
616
617
  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...
618
619
620
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
  #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...
654

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

6b136a24b   Eryu Guan   blk-mq-debugfs: d...
718
719
720
721
722
  	/*
  	 * 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...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
  		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...
748
  }
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
749
750
751
752
753
754
  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...
755
756
  
  	return seq_release(inode, file);
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
757
  }
f84659339   Bart Van Assche   blk-mq-debugfs: D...
758
  static const struct file_operations blk_mq_debugfs_fops = {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
759
  	.open		= blk_mq_debugfs_open,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
760
  	.read		= seq_read,
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
761
  	.write		= blk_mq_debugfs_write,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
762
  	.llseek		= seq_lseek,
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
763
  	.release	= blk_mq_debugfs_release,
4a46f05eb   Omar Sandoval   blk-mq: move hctx...
764
  };
07e4fead4   Omar Sandoval   blk-mq: create de...
765
  static const struct blk_mq_debugfs_attr blk_mq_debugfs_hctx_attrs[] = {
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
766
767
768
  	{"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...
769
  	{"busy", 0400, hctx_busy_show},
f57de23ac   Omar Sandoval   blk-mq-debugfs: g...
770
771
772
773
774
775
776
777
778
779
  	{"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...
780
  	{"dispatch_busy", 0400, hctx_dispatch_busy_show},
346fc1089   Ming Lei   blk-mq: export hc...
781
  	{"type", 0400, hctx_type_show},
72f2f8f69   Bart Van Assche   blk-mq-debug: Int...
782
  	{},
07e4fead4   Omar Sandoval   blk-mq: create de...
783
784
785
  };
  
  static const struct blk_mq_debugfs_attr blk_mq_debugfs_ctx_attrs[] = {
c16d6b5a9   Ming Lei   blk-mq: fix dispa...
786
787
788
  	{"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...
789
790
791
  	{"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...
792
  	{},
07e4fead4   Omar Sandoval   blk-mq: create de...
793
  };
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
794
  static void debugfs_create_files(struct dentry *parent, void *data,
9c1051aac   Omar Sandoval   blk-mq: untangle ...
795
796
  				 const struct blk_mq_debugfs_attr *attr)
  {
36991ca68   Greg Kroah-Hartman   blk-mq: protect d...
797
  	if (IS_ERR_OR_NULL(parent))
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
798
  		return;
36991ca68   Greg Kroah-Hartman   blk-mq: protect d...
799

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

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

9c1051aac   Omar Sandoval   blk-mq: untangle ...
814
  	/*
70e62f4ba   Omar Sandoval   blk-mq-debugfs: f...
815
  	 * blk_mq_init_sched() attempted to do this already, but q->debugfs_dir
9c1051aac   Omar Sandoval   blk-mq: untangle ...
816
817
818
  	 * 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...
819
820
821
822
  	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 ...
823
  	queue_for_each_hw_ctx(q, hctx, i) {
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
824
825
826
827
  		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 ...
828
  	}
cc56694f1   Ming Lei   blk-mq-debugfs: s...
829
830
831
832
833
834
835
836
  	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...
837
838
839
840
841
  }
  
  void blk_mq_debugfs_unregister(struct request_queue *q)
  {
  	debugfs_remove_recursive(q->debugfs_dir);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
842
  	q->sched_debugfs_dir = NULL;
07e4fead4   Omar Sandoval   blk-mq: create de...
843
844
  	q->debugfs_dir = NULL;
  }
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
845
846
  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...
847
848
849
  {
  	struct dentry *ctx_dir;
  	char name[20];
07e4fead4   Omar Sandoval   blk-mq: create de...
850
851
  
  	snprintf(name, sizeof(name), "cpu%u", ctx->cpu);
9c1051aac   Omar Sandoval   blk-mq: untangle ...
852
  	ctx_dir = debugfs_create_dir(name, hctx->debugfs_dir);
07e4fead4   Omar Sandoval   blk-mq: create de...
853

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

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

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

6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
893
  void blk_mq_debugfs_register_sched(struct request_queue *q)
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
894
895
  {
  	struct elevator_type *e = q->elevator->type;
7e41c3c9b   Greg Kroah-Hartman   blk-mq: fix up pl...
896
897
898
899
900
901
  	/*
  	 * 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...
902
  	if (!e->queue_debugfs_attrs)
6cfc0081b   Greg Kroah-Hartman   blk-mq: no need t...
903
  		return;
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
904
905
  
  	q->sched_debugfs_dir = debugfs_create_dir("sched", q->debugfs_dir);
d332ce091   Omar Sandoval   blk-mq-debugfs: a...
906

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

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

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