Blame view

kernel/trace/blktrace.c 46.3 KB
91c1e6ba3   Steven Rostedt (VMware)   blktrace: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0
2056a782f   Jens Axboe   [PATCH] Block que...
2
  /*
0fe234795   Jens Axboe   [PATCH] Update ax...
3
   * Copyright (C) 2006 Jens Axboe <axboe@kernel.dk>
2056a782f   Jens Axboe   [PATCH] Block que...
4
   *
2056a782f   Jens Axboe   [PATCH] Block que...
5
   */
2056a782f   Jens Axboe   [PATCH] Block que...
6
7
8
9
10
11
  #include <linux/kernel.h>
  #include <linux/blkdev.h>
  #include <linux/blktrace_api.h>
  #include <linux/percpu.h>
  #include <linux/init.h>
  #include <linux/mutex.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
12
  #include <linux/slab.h>
2056a782f   Jens Axboe   [PATCH] Block que...
13
  #include <linux/debugfs.h>
6e5fdeedc   Paul Gortmaker   kernel: Fix files...
14
  #include <linux/export.h>
be1c63411   Olaf Kirch   [PATCH] blktrace:...
15
  #include <linux/time.h>
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
16
  #include <linux/uaccess.h>
a404d5576   Jan Kara   blktrace: Send BL...
17
  #include <linux/list.h>
ca1136c99   Shaohua Li   blktrace: export ...
18
  #include <linux/blk-cgroup.h>
55782138e   Li Zefan   tracing/events: c...
19

18fbda91c   Omar Sandoval   block: use same b...
20
  #include "../../block/blk.h"
55782138e   Li Zefan   tracing/events: c...
21
  #include <trace/events/block.h>
2db270a80   Frederic Weisbecker   tracing/blktrace:...
22
  #include "trace_output.h"
2056a782f   Jens Axboe   [PATCH] Block que...
23

55782138e   Li Zefan   tracing/events: c...
24
  #ifdef CONFIG_BLK_DEV_IO_TRACE
2056a782f   Jens Axboe   [PATCH] Block que...
25
  static unsigned int blktrace_seq __read_mostly = 1;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
26
  static struct trace_array *blk_tr;
5006ea73f   Li Zefan   blktrace: make bl...
27
  static bool blk_tracer_enabled __read_mostly;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
28

a404d5576   Jan Kara   blktrace: Send BL...
29
30
  static LIST_HEAD(running_trace_list);
  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(running_trace_lock);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
31
  /* Select an alternative, minimalistic output than the original one */
ef18012b2   Steven Rostedt   tracing: remove f...
32
  #define TRACE_BLK_OPT_CLASSIC	0x1
ca1136c99   Shaohua Li   blktrace: export ...
33
  #define TRACE_BLK_OPT_CGROUP	0x2
69fd5c391   Shaohua Li   blktrace: add an ...
34
  #define TRACE_BLK_OPT_CGNAME	0x4
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
35
36
37
  
  static struct tracer_opt blk_tracer_opts[] = {
  	/* Default disable the minimalistic output */
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
38
  	{ TRACER_OPT(blk_classic, TRACE_BLK_OPT_CLASSIC) },
ca1136c99   Shaohua Li   blktrace: export ...
39
40
  #ifdef CONFIG_BLK_CGROUP
  	{ TRACER_OPT(blk_cgroup, TRACE_BLK_OPT_CGROUP) },
69fd5c391   Shaohua Li   blktrace: add an ...
41
  	{ TRACER_OPT(blk_cgname, TRACE_BLK_OPT_CGNAME) },
ca1136c99   Shaohua Li   blktrace: export ...
42
  #endif
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
43
44
45
46
47
48
49
  	{ }
  };
  
  static struct tracer_flags blk_tracer_flags = {
  	.val  = 0,
  	.opts = blk_tracer_opts,
  };
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
50
  /* Global reference count of probes */
a6da0024f   Jens Axboe   blktrace: fix unl...
51
52
  static DEFINE_MUTEX(blk_probe_mutex);
  static int blk_probes_ref;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
53

3c289ba7c   Li Zefan   blktrace: remove ...
54
  static void blk_register_tracepoints(void);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
55
  static void blk_unregister_tracepoints(void);
2056a782f   Jens Axboe   [PATCH] Block que...
56
  /*
be1c63411   Olaf Kirch   [PATCH] blktrace:...
57
58
   * Send out a notify message.
   */
a863055b1   Jens Axboe   [PATCH] blktrace:...
59
  static void trace_note(struct blk_trace *bt, pid_t pid, int action,
ca1136c99   Shaohua Li   blktrace: export ...
60
61
  		       const void *data, size_t len,
  		       union kernfs_node_id *cgid)
be1c63411   Olaf Kirch   [PATCH] blktrace:...
62
63
  {
  	struct blk_io_trace *t;
18cea4591   Li Zefan   blktrace: print o...
64
  	struct ring_buffer_event *event = NULL;
e77405ad8   Steven Rostedt   tracing: pass aro...
65
  	struct ring_buffer *buffer = NULL;
18cea4591   Li Zefan   blktrace: print o...
66
67
68
  	int pc = 0;
  	int cpu = smp_processor_id();
  	bool blk_tracer = blk_tracer_enabled;
ca1136c99   Shaohua Li   blktrace: export ...
69
  	ssize_t cgid_len = cgid ? sizeof(*cgid) : 0;
18cea4591   Li Zefan   blktrace: print o...
70
71
  
  	if (blk_tracer) {
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
72
  		buffer = blk_tr->trace_buffer.buffer;
18cea4591   Li Zefan   blktrace: print o...
73
  		pc = preempt_count();
e77405ad8   Steven Rostedt   tracing: pass aro...
74
  		event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
ca1136c99   Shaohua Li   blktrace: export ...
75
  						  sizeof(*t) + len + cgid_len,
18cea4591   Li Zefan   blktrace: print o...
76
77
78
79
80
81
  						  0, pc);
  		if (!event)
  			return;
  		t = ring_buffer_event_data(event);
  		goto record_it;
  	}
be1c63411   Olaf Kirch   [PATCH] blktrace:...
82

c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
83
84
  	if (!bt->rchan)
  		return;
ca1136c99   Shaohua Li   blktrace: export ...
85
  	t = relay_reserve(bt->rchan, sizeof(*t) + len + cgid_len);
d3d9d2a5e   Jens Axboe   [PATCH] blktrace:...
86
  	if (t) {
d3d9d2a5e   Jens Axboe   [PATCH] blktrace:...
87
  		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
2997c8c4a   Ingo Molnar   block: fix blktra...
88
  		t->time = ktime_to_ns(ktime_get());
18cea4591   Li Zefan   blktrace: print o...
89
  record_it:
d3d9d2a5e   Jens Axboe   [PATCH] blktrace:...
90
  		t->device = bt->dev;
ca1136c99   Shaohua Li   blktrace: export ...
91
  		t->action = action | (cgid ? __BLK_TN_CGROUP : 0);
d3d9d2a5e   Jens Axboe   [PATCH] blktrace:...
92
93
  		t->pid = pid;
  		t->cpu = cpu;
ca1136c99   Shaohua Li   blktrace: export ...
94
95
96
97
  		t->pdu_len = len + cgid_len;
  		if (cgid)
  			memcpy((void *)t + sizeof(*t), cgid, cgid_len);
  		memcpy((void *) t + sizeof(*t) + cgid_len, data, len);
18cea4591   Li Zefan   blktrace: print o...
98
99
  
  		if (blk_tracer)
b7f0c959e   Steven Rostedt (Red Hat)   tracing: Pass tra...
100
  			trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc);
d3d9d2a5e   Jens Axboe   [PATCH] blktrace:...
101
  	}
be1c63411   Olaf Kirch   [PATCH] blktrace:...
102
103
104
  }
  
  /*
2056a782f   Jens Axboe   [PATCH] Block que...
105
106
107
   * Send out a notify for this process, if we haven't done so since a trace
   * started
   */
a404d5576   Jan Kara   blktrace: Send BL...
108
  static void trace_note_tsk(struct task_struct *tsk)
2056a782f   Jens Axboe   [PATCH] Block que...
109
  {
a404d5576   Jan Kara   blktrace: Send BL...
110
111
  	unsigned long flags;
  	struct blk_trace *bt;
a863055b1   Jens Axboe   [PATCH] blktrace:...
112
  	tsk->btrace_seq = blktrace_seq;
a404d5576   Jan Kara   blktrace: Send BL...
113
114
115
  	spin_lock_irqsave(&running_trace_lock, flags);
  	list_for_each_entry(bt, &running_trace_list, running_list) {
  		trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm,
ca1136c99   Shaohua Li   blktrace: export ...
116
  			   sizeof(tsk->comm), NULL);
a404d5576   Jan Kara   blktrace: Send BL...
117
118
  	}
  	spin_unlock_irqrestore(&running_trace_lock, flags);
be1c63411   Olaf Kirch   [PATCH] blktrace:...
119
  }
2056a782f   Jens Axboe   [PATCH] Block que...
120

be1c63411   Olaf Kirch   [PATCH] blktrace:...
121
122
  static void trace_note_time(struct blk_trace *bt)
  {
59a37f8ba   Arnd Bergmann   blktrace: avoid u...
123
  	struct timespec64 now;
be1c63411   Olaf Kirch   [PATCH] blktrace:...
124
125
  	unsigned long flags;
  	u32 words[2];
59a37f8ba   Arnd Bergmann   blktrace: avoid u...
126
127
128
  	/* need to check user space to see if this breaks in y2038 or y2106 */
  	ktime_get_real_ts64(&now);
  	words[0] = (u32)now.tv_sec;
be1c63411   Olaf Kirch   [PATCH] blktrace:...
129
130
131
  	words[1] = now.tv_nsec;
  
  	local_irq_save(flags);
ca1136c99   Shaohua Li   blktrace: export ...
132
  	trace_note(bt, 0, BLK_TN_TIMESTAMP, words, sizeof(words), NULL);
be1c63411   Olaf Kirch   [PATCH] blktrace:...
133
  	local_irq_restore(flags);
2056a782f   Jens Axboe   [PATCH] Block que...
134
  }
35fe6d763   Shaohua Li   block: use standa...
135
136
  void __trace_note_message(struct blk_trace *bt, struct blkcg *blkcg,
  	const char *fmt, ...)
9d5f09a42   Alan D. Brunelle   Added in MESSAGE ...
137
138
139
  {
  	int n;
  	va_list args;
14a73f547   Carl Henrik Lunde   block: disable IR...
140
  	unsigned long flags;
64565911c   Jens Axboe   block: make blktr...
141
  	char *buf;
9d5f09a42   Alan D. Brunelle   Added in MESSAGE ...
142

18cea4591   Li Zefan   blktrace: print o...
143
144
  	if (unlikely(bt->trace_state != Blktrace_running &&
  		     !blk_tracer_enabled))
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
145
  		return;
490da40d8   Tao Ma   blktrace: Don't o...
146
147
148
149
150
151
  	/*
  	 * If the BLK_TC_NOTIFY action mask isn't set, don't send any note
  	 * message to the trace.
  	 */
  	if (!(bt->act_mask & BLK_TC_NOTIFY))
  		return;
14a73f547   Carl Henrik Lunde   block: disable IR...
152
  	local_irq_save(flags);
d8a0349c0   Shan Wei   tracing: Use this...
153
  	buf = this_cpu_ptr(bt->msg_data);
9d5f09a42   Alan D. Brunelle   Added in MESSAGE ...
154
  	va_start(args, fmt);
64565911c   Jens Axboe   block: make blktr...
155
  	n = vscnprintf(buf, BLK_TN_MAX_MSG, fmt, args);
9d5f09a42   Alan D. Brunelle   Added in MESSAGE ...
156
  	va_end(args);
35fe6d763   Shaohua Li   block: use standa...
157
158
159
160
161
162
  	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP))
  		blkcg = NULL;
  #ifdef CONFIG_BLK_CGROUP
  	trace_note(bt, 0, BLK_TN_MESSAGE, buf, n,
  		blkcg ? cgroup_get_kernfs_id(blkcg->css.cgroup) : NULL);
  #else
ca1136c99   Shaohua Li   blktrace: export ...
163
  	trace_note(bt, 0, BLK_TN_MESSAGE, buf, n, NULL);
35fe6d763   Shaohua Li   block: use standa...
164
  #endif
14a73f547   Carl Henrik Lunde   block: disable IR...
165
  	local_irq_restore(flags);
9d5f09a42   Alan D. Brunelle   Added in MESSAGE ...
166
167
  }
  EXPORT_SYMBOL_GPL(__trace_note_message);
2056a782f   Jens Axboe   [PATCH] Block que...
168
169
170
171
172
  static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector,
  			 pid_t pid)
  {
  	if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0)
  		return 1;
d0deef5b1   Shawn Du   blktrace: support...
173
  	if (sector && (sector < bt->start_lba || sector > bt->end_lba))
2056a782f   Jens Axboe   [PATCH] Block que...
174
175
176
177
178
179
180
181
182
183
  		return 1;
  	if (bt->pid && pid != bt->pid)
  		return 1;
  
  	return 0;
  }
  
  /*
   * Data direction bit lookup
   */
e4955c998   Li Zefan   blktrace: mark dd...
184
185
  static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
  				 BLK_TC_ACT(BLK_TC_WRITE) };
2056a782f   Jens Axboe   [PATCH] Block que...
186

7b6d91dae   Christoph Hellwig   block: unify flag...
187
  #define BLK_TC_RAHEAD		BLK_TC_AHEAD
28a8f0d31   Mike Christie   block, drivers, f...
188
  #define BLK_TC_PREFLUSH		BLK_TC_FLUSH
7b6d91dae   Christoph Hellwig   block: unify flag...
189

35ba8f708   David Woodhouse   blktrace: simplif...
190
  /* The ilog2() calls fall out because they're constant */
7b6d91dae   Christoph Hellwig   block: unify flag...
191
192
  #define MASK_TC_BIT(rw, __name) ((rw & REQ_ ## __name) << \
  	  (ilog2(BLK_TC_ ## __name) + BLK_TC_SHIFT - __REQ_ ## __name))
2056a782f   Jens Axboe   [PATCH] Block que...
193
194
195
196
197
  
  /*
   * The worker for the various blk_add_trace*() types. Fills out a
   * blk_io_trace structure and places it in a per-cpu subbuffer.
   */
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
198
  static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
1b9a9ab78   Mike Christie   blktrace: use op ...
199
  		     int op, int op_flags, u32 what, int error, int pdu_len,
ca1136c99   Shaohua Li   blktrace: export ...
200
  		     void *pdu_data, union kernfs_node_id *cgid)
2056a782f   Jens Axboe   [PATCH] Block que...
201
202
  {
  	struct task_struct *tsk = current;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
203
  	struct ring_buffer_event *event = NULL;
e77405ad8   Steven Rostedt   tracing: pass aro...
204
  	struct ring_buffer *buffer = NULL;
2056a782f   Jens Axboe   [PATCH] Block que...
205
  	struct blk_io_trace *t;
0a9877514   Arnaldo Carvalho de Melo   ring_buffer: remo...
206
  	unsigned long flags = 0;
2056a782f   Jens Axboe   [PATCH] Block que...
207
208
  	unsigned long *sequence;
  	pid_t pid;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
209
  	int cpu, pc = 0;
18cea4591   Li Zefan   blktrace: print o...
210
  	bool blk_tracer = blk_tracer_enabled;
ca1136c99   Shaohua Li   blktrace: export ...
211
  	ssize_t cgid_len = cgid ? sizeof(*cgid) : 0;
2056a782f   Jens Axboe   [PATCH] Block que...
212

18cea4591   Li Zefan   blktrace: print o...
213
  	if (unlikely(bt->trace_state != Blktrace_running && !blk_tracer))
2056a782f   Jens Axboe   [PATCH] Block que...
214
  		return;
1b9a9ab78   Mike Christie   blktrace: use op ...
215
216
217
218
  	what |= ddir_act[op_is_write(op) ? WRITE : READ];
  	what |= MASK_TC_BIT(op_flags, SYNC);
  	what |= MASK_TC_BIT(op_flags, RAHEAD);
  	what |= MASK_TC_BIT(op_flags, META);
28a8f0d31   Mike Christie   block, drivers, f...
219
  	what |= MASK_TC_BIT(op_flags, PREFLUSH);
1b9a9ab78   Mike Christie   blktrace: use op ...
220
  	what |= MASK_TC_BIT(op_flags, FUA);
7afafc8a4   Adrian Hunter   block: Fix secure...
221
  	if (op == REQ_OP_DISCARD || op == REQ_OP_SECURE_ERASE)
1b9a9ab78   Mike Christie   blktrace: use op ...
222
  		what |= BLK_TC_ACT(BLK_TC_DISCARD);
3a5e02ced   Mike Christie   block, drivers: a...
223
224
  	if (op == REQ_OP_FLUSH)
  		what |= BLK_TC_ACT(BLK_TC_FLUSH);
ca1136c99   Shaohua Li   blktrace: export ...
225
226
  	if (cgid)
  		what |= __BLK_TA_CGROUP;
2056a782f   Jens Axboe   [PATCH] Block que...
227
228
  
  	pid = tsk->pid;
d0deef5b1   Shawn Du   blktrace: support...
229
  	if (act_log_check(bt, what, sector, pid))
2056a782f   Jens Axboe   [PATCH] Block que...
230
  		return;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
231
  	cpu = raw_smp_processor_id();
18cea4591   Li Zefan   blktrace: print o...
232
  	if (blk_tracer) {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
233
  		tracing_record_cmdline(current);
12883efb6   Steven Rostedt (Red Hat)   tracing: Consolid...
234
  		buffer = blk_tr->trace_buffer.buffer;
51a763dd8   Arnaldo Carvalho de Melo   tracing: Introduc...
235
  		pc = preempt_count();
e77405ad8   Steven Rostedt   tracing: pass aro...
236
  		event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
ca1136c99   Shaohua Li   blktrace: export ...
237
  						  sizeof(*t) + pdu_len + cgid_len,
51a763dd8   Arnaldo Carvalho de Melo   tracing: Introduc...
238
  						  0, pc);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
239
240
  		if (!event)
  			return;
51a763dd8   Arnaldo Carvalho de Melo   tracing: Introduc...
241
  		t = ring_buffer_event_data(event);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
242
243
  		goto record_it;
  	}
2056a782f   Jens Axboe   [PATCH] Block que...
244

a404d5576   Jan Kara   blktrace: Send BL...
245
246
  	if (unlikely(tsk->btrace_seq != blktrace_seq))
  		trace_note_tsk(tsk);
2056a782f   Jens Axboe   [PATCH] Block que...
247
248
249
  	/*
  	 * A word about the locking here - we disable interrupts to reserve
  	 * some space in the relay per-cpu buffer, to prevent an irq
14a73f547   Carl Henrik Lunde   block: disable IR...
250
  	 * from coming in and stepping on our toes.
2056a782f   Jens Axboe   [PATCH] Block que...
251
252
  	 */
  	local_irq_save(flags);
ca1136c99   Shaohua Li   blktrace: export ...
253
  	t = relay_reserve(bt->rchan, sizeof(*t) + pdu_len + cgid_len);
2056a782f   Jens Axboe   [PATCH] Block que...
254
  	if (t) {
2056a782f   Jens Axboe   [PATCH] Block que...
255
256
257
258
  		sequence = per_cpu_ptr(bt->sequence, cpu);
  
  		t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
  		t->sequence = ++(*sequence);
2997c8c4a   Ingo Molnar   block: fix blktra...
259
  		t->time = ktime_to_ns(ktime_get());
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
260
  record_it:
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
261
  		/*
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
262
263
264
265
266
267
268
  		 * These two are not needed in ftrace as they are in the
  		 * generic trace_entry, filled by tracing_generic_entry_update,
  		 * but for the trace_event->bin() synthesizer benefit we do it
  		 * here too.
  		 */
  		t->cpu = cpu;
  		t->pid = pid;
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
269

2056a782f   Jens Axboe   [PATCH] Block que...
270
271
272
  		t->sector = sector;
  		t->bytes = bytes;
  		t->action = what;
2056a782f   Jens Axboe   [PATCH] Block que...
273
  		t->device = bt->dev;
2056a782f   Jens Axboe   [PATCH] Block que...
274
  		t->error = error;
ca1136c99   Shaohua Li   blktrace: export ...
275
  		t->pdu_len = pdu_len + cgid_len;
2056a782f   Jens Axboe   [PATCH] Block que...
276

ca1136c99   Shaohua Li   blktrace: export ...
277
278
  		if (cgid_len)
  			memcpy((void *)t + sizeof(*t), cgid, cgid_len);
2056a782f   Jens Axboe   [PATCH] Block que...
279
  		if (pdu_len)
ca1136c99   Shaohua Li   blktrace: export ...
280
  			memcpy((void *)t + sizeof(*t) + cgid_len, pdu_data, pdu_len);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
281

18cea4591   Li Zefan   blktrace: print o...
282
  		if (blk_tracer) {
b7f0c959e   Steven Rostedt (Red Hat)   tracing: Pass tra...
283
  			trace_buffer_unlock_commit(blk_tr, buffer, event, 0, pc);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
284
285
  			return;
  		}
2056a782f   Jens Axboe   [PATCH] Block que...
286
287
288
289
  	}
  
  	local_irq_restore(flags);
  }
ad5dd5493   Li Zefan   blktrace: fix mem...
290
  static void blk_trace_free(struct blk_trace *bt)
2056a782f   Jens Axboe   [PATCH] Block que...
291
  {
02c62304e   Alan D. Brunelle   Added in user-inj...
292
  	debugfs_remove(bt->msg_file);
2056a782f   Jens Axboe   [PATCH] Block que...
293
  	debugfs_remove(bt->dropped_file);
f48fc4d32   Jens Axboe   block: get rid of...
294
  	relay_close(bt->rchan);
39cbb602b   Alan D. Brunelle   Remove double rem...
295
  	debugfs_remove(bt->dir);
2056a782f   Jens Axboe   [PATCH] Block que...
296
  	free_percpu(bt->sequence);
64565911c   Jens Axboe   block: make blktr...
297
  	free_percpu(bt->msg_data);
2056a782f   Jens Axboe   [PATCH] Block que...
298
  	kfree(bt);
ad5dd5493   Li Zefan   blktrace: fix mem...
299
  }
a6da0024f   Jens Axboe   blktrace: fix unl...
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
  static void get_probe_ref(void)
  {
  	mutex_lock(&blk_probe_mutex);
  	if (++blk_probes_ref == 1)
  		blk_register_tracepoints();
  	mutex_unlock(&blk_probe_mutex);
  }
  
  static void put_probe_ref(void)
  {
  	mutex_lock(&blk_probe_mutex);
  	if (!--blk_probes_ref)
  		blk_unregister_tracepoints();
  	mutex_unlock(&blk_probe_mutex);
  }
ad5dd5493   Li Zefan   blktrace: fix mem...
315
316
  static void blk_trace_cleanup(struct blk_trace *bt)
  {
6f9cff84d   Jan Kara   blktrace: Protect...
317
  	synchronize_rcu();
ad5dd5493   Li Zefan   blktrace: fix mem...
318
  	blk_trace_free(bt);
a6da0024f   Jens Axboe   blktrace: fix unl...
319
  	put_probe_ref();
2056a782f   Jens Axboe   [PATCH] Block que...
320
  }
1f2cac107   Jens Axboe   blktrace: fix unl...
321
  static int __blk_trace_remove(struct request_queue *q)
2056a782f   Jens Axboe   [PATCH] Block que...
322
323
324
325
326
327
  {
  	struct blk_trace *bt;
  
  	bt = xchg(&q->blk_trace, NULL);
  	if (!bt)
  		return -EINVAL;
555472048   Li Zefan   blktrace: fix the...
328
  	if (bt->trace_state != Blktrace_running)
2056a782f   Jens Axboe   [PATCH] Block que...
329
330
331
332
  		blk_trace_cleanup(bt);
  
  	return 0;
  }
1f2cac107   Jens Axboe   blktrace: fix unl...
333
334
335
336
337
338
339
340
341
342
343
  
  int blk_trace_remove(struct request_queue *q)
  {
  	int ret;
  
  	mutex_lock(&q->blk_trace_mutex);
  	ret = __blk_trace_remove(q);
  	mutex_unlock(&q->blk_trace_mutex);
  
  	return ret;
  }
6da127ad0   Christof Schmitt   blktrace: Add blk...
344
  EXPORT_SYMBOL_GPL(blk_trace_remove);
2056a782f   Jens Axboe   [PATCH] Block que...
345

2056a782f   Jens Axboe   [PATCH] Block que...
346
347
348
349
350
351
352
353
354
355
356
  static ssize_t blk_dropped_read(struct file *filp, char __user *buffer,
  				size_t count, loff_t *ppos)
  {
  	struct blk_trace *bt = filp->private_data;
  	char buf[16];
  
  	snprintf(buf, sizeof(buf), "%u
  ", atomic_read(&bt->dropped));
  
  	return simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf));
  }
2b8693c06   Arjan van de Ven   [PATCH] mark stru...
357
  static const struct file_operations blk_dropped_fops = {
2056a782f   Jens Axboe   [PATCH] Block que...
358
  	.owner =	THIS_MODULE,
234e34058   Stephen Boyd   simple_open: auto...
359
  	.open =		simple_open,
2056a782f   Jens Axboe   [PATCH] Block que...
360
  	.read =		blk_dropped_read,
6038f373a   Arnd Bergmann   llseek: automatic...
361
  	.llseek =	default_llseek,
2056a782f   Jens Axboe   [PATCH] Block que...
362
  };
02c62304e   Alan D. Brunelle   Added in user-inj...
363
364
365
366
367
  static ssize_t blk_msg_write(struct file *filp, const char __user *buffer,
  				size_t count, loff_t *ppos)
  {
  	char *msg;
  	struct blk_trace *bt;
7635b03ad   Li Zefan   blktrace: small c...
368
  	if (count >= BLK_TN_MAX_MSG)
02c62304e   Alan D. Brunelle   Added in user-inj...
369
  		return -EINVAL;
16e5c1fc3   Al Viro   convert a bunch o...
370
371
372
  	msg = memdup_user_nul(buffer, count);
  	if (IS_ERR(msg))
  		return PTR_ERR(msg);
02c62304e   Alan D. Brunelle   Added in user-inj...
373

02c62304e   Alan D. Brunelle   Added in user-inj...
374
  	bt = filp->private_data;
35fe6d763   Shaohua Li   block: use standa...
375
  	__trace_note_message(bt, NULL, "%s", msg);
02c62304e   Alan D. Brunelle   Added in user-inj...
376
377
378
379
380
381
382
  	kfree(msg);
  
  	return count;
  }
  
  static const struct file_operations blk_msg_fops = {
  	.owner =	THIS_MODULE,
234e34058   Stephen Boyd   simple_open: auto...
383
  	.open =		simple_open,
02c62304e   Alan D. Brunelle   Added in user-inj...
384
  	.write =	blk_msg_write,
6038f373a   Arnd Bergmann   llseek: automatic...
385
  	.llseek =	noop_llseek,
02c62304e   Alan D. Brunelle   Added in user-inj...
386
  };
2056a782f   Jens Axboe   [PATCH] Block que...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
  /*
   * Keep track of how many times we encountered a full subbuffer, to aid
   * the user space app in telling how many lost events there were.
   */
  static int blk_subbuf_start_callback(struct rchan_buf *buf, void *subbuf,
  				     void *prev_subbuf, size_t prev_padding)
  {
  	struct blk_trace *bt;
  
  	if (!relay_buf_full(buf))
  		return 1;
  
  	bt = buf->chan->private_data;
  	atomic_inc(&bt->dropped);
  	return 0;
  }
  
  static int blk_remove_buf_file_callback(struct dentry *dentry)
  {
  	debugfs_remove(dentry);
f48fc4d32   Jens Axboe   block: get rid of...
407

2056a782f   Jens Axboe   [PATCH] Block que...
408
409
410
411
412
  	return 0;
  }
  
  static struct dentry *blk_create_buf_file_callback(const char *filename,
  						   struct dentry *parent,
f4ae40a6a   Al Viro   switch debugfs to...
413
  						   umode_t mode,
2056a782f   Jens Axboe   [PATCH] Block que...
414
415
416
417
418
419
420
421
422
423
424
425
  						   struct rchan_buf *buf,
  						   int *is_global)
  {
  	return debugfs_create_file(filename, mode, parent, buf,
  					&relay_file_operations);
  }
  
  static struct rchan_callbacks blk_relay_callbacks = {
  	.subbuf_start		= blk_subbuf_start_callback,
  	.create_buf_file	= blk_create_buf_file_callback,
  	.remove_buf_file	= blk_remove_buf_file_callback,
  };
9908c3099   Li Zefan   blktrace: support...
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
  static void blk_trace_setup_lba(struct blk_trace *bt,
  				struct block_device *bdev)
  {
  	struct hd_struct *part = NULL;
  
  	if (bdev)
  		part = bdev->bd_part;
  
  	if (part) {
  		bt->start_lba = part->start_sect;
  		bt->end_lba = part->start_sect + part->nr_sects;
  	} else {
  		bt->start_lba = 0;
  		bt->end_lba = -1ULL;
  	}
  }
2056a782f   Jens Axboe   [PATCH] Block que...
442
443
444
  /*
   * Setup everything required to start tracing
   */
a428d314e   Omar Sandoval   blktrace: make do...
445
446
447
  static int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
  			      struct block_device *bdev,
  			      struct blk_user_trace_setup *buts)
2056a782f   Jens Axboe   [PATCH] Block que...
448
  {
cdea01b2b   Davidlohr Bueso   blktrace: re-writ...
449
  	struct blk_trace *bt = NULL;
2056a782f   Jens Axboe   [PATCH] Block que...
450
  	struct dentry *dir = NULL;
ff14417c0   Rasmus Villemoes   kernel/trace/blkt...
451
  	int ret;
2056a782f   Jens Axboe   [PATCH] Block que...
452

171044d44   Arnd Bergmann   compat_ioctl: han...
453
  	if (!buts->buf_size || !buts->buf_nr)
2056a782f   Jens Axboe   [PATCH] Block que...
454
  		return -EINVAL;
e1a413245   Liu Bo   Blktrace: bail ou...
455
456
  	if (!blk_debugfs_root)
  		return -ENOENT;
0497b345e   Jens Axboe   blktrace: use BLK...
457
458
  	strncpy(buts->name, name, BLKTRACE_BDEV_SIZE);
  	buts->name[BLKTRACE_BDEV_SIZE - 1] = '\0';
2056a782f   Jens Axboe   [PATCH] Block que...
459
460
461
462
463
  
  	/*
  	 * some device names have larger paths - convert the slashes
  	 * to underscores for this to work as expected
  	 */
ff14417c0   Rasmus Villemoes   kernel/trace/blkt...
464
  	strreplace(buts->name, '/', '_');
2056a782f   Jens Axboe   [PATCH] Block que...
465

2056a782f   Jens Axboe   [PATCH] Block que...
466
467
  	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
  	if (!bt)
ad5dd5493   Li Zefan   blktrace: fix mem...
468
  		return -ENOMEM;
2056a782f   Jens Axboe   [PATCH] Block que...
469

ad5dd5493   Li Zefan   blktrace: fix mem...
470
  	ret = -ENOMEM;
2056a782f   Jens Axboe   [PATCH] Block que...
471
472
473
  	bt->sequence = alloc_percpu(unsigned long);
  	if (!bt->sequence)
  		goto err;
313e458f8   Rusty Russell   alloc_percpu: add...
474
  	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
64565911c   Jens Axboe   block: make blktr...
475
476
  	if (!bt->msg_data)
  		goto err;
2056a782f   Jens Axboe   [PATCH] Block que...
477
  	ret = -ENOENT;
f48fc4d32   Jens Axboe   block: get rid of...
478

6ac93117a   Omar Sandoval   blktrace: use exi...
479
480
481
  	dir = debugfs_lookup(buts->name, blk_debugfs_root);
  	if (!dir)
  		bt->dir = dir = debugfs_create_dir(buts->name, blk_debugfs_root);
2056a782f   Jens Axboe   [PATCH] Block que...
482

6da127ad0   Christof Schmitt   blktrace: Add blk...
483
  	bt->dev = dev;
2056a782f   Jens Axboe   [PATCH] Block que...
484
  	atomic_set(&bt->dropped, 0);
a404d5576   Jan Kara   blktrace: Send BL...
485
  	INIT_LIST_HEAD(&bt->running_list);
2056a782f   Jens Axboe   [PATCH] Block que...
486
487
  
  	ret = -EIO;
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
488
489
  	bt->dropped_file = debugfs_create_file("dropped", 0444, dir, bt,
  					       &blk_dropped_fops);
2056a782f   Jens Axboe   [PATCH] Block que...
490

02c62304e   Alan D. Brunelle   Added in user-inj...
491
  	bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops);
02c62304e   Alan D. Brunelle   Added in user-inj...
492

171044d44   Arnd Bergmann   compat_ioctl: han...
493
494
  	bt->rchan = relay_open("trace", dir, buts->buf_size,
  				buts->buf_nr, &blk_relay_callbacks, bt);
2056a782f   Jens Axboe   [PATCH] Block que...
495
496
  	if (!bt->rchan)
  		goto err;
2056a782f   Jens Axboe   [PATCH] Block que...
497

171044d44   Arnd Bergmann   compat_ioctl: han...
498
  	bt->act_mask = buts->act_mask;
2056a782f   Jens Axboe   [PATCH] Block que...
499
500
  	if (!bt->act_mask)
  		bt->act_mask = (u16) -1;
9908c3099   Li Zefan   blktrace: support...
501
  	blk_trace_setup_lba(bt, bdev);
2056a782f   Jens Axboe   [PATCH] Block que...
502

d0deef5b1   Shawn Du   blktrace: support...
503
504
505
506
507
  	/* overwrite with user settings */
  	if (buts->start_lba)
  		bt->start_lba = buts->start_lba;
  	if (buts->end_lba)
  		bt->end_lba = buts->end_lba;
171044d44   Arnd Bergmann   compat_ioctl: han...
508
  	bt->pid = buts->pid;
2056a782f   Jens Axboe   [PATCH] Block que...
509
510
511
  	bt->trace_state = Blktrace_setup;
  
  	ret = -EBUSY;
cdea01b2b   Davidlohr Bueso   blktrace: re-writ...
512
  	if (cmpxchg(&q->blk_trace, NULL, bt))
2056a782f   Jens Axboe   [PATCH] Block que...
513
  		goto err;
2056a782f   Jens Axboe   [PATCH] Block que...
514

a6da0024f   Jens Axboe   blktrace: fix unl...
515
  	get_probe_ref();
cbe28296e   Li Zefan   blktrace: don't i...
516

6ac93117a   Omar Sandoval   blktrace: use exi...
517
  	ret = 0;
2056a782f   Jens Axboe   [PATCH] Block que...
518
  err:
6ac93117a   Omar Sandoval   blktrace: use exi...
519
520
521
522
  	if (dir && !bt->dir)
  		dput(dir);
  	if (ret)
  		blk_trace_free(bt);
2056a782f   Jens Axboe   [PATCH] Block que...
523
524
  	return ret;
  }
171044d44   Arnd Bergmann   compat_ioctl: han...
525

1f2cac107   Jens Axboe   blktrace: fix unl...
526
527
  static int __blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
  			     struct block_device *bdev, char __user *arg)
171044d44   Arnd Bergmann   compat_ioctl: han...
528
529
530
531
532
533
534
  {
  	struct blk_user_trace_setup buts;
  	int ret;
  
  	ret = copy_from_user(&buts, arg, sizeof(buts));
  	if (ret)
  		return -EFAULT;
d0deef5b1   Shawn Du   blktrace: support...
535
  	ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
171044d44   Arnd Bergmann   compat_ioctl: han...
536
537
  	if (ret)
  		return ret;
9a8c28c83   Dmitry Monakhov   blktrace: perform...
538
  	if (copy_to_user(arg, &buts, sizeof(buts))) {
2967acbb2   Jens Axboe   blktrace: fix tra...
539
  		__blk_trace_remove(q);
171044d44   Arnd Bergmann   compat_ioctl: han...
540
  		return -EFAULT;
9a8c28c83   Dmitry Monakhov   blktrace: perform...
541
  	}
171044d44   Arnd Bergmann   compat_ioctl: han...
542
543
  	return 0;
  }
1f2cac107   Jens Axboe   blktrace: fix unl...
544
545
546
547
548
549
550
551
552
553
554
555
556
  
  int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
  		    struct block_device *bdev,
  		    char __user *arg)
  {
  	int ret;
  
  	mutex_lock(&q->blk_trace_mutex);
  	ret = __blk_trace_setup(q, name, dev, bdev, arg);
  	mutex_unlock(&q->blk_trace_mutex);
  
  	return ret;
  }
6da127ad0   Christof Schmitt   blktrace: Add blk...
557
  EXPORT_SYMBOL_GPL(blk_trace_setup);
2056a782f   Jens Axboe   [PATCH] Block que...
558

62c2a7d96   Arnd Bergmann   block: push BKL i...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
  #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
  static int compat_blk_trace_setup(struct request_queue *q, char *name,
  				  dev_t dev, struct block_device *bdev,
  				  char __user *arg)
  {
  	struct blk_user_trace_setup buts;
  	struct compat_blk_user_trace_setup cbuts;
  	int ret;
  
  	if (copy_from_user(&cbuts, arg, sizeof(cbuts)))
  		return -EFAULT;
  
  	buts = (struct blk_user_trace_setup) {
  		.act_mask = cbuts.act_mask,
  		.buf_size = cbuts.buf_size,
  		.buf_nr = cbuts.buf_nr,
  		.start_lba = cbuts.start_lba,
  		.end_lba = cbuts.end_lba,
  		.pid = cbuts.pid,
  	};
62c2a7d96   Arnd Bergmann   block: push BKL i...
579
580
581
582
  
  	ret = do_blk_trace_setup(q, name, dev, bdev, &buts);
  	if (ret)
  		return ret;
f8c5e9448   Chen Gang   kernel: trace: bl...
583
  	if (copy_to_user(arg, &buts.name, ARRAY_SIZE(buts.name))) {
2967acbb2   Jens Axboe   blktrace: fix tra...
584
  		__blk_trace_remove(q);
62c2a7d96   Arnd Bergmann   block: push BKL i...
585
586
587
588
589
590
  		return -EFAULT;
  	}
  
  	return 0;
  }
  #endif
1f2cac107   Jens Axboe   blktrace: fix unl...
591
  static int __blk_trace_startstop(struct request_queue *q, int start)
2056a782f   Jens Axboe   [PATCH] Block que...
592
  {
2056a782f   Jens Axboe   [PATCH] Block que...
593
  	int ret;
6f9cff84d   Jan Kara   blktrace: Protect...
594
  	struct blk_trace *bt;
2056a782f   Jens Axboe   [PATCH] Block que...
595

6f9cff84d   Jan Kara   blktrace: Protect...
596
597
  	bt = rcu_dereference_protected(q->blk_trace,
  				       lockdep_is_held(&q->blk_trace_mutex));
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
598
  	if (bt == NULL)
2056a782f   Jens Axboe   [PATCH] Block que...
599
600
601
602
603
604
605
606
607
608
609
610
611
  		return -EINVAL;
  
  	/*
  	 * For starting a trace, we can transition from a setup or stopped
  	 * trace. For stopping a trace, the state must be running
  	 */
  	ret = -EINVAL;
  	if (start) {
  		if (bt->trace_state == Blktrace_setup ||
  		    bt->trace_state == Blktrace_stopped) {
  			blktrace_seq++;
  			smp_mb();
  			bt->trace_state = Blktrace_running;
a404d5576   Jan Kara   blktrace: Send BL...
612
613
614
  			spin_lock_irq(&running_trace_lock);
  			list_add(&bt->running_list, &running_trace_list);
  			spin_unlock_irq(&running_trace_lock);
be1c63411   Olaf Kirch   [PATCH] blktrace:...
615
616
  
  			trace_note_time(bt);
2056a782f   Jens Axboe   [PATCH] Block que...
617
618
619
620
621
  			ret = 0;
  		}
  	} else {
  		if (bt->trace_state == Blktrace_running) {
  			bt->trace_state = Blktrace_stopped;
a404d5576   Jan Kara   blktrace: Send BL...
622
623
624
  			spin_lock_irq(&running_trace_lock);
  			list_del_init(&bt->running_list);
  			spin_unlock_irq(&running_trace_lock);
2056a782f   Jens Axboe   [PATCH] Block que...
625
626
627
628
629
630
631
  			relay_flush(bt->rchan);
  			ret = 0;
  		}
  	}
  
  	return ret;
  }
1f2cac107   Jens Axboe   blktrace: fix unl...
632
633
634
635
636
637
638
639
640
641
642
  
  int blk_trace_startstop(struct request_queue *q, int start)
  {
  	int ret;
  
  	mutex_lock(&q->blk_trace_mutex);
  	ret = __blk_trace_startstop(q, start);
  	mutex_unlock(&q->blk_trace_mutex);
  
  	return ret;
  }
6da127ad0   Christof Schmitt   blktrace: Add blk...
643
  EXPORT_SYMBOL_GPL(blk_trace_startstop);
2056a782f   Jens Axboe   [PATCH] Block que...
644

5acb3cc2c   Waiman Long   blktrace: Fix pot...
645
646
647
648
649
  /*
   * When reading or writing the blktrace sysfs files, the references to the
   * opened sysfs or device files should prevent the underlying block device
   * from being removed. So no further delete protection is really needed.
   */
2056a782f   Jens Axboe   [PATCH] Block que...
650
651
652
  /**
   * blk_trace_ioctl: - handle the ioctls associated with tracing
   * @bdev:	the block device
ef18012b2   Steven Rostedt   tracing: remove f...
653
   * @cmd:	the ioctl cmd
2056a782f   Jens Axboe   [PATCH] Block que...
654
655
656
657
658
   * @arg:	the argument data, if any
   *
   **/
  int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg)
  {
165125e1e   Jens Axboe   [BLOCK] Get rid o...
659
  	struct request_queue *q;
2056a782f   Jens Axboe   [PATCH] Block que...
660
  	int ret, start = 0;
6da127ad0   Christof Schmitt   blktrace: Add blk...
661
  	char b[BDEVNAME_SIZE];
2056a782f   Jens Axboe   [PATCH] Block que...
662
663
664
665
  
  	q = bdev_get_queue(bdev);
  	if (!q)
  		return -ENXIO;
5acb3cc2c   Waiman Long   blktrace: Fix pot...
666
  	mutex_lock(&q->blk_trace_mutex);
2056a782f   Jens Axboe   [PATCH] Block que...
667
668
669
  
  	switch (cmd) {
  	case BLKTRACESETUP:
f36f21ecc   Jean Delvare   Fix misuses of bd...
670
  		bdevname(bdev, b);
1f2cac107   Jens Axboe   blktrace: fix unl...
671
  		ret = __blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
2056a782f   Jens Axboe   [PATCH] Block que...
672
  		break;
62c2a7d96   Arnd Bergmann   block: push BKL i...
673
674
675
676
677
678
  #if defined(CONFIG_COMPAT) && defined(CONFIG_X86_64)
  	case BLKTRACESETUP32:
  		bdevname(bdev, b);
  		ret = compat_blk_trace_setup(q, b, bdev->bd_dev, bdev, arg);
  		break;
  #endif
2056a782f   Jens Axboe   [PATCH] Block que...
679
680
  	case BLKTRACESTART:
  		start = 1;
f6d85f04e   Mathieu Malaterre   blkcg: annotate i...
681
  		/* fall through */
2056a782f   Jens Axboe   [PATCH] Block que...
682
  	case BLKTRACESTOP:
1f2cac107   Jens Axboe   blktrace: fix unl...
683
  		ret = __blk_trace_startstop(q, start);
2056a782f   Jens Axboe   [PATCH] Block que...
684
685
  		break;
  	case BLKTRACETEARDOWN:
1f2cac107   Jens Axboe   blktrace: fix unl...
686
  		ret = __blk_trace_remove(q);
2056a782f   Jens Axboe   [PATCH] Block que...
687
688
689
690
691
  		break;
  	default:
  		ret = -ENOTTY;
  		break;
  	}
5acb3cc2c   Waiman Long   blktrace: Fix pot...
692
  	mutex_unlock(&q->blk_trace_mutex);
2056a782f   Jens Axboe   [PATCH] Block que...
693
694
695
696
697
698
699
700
  	return ret;
  }
  
  /**
   * blk_trace_shutdown: - stop and cleanup trace structures
   * @q:    the request queue associated with the device
   *
   **/
165125e1e   Jens Axboe   [BLOCK] Get rid o...
701
  void blk_trace_shutdown(struct request_queue *q)
2056a782f   Jens Axboe   [PATCH] Block que...
702
  {
1f2cac107   Jens Axboe   blktrace: fix unl...
703
  	mutex_lock(&q->blk_trace_mutex);
6f9cff84d   Jan Kara   blktrace: Protect...
704
705
  	if (rcu_dereference_protected(q->blk_trace,
  				      lockdep_is_held(&q->blk_trace_mutex))) {
1f2cac107   Jens Axboe   blktrace: fix unl...
706
707
  		__blk_trace_startstop(q, 0);
  		__blk_trace_remove(q);
6c5c93415   Alexey Dobriyan   [PATCH] ifdef blk...
708
  	}
1f2cac107   Jens Axboe   blktrace: fix unl...
709
710
  
  	mutex_unlock(&q->blk_trace_mutex);
2056a782f   Jens Axboe   [PATCH] Block que...
711
  }
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
712

ca1136c99   Shaohua Li   blktrace: export ...
713
714
715
716
  #ifdef CONFIG_BLK_CGROUP
  static union kernfs_node_id *
  blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio)
  {
6f9cff84d   Jan Kara   blktrace: Protect...
717
  	struct blk_trace *bt;
ca1136c99   Shaohua Li   blktrace: export ...
718

6f9cff84d   Jan Kara   blktrace: Protect...
719
720
  	/* We don't use the 'bt' value here except as an optimization... */
  	bt = rcu_dereference_protected(q->blk_trace, 1);
ca1136c99   Shaohua Li   blktrace: export ...
721
722
  	if (!bt || !(blk_tracer_flags.val & TRACE_BLK_OPT_CGROUP))
  		return NULL;
db6638d7d   Dennis Zhou   blkcg: remove bio...
723
  	if (!bio->bi_blkg)
ca1136c99   Shaohua Li   blktrace: export ...
724
  		return NULL;
db6638d7d   Dennis Zhou   blkcg: remove bio...
725
  	return cgroup_get_kernfs_id(bio_blkcg(bio)->css.cgroup);
ca1136c99   Shaohua Li   blktrace: export ...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  }
  #else
  static union kernfs_node_id *
  blk_trace_bio_get_cgid(struct request_queue *q, struct bio *bio)
  {
  	return NULL;
  }
  #endif
  
  static union kernfs_node_id *
  blk_trace_request_get_cgid(struct request_queue *q, struct request *rq)
  {
  	if (!rq->bio)
  		return NULL;
  	/* Use the first bio */
  	return blk_trace_bio_get_cgid(q, rq->bio);
  }
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
743
744
745
746
747
748
  /*
   * blktrace probes
   */
  
  /**
   * blk_add_trace_rq - Add a trace for a request oriented action
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
749
   * @rq:		the source request
caf7df122   Christoph Hellwig   block: remove the...
750
   * @error:	return status to log
af5040da0   Roman Pen   blktrace: fix acc...
751
   * @nr_bytes:	number of completed bytes
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
752
   * @what:	the action
ca1136c99   Shaohua Li   blktrace: export ...
753
   * @cgid:	the cgroup info
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
754
755
756
757
758
   *
   * Description:
   *     Records an action against a request. Will log the bio offset + size.
   *
   **/
caf7df122   Christoph Hellwig   block: remove the...
759
  static void blk_add_trace_rq(struct request *rq, int error,
ca1136c99   Shaohua Li   blktrace: export ...
760
761
  			     unsigned int nr_bytes, u32 what,
  			     union kernfs_node_id *cgid)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
762
  {
6f9cff84d   Jan Kara   blktrace: Protect...
763
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
764

6f9cff84d   Jan Kara   blktrace: Protect...
765
766
767
768
  	rcu_read_lock();
  	bt = rcu_dereference(rq->q->blk_trace);
  	if (likely(!bt)) {
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
769
  		return;
6f9cff84d   Jan Kara   blktrace: Protect...
770
  	}
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
771

57292b58d   Christoph Hellwig   block: introduce ...
772
  	if (blk_rq_is_passthrough(rq))
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
773
  		what |= BLK_TC_ACT(BLK_TC_PC);
48b77ad60   Christoph Hellwig   block: cleanup tr...
774
  	else
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
775
  		what |= BLK_TC_ACT(BLK_TC_FS);
48b77ad60   Christoph Hellwig   block: cleanup tr...
776
777
  
  	__blk_add_trace(bt, blk_rq_trace_sector(rq), nr_bytes, req_op(rq),
ca1136c99   Shaohua Li   blktrace: export ...
778
  			rq->cmd_flags, what, error, 0, NULL, cgid);
6f9cff84d   Jan Kara   blktrace: Protect...
779
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
780
  }
38516ab59   Steven Rostedt   tracing: Let trac...
781
782
  static void blk_add_trace_rq_insert(void *ignore,
  				    struct request_queue *q, struct request *rq)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
783
  {
ca1136c99   Shaohua Li   blktrace: export ...
784
785
  	blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_INSERT,
  			 blk_trace_request_get_cgid(q, rq));
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
786
  }
38516ab59   Steven Rostedt   tracing: Let trac...
787
788
  static void blk_add_trace_rq_issue(void *ignore,
  				   struct request_queue *q, struct request *rq)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
789
  {
ca1136c99   Shaohua Li   blktrace: export ...
790
791
  	blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_ISSUE,
  			 blk_trace_request_get_cgid(q, rq));
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
792
  }
38516ab59   Steven Rostedt   tracing: Let trac...
793
794
  static void blk_add_trace_rq_requeue(void *ignore,
  				     struct request_queue *q,
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
795
  				     struct request *rq)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
796
  {
ca1136c99   Shaohua Li   blktrace: export ...
797
798
  	blk_add_trace_rq(rq, 0, blk_rq_bytes(rq), BLK_TA_REQUEUE,
  			 blk_trace_request_get_cgid(q, rq));
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
799
  }
caf7df122   Christoph Hellwig   block: remove the...
800
801
  static void blk_add_trace_rq_complete(void *ignore, struct request *rq,
  			int error, unsigned int nr_bytes)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
802
  {
ca1136c99   Shaohua Li   blktrace: export ...
803
804
  	blk_add_trace_rq(rq, error, nr_bytes, BLK_TA_COMPLETE,
  			 blk_trace_request_get_cgid(rq->q, rq));
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
805
806
807
808
809
810
811
  }
  
  /**
   * blk_add_trace_bio - Add a trace for a bio oriented action
   * @q:		queue the io is for
   * @bio:	the source bio
   * @what:	the action
797a455d2   Jens Axboe   block: ensure tha...
812
   * @error:	error, if any
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
813
814
815
816
817
818
   *
   * Description:
   *     Records an action against a bio. Will log the bio offset + size.
   *
   **/
  static void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
819
  			      u32 what, int error)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
820
  {
6f9cff84d   Jan Kara   blktrace: Protect...
821
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
822

6f9cff84d   Jan Kara   blktrace: Protect...
823
824
825
826
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
  	if (likely(!bt)) {
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
827
  		return;
6f9cff84d   Jan Kara   blktrace: Protect...
828
  	}
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
829

4f024f379   Kent Overstreet   block: Abstract o...
830
  	__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
831
832
  			bio_op(bio), bio->bi_opf, what, error, 0, NULL,
  			blk_trace_bio_get_cgid(q, bio));
6f9cff84d   Jan Kara   blktrace: Protect...
833
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
834
  }
38516ab59   Steven Rostedt   tracing: Let trac...
835
836
  static void blk_add_trace_bio_bounce(void *ignore,
  				     struct request_queue *q, struct bio *bio)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
837
  {
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
838
  	blk_add_trace_bio(q, bio, BLK_TA_BOUNCE, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
839
  }
0a82a8d13   Linus Torvalds   Revert "block: ad...
840
841
842
  static void blk_add_trace_bio_complete(void *ignore,
  				       struct request_queue *q, struct bio *bio,
  				       int error)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
843
  {
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
844
  	blk_add_trace_bio(q, bio, BLK_TA_COMPLETE, error);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
845
  }
38516ab59   Steven Rostedt   tracing: Let trac...
846
847
  static void blk_add_trace_bio_backmerge(void *ignore,
  					struct request_queue *q,
8c1cf6bb0   Tejun Heo   block: add @req t...
848
  					struct request *rq,
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
849
  					struct bio *bio)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
850
  {
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
851
  	blk_add_trace_bio(q, bio, BLK_TA_BACKMERGE, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
852
  }
38516ab59   Steven Rostedt   tracing: Let trac...
853
854
  static void blk_add_trace_bio_frontmerge(void *ignore,
  					 struct request_queue *q,
8c1cf6bb0   Tejun Heo   block: add @req t...
855
  					 struct request *rq,
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
856
  					 struct bio *bio)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
857
  {
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
858
  	blk_add_trace_bio(q, bio, BLK_TA_FRONTMERGE, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
859
  }
38516ab59   Steven Rostedt   tracing: Let trac...
860
861
  static void blk_add_trace_bio_queue(void *ignore,
  				    struct request_queue *q, struct bio *bio)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
862
  {
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
863
  	blk_add_trace_bio(q, bio, BLK_TA_QUEUE, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
864
  }
38516ab59   Steven Rostedt   tracing: Let trac...
865
866
  static void blk_add_trace_getrq(void *ignore,
  				struct request_queue *q,
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
867
  				struct bio *bio, int rw)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
868
869
  {
  	if (bio)
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
870
  		blk_add_trace_bio(q, bio, BLK_TA_GETRQ, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
871
  	else {
6f9cff84d   Jan Kara   blktrace: Protect...
872
  		struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
873

6f9cff84d   Jan Kara   blktrace: Protect...
874
875
  		rcu_read_lock();
  		bt = rcu_dereference(q->blk_trace);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
876
  		if (bt)
1b9a9ab78   Mike Christie   blktrace: use op ...
877
  			__blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_GETRQ, 0, 0,
ca1136c99   Shaohua Li   blktrace: export ...
878
  					NULL, NULL);
6f9cff84d   Jan Kara   blktrace: Protect...
879
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
880
881
  	}
  }
38516ab59   Steven Rostedt   tracing: Let trac...
882
883
  static void blk_add_trace_sleeprq(void *ignore,
  				  struct request_queue *q,
939b36697   Arnaldo Carvalho de Melo   blktrace: fix cod...
884
  				  struct bio *bio, int rw)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
885
886
  {
  	if (bio)
1690102de   Marcos Paulo de Souza   blktrace: Use blk...
887
  		blk_add_trace_bio(q, bio, BLK_TA_SLEEPRQ, 0);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
888
  	else {
6f9cff84d   Jan Kara   blktrace: Protect...
889
  		struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
890

6f9cff84d   Jan Kara   blktrace: Protect...
891
892
  		rcu_read_lock();
  		bt = rcu_dereference(q->blk_trace);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
893
  		if (bt)
1b9a9ab78   Mike Christie   blktrace: use op ...
894
  			__blk_add_trace(bt, 0, 0, rw, 0, BLK_TA_SLEEPRQ,
ca1136c99   Shaohua Li   blktrace: export ...
895
  					0, 0, NULL, NULL);
6f9cff84d   Jan Kara   blktrace: Protect...
896
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
897
898
  	}
  }
38516ab59   Steven Rostedt   tracing: Let trac...
899
  static void blk_add_trace_plug(void *ignore, struct request_queue *q)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
900
  {
6f9cff84d   Jan Kara   blktrace: Protect...
901
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
902

6f9cff84d   Jan Kara   blktrace: Protect...
903
904
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
905
  	if (bt)
ca1136c99   Shaohua Li   blktrace: export ...
906
  		__blk_add_trace(bt, 0, 0, 0, 0, BLK_TA_PLUG, 0, 0, NULL, NULL);
6f9cff84d   Jan Kara   blktrace: Protect...
907
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
908
  }
49cac01e1   Jens Axboe   block: make unplu...
909
910
  static void blk_add_trace_unplug(void *ignore, struct request_queue *q,
  				    unsigned int depth, bool explicit)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
911
  {
6f9cff84d   Jan Kara   blktrace: Protect...
912
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
913

6f9cff84d   Jan Kara   blktrace: Protect...
914
915
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
916
  	if (bt) {
94b5eb28b   Jens Axboe   block: fixup bloc...
917
  		__be64 rpdu = cpu_to_be64(depth);
49cac01e1   Jens Axboe   block: make unplu...
918
  		u32 what;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
919

49cac01e1   Jens Axboe   block: make unplu...
920
921
922
923
  		if (explicit)
  			what = BLK_TA_UNPLUG_IO;
  		else
  			what = BLK_TA_UNPLUG_TIMER;
ca1136c99   Shaohua Li   blktrace: export ...
924
  		__blk_add_trace(bt, 0, 0, 0, 0, what, 0, sizeof(rpdu), &rpdu, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
925
  	}
6f9cff84d   Jan Kara   blktrace: Protect...
926
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
927
  }
38516ab59   Steven Rostedt   tracing: Let trac...
928
929
  static void blk_add_trace_split(void *ignore,
  				struct request_queue *q, struct bio *bio,
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
930
931
  				unsigned int pdu)
  {
6f9cff84d   Jan Kara   blktrace: Protect...
932
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
933

6f9cff84d   Jan Kara   blktrace: Protect...
934
935
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
936
937
  	if (bt) {
  		__be64 rpdu = cpu_to_be64(pdu);
4f024f379   Kent Overstreet   block: Abstract o...
938
  		__blk_add_trace(bt, bio->bi_iter.bi_sector,
1eff9d322   Jens Axboe   block: rename bio...
939
  				bio->bi_iter.bi_size, bio_op(bio), bio->bi_opf,
4e4cbee93   Christoph Hellwig   block: switch bio...
940
  				BLK_TA_SPLIT, bio->bi_status, sizeof(rpdu),
ca1136c99   Shaohua Li   blktrace: export ...
941
  				&rpdu, blk_trace_bio_get_cgid(q, bio));
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
942
  	}
6f9cff84d   Jan Kara   blktrace: Protect...
943
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
944
945
946
  }
  
  /**
d07335e51   Mike Snitzer   block: Rename "bl...
947
   * blk_add_trace_bio_remap - Add a trace for a bio-remap operation
546cf44a1   Randy Dunlap   blktrace: Fix new...
948
   * @ignore:	trace callback data parameter (not used)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
949
950
951
   * @q:		queue the io is for
   * @bio:	the source bio
   * @dev:	target device
a42aaa3bb   Alan D. Brunelle   blktrace: correct...
952
   * @from:	source sector
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
953
954
955
956
957
958
   *
   * Description:
   *     Device mapper or raid target sometimes need to split a bio because
   *     it spans a stripe (or similar). Add a trace for that action.
   *
   **/
d07335e51   Mike Snitzer   block: Rename "bl...
959
960
961
  static void blk_add_trace_bio_remap(void *ignore,
  				    struct request_queue *q, struct bio *bio,
  				    dev_t dev, sector_t from)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
962
  {
6f9cff84d   Jan Kara   blktrace: Protect...
963
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
964
  	struct blk_io_trace_remap r;
6f9cff84d   Jan Kara   blktrace: Protect...
965
966
967
968
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
  	if (likely(!bt)) {
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
969
  		return;
6f9cff84d   Jan Kara   blktrace: Protect...
970
  	}
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
971

a42aaa3bb   Alan D. Brunelle   blktrace: correct...
972
  	r.device_from = cpu_to_be32(dev);
74d46992e   Christoph Hellwig   block: replace bi...
973
  	r.device_to   = cpu_to_be32(bio_dev(bio));
a42aaa3bb   Alan D. Brunelle   blktrace: correct...
974
  	r.sector_from = cpu_to_be64(from);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
975

4f024f379   Kent Overstreet   block: Abstract o...
976
  	__blk_add_trace(bt, bio->bi_iter.bi_sector, bio->bi_iter.bi_size,
4e4cbee93   Christoph Hellwig   block: switch bio...
977
  			bio_op(bio), bio->bi_opf, BLK_TA_REMAP, bio->bi_status,
ca1136c99   Shaohua Li   blktrace: export ...
978
  			sizeof(r), &r, blk_trace_bio_get_cgid(q, bio));
6f9cff84d   Jan Kara   blktrace: Protect...
979
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
980
981
982
  }
  
  /**
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
983
   * blk_add_trace_rq_remap - Add a trace for a request-remap operation
546cf44a1   Randy Dunlap   blktrace: Fix new...
984
   * @ignore:	trace callback data parameter (not used)
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
985
986
987
988
989
990
991
992
993
994
   * @q:		queue the io is for
   * @rq:		the source request
   * @dev:	target device
   * @from:	source sector
   *
   * Description:
   *     Device mapper remaps request to other devices.
   *     Add a trace for that action.
   *
   **/
38516ab59   Steven Rostedt   tracing: Let trac...
995
996
  static void blk_add_trace_rq_remap(void *ignore,
  				   struct request_queue *q,
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
997
998
999
  				   struct request *rq, dev_t dev,
  				   sector_t from)
  {
6f9cff84d   Jan Kara   blktrace: Protect...
1000
  	struct blk_trace *bt;
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
1001
  	struct blk_io_trace_remap r;
6f9cff84d   Jan Kara   blktrace: Protect...
1002
1003
1004
1005
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
  	if (likely(!bt)) {
  		rcu_read_unlock();
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
1006
  		return;
6f9cff84d   Jan Kara   blktrace: Protect...
1007
  	}
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
1008
1009
1010
1011
1012
1013
  
  	r.device_from = cpu_to_be32(dev);
  	r.device_to   = cpu_to_be32(disk_devt(rq->rq_disk));
  	r.sector_from = cpu_to_be64(from);
  
  	__blk_add_trace(bt, blk_rq_pos(rq), blk_rq_bytes(rq),
caf7df122   Christoph Hellwig   block: remove the...
1014
  			rq_data_dir(rq), 0, BLK_TA_REMAP, 0,
ca1136c99   Shaohua Li   blktrace: export ...
1015
  			sizeof(r), &r, blk_trace_request_get_cgid(q, rq));
6f9cff84d   Jan Kara   blktrace: Protect...
1016
  	rcu_read_unlock();
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
1017
1018
1019
  }
  
  /**
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
   * blk_add_driver_data - Add binary message with driver-specific data
   * @q:		queue the io is for
   * @rq:		io request
   * @data:	driver-specific data
   * @len:	length of driver-specific data
   *
   * Description:
   *     Some drivers might want to write driver-specific data per request.
   *
   **/
  void blk_add_driver_data(struct request_queue *q,
  			 struct request *rq,
  			 void *data, size_t len)
  {
6f9cff84d   Jan Kara   blktrace: Protect...
1034
  	struct blk_trace *bt;
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1035

6f9cff84d   Jan Kara   blktrace: Protect...
1036
1037
1038
1039
  	rcu_read_lock();
  	bt = rcu_dereference(q->blk_trace);
  	if (likely(!bt)) {
  		rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1040
  		return;
6f9cff84d   Jan Kara   blktrace: Protect...
1041
  	}
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1042

48b77ad60   Christoph Hellwig   block: cleanup tr...
1043
  	__blk_add_trace(bt, blk_rq_trace_sector(rq), blk_rq_bytes(rq), 0, 0,
ca1136c99   Shaohua Li   blktrace: export ...
1044
1045
  				BLK_TA_DRV_DATA, 0, len, data,
  				blk_trace_request_get_cgid(q, rq));
6f9cff84d   Jan Kara   blktrace: Protect...
1046
  	rcu_read_unlock();
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1047
1048
  }
  EXPORT_SYMBOL_GPL(blk_add_driver_data);
3c289ba7c   Li Zefan   blktrace: remove ...
1049
  static void blk_register_tracepoints(void)
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1050
1051
  {
  	int ret;
38516ab59   Steven Rostedt   tracing: Let trac...
1052
  	ret = register_trace_block_rq_insert(blk_add_trace_rq_insert, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1053
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1054
  	ret = register_trace_block_rq_issue(blk_add_trace_rq_issue, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1055
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1056
  	ret = register_trace_block_rq_requeue(blk_add_trace_rq_requeue, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1057
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1058
  	ret = register_trace_block_rq_complete(blk_add_trace_rq_complete, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1059
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1060
  	ret = register_trace_block_bio_bounce(blk_add_trace_bio_bounce, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1061
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1062
  	ret = register_trace_block_bio_complete(blk_add_trace_bio_complete, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1063
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1064
  	ret = register_trace_block_bio_backmerge(blk_add_trace_bio_backmerge, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1065
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1066
  	ret = register_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1067
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1068
  	ret = register_trace_block_bio_queue(blk_add_trace_bio_queue, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1069
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1070
  	ret = register_trace_block_getrq(blk_add_trace_getrq, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1071
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1072
  	ret = register_trace_block_sleeprq(blk_add_trace_sleeprq, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1073
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1074
  	ret = register_trace_block_plug(blk_add_trace_plug, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1075
  	WARN_ON(ret);
49cac01e1   Jens Axboe   block: make unplu...
1076
  	ret = register_trace_block_unplug(blk_add_trace_unplug, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1077
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1078
  	ret = register_trace_block_split(blk_add_trace_split, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1079
  	WARN_ON(ret);
d07335e51   Mike Snitzer   block: Rename "bl...
1080
  	ret = register_trace_block_bio_remap(blk_add_trace_bio_remap, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1081
  	WARN_ON(ret);
38516ab59   Steven Rostedt   tracing: Let trac...
1082
  	ret = register_trace_block_rq_remap(blk_add_trace_rq_remap, NULL);
b0da3f0da   Jun'ichi Nomura   Add a tracepoint ...
1083
  	WARN_ON(ret);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1084
1085
1086
1087
  }
  
  static void blk_unregister_tracepoints(void)
  {
38516ab59   Steven Rostedt   tracing: Let trac...
1088
  	unregister_trace_block_rq_remap(blk_add_trace_rq_remap, NULL);
d07335e51   Mike Snitzer   block: Rename "bl...
1089
  	unregister_trace_block_bio_remap(blk_add_trace_bio_remap, NULL);
38516ab59   Steven Rostedt   tracing: Let trac...
1090
  	unregister_trace_block_split(blk_add_trace_split, NULL);
49cac01e1   Jens Axboe   block: make unplu...
1091
  	unregister_trace_block_unplug(blk_add_trace_unplug, NULL);
38516ab59   Steven Rostedt   tracing: Let trac...
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
  	unregister_trace_block_plug(blk_add_trace_plug, NULL);
  	unregister_trace_block_sleeprq(blk_add_trace_sleeprq, NULL);
  	unregister_trace_block_getrq(blk_add_trace_getrq, NULL);
  	unregister_trace_block_bio_queue(blk_add_trace_bio_queue, NULL);
  	unregister_trace_block_bio_frontmerge(blk_add_trace_bio_frontmerge, NULL);
  	unregister_trace_block_bio_backmerge(blk_add_trace_bio_backmerge, NULL);
  	unregister_trace_block_bio_complete(blk_add_trace_bio_complete, NULL);
  	unregister_trace_block_bio_bounce(blk_add_trace_bio_bounce, NULL);
  	unregister_trace_block_rq_complete(blk_add_trace_rq_complete, NULL);
  	unregister_trace_block_rq_requeue(blk_add_trace_rq_requeue, NULL);
  	unregister_trace_block_rq_issue(blk_add_trace_rq_issue, NULL);
  	unregister_trace_block_rq_insert(blk_add_trace_rq_insert, NULL);
5f3ea37c7   Arnaldo Carvalho de Melo   blktrace: port to...
1104
1105
1106
  
  	tracepoint_synchronize_unregister();
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1107
1108
1109
1110
1111
1112
1113
  
  /*
   * struct blk_io_tracer formatting routines
   */
  
  static void fill_rwbs(char *rwbs, const struct blk_io_trace *t)
  {
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1114
  	int i = 0;
65796348e   Li Zefan   blktrace: fix wro...
1115
  	int tc = t->action >> BLK_TC_SHIFT;
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1116

ca1136c99   Shaohua Li   blktrace: export ...
1117
  	if ((t->action & ~__BLK_TN_CGROUP) == BLK_TN_MESSAGE) {
18cea4591   Li Zefan   blktrace: print o...
1118
1119
1120
  		rwbs[i++] = 'N';
  		goto out;
  	}
c09c47cae   Namhyung Kim   blktrace: add FLU...
1121
1122
  	if (tc & BLK_TC_FLUSH)
  		rwbs[i++] = 'F';
65796348e   Li Zefan   blktrace: fix wro...
1123
  	if (tc & BLK_TC_DISCARD)
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1124
  		rwbs[i++] = 'D';
65796348e   Li Zefan   blktrace: fix wro...
1125
  	else if (tc & BLK_TC_WRITE)
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1126
1127
1128
1129
1130
  		rwbs[i++] = 'W';
  	else if (t->bytes)
  		rwbs[i++] = 'R';
  	else
  		rwbs[i++] = 'N';
c09c47cae   Namhyung Kim   blktrace: add FLU...
1131
1132
  	if (tc & BLK_TC_FUA)
  		rwbs[i++] = 'F';
65796348e   Li Zefan   blktrace: fix wro...
1133
  	if (tc & BLK_TC_AHEAD)
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1134
  		rwbs[i++] = 'A';
65796348e   Li Zefan   blktrace: fix wro...
1135
  	if (tc & BLK_TC_SYNC)
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1136
  		rwbs[i++] = 'S';
65796348e   Li Zefan   blktrace: fix wro...
1137
  	if (tc & BLK_TC_META)
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1138
  		rwbs[i++] = 'M';
18cea4591   Li Zefan   blktrace: print o...
1139
  out:
157f9c00e   Arnaldo Carvalho de Melo   tracing/blktrace:...
1140
  	rwbs[i] = '\0';
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1141
1142
1143
1144
1145
1146
1147
  }
  
  static inline
  const struct blk_io_trace *te_blk_io_trace(const struct trace_entry *ent)
  {
  	return (const struct blk_io_trace *)ent;
  }
ca1136c99   Shaohua Li   blktrace: export ...
1148
1149
1150
1151
1152
1153
1154
  static inline const void *pdu_start(const struct trace_entry *ent, bool has_cg)
  {
  	return (void *)(te_blk_io_trace(ent) + 1) +
  		(has_cg ? sizeof(union kernfs_node_id) : 0);
  }
  
  static inline const void *cgid_start(const struct trace_entry *ent)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1155
  {
ca1136c99   Shaohua Li   blktrace: export ...
1156
1157
1158
1159
1160
1161
1162
  	return (void *)(te_blk_io_trace(ent) + 1);
  }
  
  static inline int pdu_real_len(const struct trace_entry *ent, bool has_cg)
  {
  	return te_blk_io_trace(ent)->pdu_len -
  			(has_cg ? sizeof(union kernfs_node_id) : 0);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1163
  }
66de7792c   Li Zefan   blktrace: fix out...
1164
1165
1166
1167
1168
1169
1170
1171
1172
  static inline u32 t_action(const struct trace_entry *ent)
  {
  	return te_blk_io_trace(ent)->action;
  }
  
  static inline u32 t_bytes(const struct trace_entry *ent)
  {
  	return te_blk_io_trace(ent)->bytes;
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
  static inline u32 t_sec(const struct trace_entry *ent)
  {
  	return te_blk_io_trace(ent)->bytes >> 9;
  }
  
  static inline unsigned long long t_sector(const struct trace_entry *ent)
  {
  	return te_blk_io_trace(ent)->sector;
  }
  
  static inline __u16 t_error(const struct trace_entry *ent)
  {
e0dc81bec   Li Zefan   blktrace: fix t_e...
1185
  	return te_blk_io_trace(ent)->error;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1186
  }
ca1136c99   Shaohua Li   blktrace: export ...
1187
  static __u64 get_pdu_int(const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1188
  {
ca1136c99   Shaohua Li   blktrace: export ...
1189
  	const __u64 *val = pdu_start(ent, has_cg);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1190
1191
1192
1193
  	return be64_to_cpu(*val);
  }
  
  static void get_pdu_remap(const struct trace_entry *ent,
ca1136c99   Shaohua Li   blktrace: export ...
1194
  			  struct blk_io_trace_remap *r, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1195
  {
ca1136c99   Shaohua Li   blktrace: export ...
1196
  	const struct blk_io_trace_remap *__r = pdu_start(ent, has_cg);
a42aaa3bb   Alan D. Brunelle   blktrace: correct...
1197
  	__u64 sector_from = __r->sector_from;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1198

c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1199
  	r->device_from = be32_to_cpu(__r->device_from);
a42aaa3bb   Alan D. Brunelle   blktrace: correct...
1200
1201
  	r->device_to   = be32_to_cpu(__r->device_to);
  	r->sector_from = be64_to_cpu(sector_from);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1202
  }
ca1136c99   Shaohua Li   blktrace: export ...
1203
1204
  typedef void (blk_log_action_t) (struct trace_iterator *iter, const char *act,
  	bool has_cg);
b6a4b0c3a   Li Zefan   blktrace: extract...
1205

ca1136c99   Shaohua Li   blktrace: export ...
1206
1207
  static void blk_log_action_classic(struct trace_iterator *iter, const char *act,
  	bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1208
  {
c09c47cae   Namhyung Kim   blktrace: add FLU...
1209
  	char rwbs[RWBS_LEN];
35ac51bfe   Li Zefan   blktrace: make cl...
1210
1211
  	unsigned long long ts  = iter->ts;
  	unsigned long nsec_rem = do_div(ts, NSEC_PER_SEC);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1212
  	unsigned secs	       = (unsigned long)ts;
b6a4b0c3a   Li Zefan   blktrace: extract...
1213
  	const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1214
1215
  
  	fill_rwbs(rwbs, t);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1216
1217
1218
1219
  	trace_seq_printf(&iter->seq,
  			 "%3d,%-3d %2d %5d.%09lu %5u %2s %3s ",
  			 MAJOR(t->device), MINOR(t->device), iter->cpu,
  			 secs, nsec_rem, iter->ent->pid, act, rwbs);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1220
  }
ca1136c99   Shaohua Li   blktrace: export ...
1221
1222
  static void blk_log_action(struct trace_iterator *iter, const char *act,
  	bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1223
  {
c09c47cae   Namhyung Kim   blktrace: add FLU...
1224
  	char rwbs[RWBS_LEN];
b6a4b0c3a   Li Zefan   blktrace: extract...
1225
  	const struct blk_io_trace *t = te_blk_io_trace(iter->ent);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1226
  	fill_rwbs(rwbs, t);
ca1136c99   Shaohua Li   blktrace: export ...
1227
1228
  	if (has_cg) {
  		const union kernfs_node_id *id = cgid_start(iter->ent);
69fd5c391   Shaohua Li   blktrace: add an ...
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
  		if (blk_tracer_flags.val & TRACE_BLK_OPT_CGNAME) {
  			char blkcg_name_buf[NAME_MAX + 1] = "<...>";
  
  			cgroup_path_from_kernfs_id(id, blkcg_name_buf,
  				sizeof(blkcg_name_buf));
  			trace_seq_printf(&iter->seq, "%3d,%-3d %s %2s %3s ",
  				 MAJOR(t->device), MINOR(t->device),
  				 blkcg_name_buf, act, rwbs);
  		} else
  			trace_seq_printf(&iter->seq,
  				 "%3d,%-3d %x,%-x %2s %3s ",
ca1136c99   Shaohua Li   blktrace: export ...
1240
1241
1242
1243
1244
  				 MAJOR(t->device), MINOR(t->device),
  				 id->ino, id->generation, act, rwbs);
  	} else
  		trace_seq_printf(&iter->seq, "%3d,%-3d %2s %3s ",
  				 MAJOR(t->device), MINOR(t->device), act, rwbs);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1245
  }
ca1136c99   Shaohua Li   blktrace: export ...
1246
1247
  static void blk_log_dump_pdu(struct trace_seq *s,
  	const struct trace_entry *ent, bool has_cg)
66de7792c   Li Zefan   blktrace: fix out...
1248
  {
049862579   Li Zefan   blktrace: pdu_buf...
1249
  	const unsigned char *pdu_buf;
66de7792c   Li Zefan   blktrace: fix out...
1250
  	int pdu_len;
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1251
  	int i, end;
66de7792c   Li Zefan   blktrace: fix out...
1252

ca1136c99   Shaohua Li   blktrace: export ...
1253
1254
  	pdu_buf = pdu_start(ent, has_cg);
  	pdu_len = pdu_real_len(ent, has_cg);
66de7792c   Li Zefan   blktrace: fix out...
1255
1256
  
  	if (!pdu_len)
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1257
  		return;
66de7792c   Li Zefan   blktrace: fix out...
1258
1259
1260
1261
1262
1263
  
  	/* find the last zero that needs to be printed */
  	for (end = pdu_len - 1; end >= 0; end--)
  		if (pdu_buf[end])
  			break;
  	end++;
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1264
  	trace_seq_putc(s, '(');
66de7792c   Li Zefan   blktrace: fix out...
1265
1266
  
  	for (i = 0; i < pdu_len; i++) {
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1267
1268
  		trace_seq_printf(s, "%s%02x",
  				 i == 0 ? "" : " ", pdu_buf[i]);
66de7792c   Li Zefan   blktrace: fix out...
1269
1270
1271
1272
1273
  
  		/*
  		 * stop when the rest is just zeroes and indicate so
  		 * with a ".." appended
  		 */
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1274
1275
1276
1277
  		if (i == end && end != pdu_len - 1) {
  			trace_seq_puts(s, " ..) ");
  			return;
  		}
66de7792c   Li Zefan   blktrace: fix out...
1278
  	}
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1279
  	trace_seq_puts(s, ") ");
66de7792c   Li Zefan   blktrace: fix out...
1280
  }
ca1136c99   Shaohua Li   blktrace: export ...
1281
  static void blk_log_generic(struct trace_seq *s, const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1282
  {
4ca530852   Steven Rostedt   tracing: protect ...
1283
1284
1285
  	char cmd[TASK_COMM_LEN];
  
  	trace_find_cmdline(ent->pid, cmd);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1286

66de7792c   Li Zefan   blktrace: fix out...
1287
  	if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) {
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1288
  		trace_seq_printf(s, "%u ", t_bytes(ent));
ca1136c99   Shaohua Li   blktrace: export ...
1289
  		blk_log_dump_pdu(s, ent, has_cg);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1290
1291
  		trace_seq_printf(s, "[%s]
  ", cmd);
66de7792c   Li Zefan   blktrace: fix out...
1292
1293
  	} else {
  		if (t_sec(ent))
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1294
1295
  			trace_seq_printf(s, "%llu + %u [%s]
  ",
66de7792c   Li Zefan   blktrace: fix out...
1296
  						t_sector(ent), t_sec(ent), cmd);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1297
1298
1299
  		else
  			trace_seq_printf(s, "[%s]
  ", cmd);
66de7792c   Li Zefan   blktrace: fix out...
1300
  	}
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1301
  }
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1302
  static void blk_log_with_error(struct trace_seq *s,
ca1136c99   Shaohua Li   blktrace: export ...
1303
  			      const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1304
  {
66de7792c   Li Zefan   blktrace: fix out...
1305
  	if (t_action(ent) & BLK_TC_ACT(BLK_TC_PC)) {
ca1136c99   Shaohua Li   blktrace: export ...
1306
  		blk_log_dump_pdu(s, ent, has_cg);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1307
1308
  		trace_seq_printf(s, "[%d]
  ", t_error(ent));
66de7792c   Li Zefan   blktrace: fix out...
1309
1310
  	} else {
  		if (t_sec(ent))
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1311
1312
1313
1314
1315
1316
1317
1318
  			trace_seq_printf(s, "%llu + %u [%d]
  ",
  					 t_sector(ent),
  					 t_sec(ent), t_error(ent));
  		else
  			trace_seq_printf(s, "%llu [%d]
  ",
  					 t_sector(ent), t_error(ent));
66de7792c   Li Zefan   blktrace: fix out...
1319
  	}
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1320
  }
ca1136c99   Shaohua Li   blktrace: export ...
1321
  static void blk_log_remap(struct trace_seq *s, const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1322
  {
a42aaa3bb   Alan D. Brunelle   blktrace: correct...
1323
  	struct blk_io_trace_remap r = { .device_from = 0, };
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1324

ca1136c99   Shaohua Li   blktrace: export ...
1325
  	get_pdu_remap(ent, &r, has_cg);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1326
1327
1328
1329
1330
  	trace_seq_printf(s, "%llu + %u <- (%d,%d) %llu
  ",
  			 t_sector(ent), t_sec(ent),
  			 MAJOR(r.device_from), MINOR(r.device_from),
  			 (unsigned long long)r.sector_from);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1331
  }
ca1136c99   Shaohua Li   blktrace: export ...
1332
  static void blk_log_plug(struct trace_seq *s, const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1333
  {
4ca530852   Steven Rostedt   tracing: protect ...
1334
1335
1336
  	char cmd[TASK_COMM_LEN];
  
  	trace_find_cmdline(ent->pid, cmd);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1337
1338
  	trace_seq_printf(s, "[%s]
  ", cmd);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1339
  }
ca1136c99   Shaohua Li   blktrace: export ...
1340
  static void blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1341
  {
4ca530852   Steven Rostedt   tracing: protect ...
1342
1343
1344
  	char cmd[TASK_COMM_LEN];
  
  	trace_find_cmdline(ent->pid, cmd);
ca1136c99   Shaohua Li   blktrace: export ...
1345
1346
  	trace_seq_printf(s, "[%s] %llu
  ", cmd, get_pdu_int(ent, has_cg));
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1347
  }
ca1136c99   Shaohua Li   blktrace: export ...
1348
  static void blk_log_split(struct trace_seq *s, const struct trace_entry *ent, bool has_cg)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1349
  {
4ca530852   Steven Rostedt   tracing: protect ...
1350
1351
1352
  	char cmd[TASK_COMM_LEN];
  
  	trace_find_cmdline(ent->pid, cmd);
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1353
1354
  	trace_seq_printf(s, "%llu / %llu [%s]
  ", t_sector(ent),
ca1136c99   Shaohua Li   blktrace: export ...
1355
  			 get_pdu_int(ent, has_cg), cmd);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1356
  }
ca1136c99   Shaohua Li   blktrace: export ...
1357
1358
  static void blk_log_msg(struct trace_seq *s, const struct trace_entry *ent,
  			bool has_cg)
18cea4591   Li Zefan   blktrace: print o...
1359
  {
18cea4591   Li Zefan   blktrace: print o...
1360

ca1136c99   Shaohua Li   blktrace: export ...
1361
1362
  	trace_seq_putmem(s, pdu_start(ent, has_cg),
  		pdu_real_len(ent, has_cg));
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1363
1364
  	trace_seq_putc(s, '
  ');
18cea4591   Li Zefan   blktrace: print o...
1365
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
  /*
   * struct tracer operations
   */
  
  static void blk_tracer_print_header(struct seq_file *m)
  {
  	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
  		return;
  	seq_puts(m, "# DEV   CPU TIMESTAMP     PID ACT FLG
  "
  		    "#  |     |     |           |   |   |
  ");
  }
  
  static void blk_tracer_start(struct trace_array *tr)
  {
ad5dd5493   Li Zefan   blktrace: fix mem...
1382
  	blk_tracer_enabled = true;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1383
1384
1385
1386
1387
1388
  }
  
  static int blk_tracer_init(struct trace_array *tr)
  {
  	blk_tr = tr;
  	blk_tracer_start(tr);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1389
1390
1391
1392
1393
  	return 0;
  }
  
  static void blk_tracer_stop(struct trace_array *tr)
  {
ad5dd5493   Li Zefan   blktrace: fix mem...
1394
  	blk_tracer_enabled = false;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1395
1396
1397
1398
  }
  
  static void blk_tracer_reset(struct trace_array *tr)
  {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1399
1400
  	blk_tracer_stop(tr);
  }
e4955c998   Li Zefan   blktrace: mark dd...
1401
  static const struct {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1402
  	const char *act[2];
ca1136c99   Shaohua Li   blktrace: export ...
1403
1404
  	void	   (*print)(struct trace_seq *s, const struct trace_entry *ent,
  			    bool has_cg);
e4955c998   Li Zefan   blktrace: mark dd...
1405
  } what2act[] = {
ef18012b2   Steven Rostedt   tracing: remove f...
1406
  	[__BLK_TA_QUEUE]	= {{  "Q", "queue" },	   blk_log_generic },
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1407
1408
1409
1410
1411
1412
1413
1414
1415
  	[__BLK_TA_BACKMERGE]	= {{  "M", "backmerge" },  blk_log_generic },
  	[__BLK_TA_FRONTMERGE]	= {{  "F", "frontmerge" }, blk_log_generic },
  	[__BLK_TA_GETRQ]	= {{  "G", "getrq" },	   blk_log_generic },
  	[__BLK_TA_SLEEPRQ]	= {{  "S", "sleeprq" },	   blk_log_generic },
  	[__BLK_TA_REQUEUE]	= {{  "R", "requeue" },	   blk_log_with_error },
  	[__BLK_TA_ISSUE]	= {{  "D", "issue" },	   blk_log_generic },
  	[__BLK_TA_COMPLETE]	= {{  "C", "complete" },   blk_log_with_error },
  	[__BLK_TA_PLUG]		= {{  "P", "plug" },	   blk_log_plug },
  	[__BLK_TA_UNPLUG_IO]	= {{  "U", "unplug_io" },  blk_log_unplug },
49cac01e1   Jens Axboe   block: make unplu...
1416
  	[__BLK_TA_UNPLUG_TIMER]	= {{ "UT", "unplug_timer" }, blk_log_unplug },
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1417
1418
1419
1420
1421
  	[__BLK_TA_INSERT]	= {{  "I", "insert" },	   blk_log_generic },
  	[__BLK_TA_SPLIT]	= {{  "X", "split" },	   blk_log_split },
  	[__BLK_TA_BOUNCE]	= {{  "B", "bounce" },	   blk_log_generic },
  	[__BLK_TA_REMAP]	= {{  "A", "remap" },	   blk_log_remap },
  };
b6a4b0c3a   Li Zefan   blktrace: extract...
1422
1423
  static enum print_line_t print_one_line(struct trace_iterator *iter,
  					bool classic)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1424
  {
983f938ae   Steven Rostedt (Red Hat)   tracing: Move tra...
1425
  	struct trace_array *tr = iter->tr;
2c9b238eb   Arnaldo Carvalho de Melo   trace: Change str...
1426
  	struct trace_seq *s = &iter->seq;
b6a4b0c3a   Li Zefan   blktrace: extract...
1427
1428
  	const struct blk_io_trace *t;
  	u16 what;
b6a4b0c3a   Li Zefan   blktrace: extract...
1429
1430
  	bool long_act;
  	blk_log_action_t *log_action;
ca1136c99   Shaohua Li   blktrace: export ...
1431
  	bool has_cg;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1432

b6a4b0c3a   Li Zefan   blktrace: extract...
1433
  	t	   = te_blk_io_trace(iter->ent);
ca1136c99   Shaohua Li   blktrace: export ...
1434
  	what	   = (t->action & ((1 << BLK_TC_SHIFT) - 1)) & ~__BLK_TA_CGROUP;
983f938ae   Steven Rostedt (Red Hat)   tracing: Move tra...
1435
  	long_act   = !!(tr->trace_flags & TRACE_ITER_VERBOSE);
b6a4b0c3a   Li Zefan   blktrace: extract...
1436
  	log_action = classic ? &blk_log_action_classic : &blk_log_action;
ca1136c99   Shaohua Li   blktrace: export ...
1437
  	has_cg	   = t->action & __BLK_TA_CGROUP;
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1438

ca1136c99   Shaohua Li   blktrace: export ...
1439
1440
1441
  	if ((t->action & ~__BLK_TN_CGROUP) == BLK_TN_MESSAGE) {
  		log_action(iter, long_act ? "message" : "m", has_cg);
  		blk_log_msg(s, iter->ent, has_cg);
b7d7641e2   Shaohua Li   blktrace: delete ...
1442
  		return trace_handle_return(s);
18cea4591   Li Zefan   blktrace: print o...
1443
  	}
eb08f8eb0   Li Zefan   blktrace: fix off...
1444
  	if (unlikely(what == 0 || what >= ARRAY_SIZE(what2act)))
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1445
1446
  		trace_seq_printf(s, "Unknown action %x
  ", what);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1447
  	else {
ca1136c99   Shaohua Li   blktrace: export ...
1448
1449
  		log_action(iter, what2act[what].act[long_act], has_cg);
  		what2act[what].print(s, iter->ent, has_cg);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1450
  	}
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1451
1452
  
  	return trace_handle_return(s);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1453
  }
b6a4b0c3a   Li Zefan   blktrace: extract...
1454
  static enum print_line_t blk_trace_event_print(struct trace_iterator *iter,
a9a577638   Steven Rostedt   tracing: Allow ev...
1455
  					       int flags, struct trace_event *event)
b6a4b0c3a   Li Zefan   blktrace: extract...
1456
  {
b6a4b0c3a   Li Zefan   blktrace: extract...
1457
1458
  	return print_one_line(iter, false);
  }
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1459
  static void blk_trace_synthesize_old_trace(struct trace_iterator *iter)
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1460
1461
1462
1463
1464
1465
  {
  	struct trace_seq *s = &iter->seq;
  	struct blk_io_trace *t = (struct blk_io_trace *)iter->ent;
  	const int offset = offsetof(struct blk_io_trace, sector);
  	struct blk_io_trace old = {
  		.magic	  = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION,
6c051ce03   Li Zefan   blktrace: fix tim...
1466
  		.time     = iter->ts,
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1467
  	};
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1468
1469
1470
  	trace_seq_putmem(s, &old, offset);
  	trace_seq_putmem(s, &t->sector,
  			 sizeof(old) - offset + t->pdu_len);
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1471
  }
ae7462b4f   Arnaldo Carvalho de Melo   trace: make the t...
1472
  static enum print_line_t
a9a577638   Steven Rostedt   tracing: Allow ev...
1473
1474
  blk_trace_event_print_binary(struct trace_iterator *iter, int flags,
  			     struct trace_event *event)
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1475
  {
f4a1d08ce   Steven Rostedt (Red Hat)   blktrace/tracing:...
1476
1477
1478
  	blk_trace_synthesize_old_trace(iter);
  
  	return trace_handle_return(&iter->seq);
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1479
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1480
1481
  static enum print_line_t blk_tracer_print_line(struct trace_iterator *iter)
  {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1482
1483
  	if (!(blk_tracer_flags.val & TRACE_BLK_OPT_CLASSIC))
  		return TRACE_TYPE_UNHANDLED;
b6a4b0c3a   Li Zefan   blktrace: extract...
1484
  	return print_one_line(iter, true);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1485
  }
8c1a49aed   Steven Rostedt (Red Hat)   tracing: Pass tra...
1486
1487
  static int
  blk_tracer_set_flag(struct trace_array *tr, u32 old_flags, u32 bit, int set)
f3948f885   Li Zefan   blktrace: fix con...
1488
1489
1490
1491
  {
  	/* don't output context-info for blk_classic output */
  	if (bit == TRACE_BLK_OPT_CLASSIC) {
  		if (set)
983f938ae   Steven Rostedt (Red Hat)   tracing: Move tra...
1492
  			tr->trace_flags &= ~TRACE_ITER_CONTEXT_INFO;
f3948f885   Li Zefan   blktrace: fix con...
1493
  		else
983f938ae   Steven Rostedt (Red Hat)   tracing: Move tra...
1494
  			tr->trace_flags |= TRACE_ITER_CONTEXT_INFO;
f3948f885   Li Zefan   blktrace: fix con...
1495
1496
1497
  	}
  	return 0;
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1498
1499
1500
1501
1502
1503
1504
1505
1506
  static struct tracer blk_tracer __read_mostly = {
  	.name		= "blk",
  	.init		= blk_tracer_init,
  	.reset		= blk_tracer_reset,
  	.start		= blk_tracer_start,
  	.stop		= blk_tracer_stop,
  	.print_header	= blk_tracer_print_header,
  	.print_line	= blk_tracer_print_line,
  	.flags		= &blk_tracer_flags,
f3948f885   Li Zefan   blktrace: fix con...
1507
  	.set_flag	= blk_tracer_set_flag,
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1508
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1509
  static struct trace_event_functions trace_blk_event_funcs = {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1510
  	.trace		= blk_trace_event_print,
08a06b83f   Arnaldo Carvalho de Melo   blkftrace: binary...
1511
  	.binary		= blk_trace_event_print_binary,
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1512
  };
a9a577638   Steven Rostedt   tracing: Allow ev...
1513
1514
1515
1516
  static struct trace_event trace_blk_event = {
  	.type		= TRACE_BLK,
  	.funcs		= &trace_blk_event_funcs,
  };
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1517
1518
  static int __init init_blk_tracer(void)
  {
9023c9309   Steven Rostedt (Red Hat)   tracing: Rename (...
1519
  	if (!register_trace_event(&trace_blk_event)) {
a395d6a7e   Joe Perches   kernel/...: conve...
1520
1521
  		pr_warn("Warning: could not register block events
  ");
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1522
1523
1524
1525
  		return 1;
  	}
  
  	if (register_tracer(&blk_tracer) != 0) {
a395d6a7e   Joe Perches   kernel/...: conve...
1526
1527
  		pr_warn("Warning: could not register the block tracer
  ");
9023c9309   Steven Rostedt (Red Hat)   tracing: Rename (...
1528
  		unregister_trace_event(&trace_blk_event);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
  		return 1;
  	}
  
  	return 0;
  }
  
  device_initcall(init_blk_tracer);
  
  static int blk_trace_remove_queue(struct request_queue *q)
  {
  	struct blk_trace *bt;
  
  	bt = xchg(&q->blk_trace, NULL);
  	if (bt == NULL)
  		return -EINVAL;
a6da0024f   Jens Axboe   blktrace: fix unl...
1544
  	put_probe_ref();
6f9cff84d   Jan Kara   blktrace: Protect...
1545
  	synchronize_rcu();
ad5dd5493   Li Zefan   blktrace: fix mem...
1546
  	blk_trace_free(bt);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1547
1548
1549
1550
1551
1552
  	return 0;
  }
  
  /*
   * Setup everything required to start tracing
   */
9908c3099   Li Zefan   blktrace: support...
1553
1554
  static int blk_trace_setup_queue(struct request_queue *q,
  				 struct block_device *bdev)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1555
  {
cdea01b2b   Davidlohr Bueso   blktrace: re-writ...
1556
  	struct blk_trace *bt = NULL;
18cea4591   Li Zefan   blktrace: print o...
1557
  	int ret = -ENOMEM;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1558

c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1559
1560
  	bt = kzalloc(sizeof(*bt), GFP_KERNEL);
  	if (!bt)
15152e448   Li Zefan   blktrace: report ...
1561
  		return -ENOMEM;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1562

18cea4591   Li Zefan   blktrace: print o...
1563
1564
1565
  	bt->msg_data = __alloc_percpu(BLK_TN_MAX_MSG, __alignof__(char));
  	if (!bt->msg_data)
  		goto free_bt;
9908c3099   Li Zefan   blktrace: support...
1566
  	bt->dev = bdev->bd_dev;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1567
  	bt->act_mask = (u16)-1;
9908c3099   Li Zefan   blktrace: support...
1568
1569
  
  	blk_trace_setup_lba(bt, bdev);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1570

cdea01b2b   Davidlohr Bueso   blktrace: re-writ...
1571
1572
  	ret = -EBUSY;
  	if (cmpxchg(&q->blk_trace, NULL, bt))
18cea4591   Li Zefan   blktrace: print o...
1573
  		goto free_bt;
15152e448   Li Zefan   blktrace: report ...
1574

a6da0024f   Jens Axboe   blktrace: fix unl...
1575
  	get_probe_ref();
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1576
  	return 0;
18cea4591   Li Zefan   blktrace: print o...
1577
1578
1579
1580
  
  free_bt:
  	blk_trace_free(bt);
  	return ret;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1581
1582
1583
1584
1585
  }
  
  /*
   * sysfs interface to enable and configure tracing
   */
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
  static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
  					 struct device_attribute *attr,
  					 char *buf);
  static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
  					  struct device_attribute *attr,
  					  const char *buf, size_t count);
  #define BLK_TRACE_DEVICE_ATTR(_name) \
  	DEVICE_ATTR(_name, S_IRUGO | S_IWUSR, \
  		    sysfs_blk_trace_attr_show, \
  		    sysfs_blk_trace_attr_store)
cd649b8bb   Li Zefan   blktrace: remove ...
1596
  static BLK_TRACE_DEVICE_ATTR(enable);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
  static BLK_TRACE_DEVICE_ATTR(act_mask);
  static BLK_TRACE_DEVICE_ATTR(pid);
  static BLK_TRACE_DEVICE_ATTR(start_lba);
  static BLK_TRACE_DEVICE_ATTR(end_lba);
  
  static struct attribute *blk_trace_attrs[] = {
  	&dev_attr_enable.attr,
  	&dev_attr_act_mask.attr,
  	&dev_attr_pid.attr,
  	&dev_attr_start_lba.attr,
  	&dev_attr_end_lba.attr,
  	NULL
  };
  
  struct attribute_group blk_trace_attr_group = {
  	.name  = "trace",
  	.attrs = blk_trace_attrs,
  };
093419971   Li Zefan   blktrace: print h...
1615
1616
1617
1618
1619
1620
  static const struct {
  	int mask;
  	const char *str;
  } mask_maps[] = {
  	{ BLK_TC_READ,		"read"		},
  	{ BLK_TC_WRITE,		"write"		},
c09c47cae   Namhyung Kim   blktrace: add FLU...
1621
  	{ BLK_TC_FLUSH,		"flush"		},
093419971   Li Zefan   blktrace: print h...
1622
1623
1624
1625
1626
1627
1628
  	{ BLK_TC_SYNC,		"sync"		},
  	{ BLK_TC_QUEUE,		"queue"		},
  	{ BLK_TC_REQUEUE,	"requeue"	},
  	{ BLK_TC_ISSUE,		"issue"		},
  	{ BLK_TC_COMPLETE,	"complete"	},
  	{ BLK_TC_FS,		"fs"		},
  	{ BLK_TC_PC,		"pc"		},
8d1547e08   Shaohua Li   blktrace: add mis...
1629
  	{ BLK_TC_NOTIFY,	"notify"	},
093419971   Li Zefan   blktrace: print h...
1630
1631
1632
1633
  	{ BLK_TC_AHEAD,		"ahead"		},
  	{ BLK_TC_META,		"meta"		},
  	{ BLK_TC_DISCARD,	"discard"	},
  	{ BLK_TC_DRV_DATA,	"drv_data"	},
c09c47cae   Namhyung Kim   blktrace: add FLU...
1634
  	{ BLK_TC_FUA,		"fua"		},
093419971   Li Zefan   blktrace: print h...
1635
1636
1637
  };
  
  static int blk_trace_str2mask(const char *str)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1638
  {
093419971   Li Zefan   blktrace: print h...
1639
  	int i;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1640
  	int mask = 0;
9eb85125c   Li Zefan   blktrace: pass th...
1641
  	char *buf, *s, *token;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1642

9eb85125c   Li Zefan   blktrace: pass th...
1643
1644
  	buf = kstrdup(str, GFP_KERNEL);
  	if (buf == NULL)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1645
  		return -ENOMEM;
9eb85125c   Li Zefan   blktrace: pass th...
1646
  	s = strstrip(buf);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1647
1648
  
  	while (1) {
093419971   Li Zefan   blktrace: print h...
1649
1650
  		token = strsep(&s, ",");
  		if (token == NULL)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1651
  			break;
093419971   Li Zefan   blktrace: print h...
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
  		if (*token == '\0')
  			continue;
  
  		for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
  			if (strcasecmp(token, mask_maps[i].str) == 0) {
  				mask |= mask_maps[i].mask;
  				break;
  			}
  		}
  		if (i == ARRAY_SIZE(mask_maps)) {
  			mask = -EINVAL;
  			break;
  		}
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1665
  	}
9eb85125c   Li Zefan   blktrace: pass th...
1666
  	kfree(buf);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1667
1668
1669
  
  	return mask;
  }
093419971   Li Zefan   blktrace: print h...
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
  static ssize_t blk_trace_mask2str(char *buf, int mask)
  {
  	int i;
  	char *p = buf;
  
  	for (i = 0; i < ARRAY_SIZE(mask_maps); i++) {
  		if (mask & mask_maps[i].mask) {
  			p += sprintf(p, "%s%s",
  				    (p == buf) ? "" : ",", mask_maps[i].str);
  		}
  	}
  	*p++ = '
  ';
  
  	return p - buf;
  }
b125130b2   Li Zefan   blktrace: avoid a...
1686
1687
1688
1689
1690
1691
1692
  static struct request_queue *blk_trace_get_queue(struct block_device *bdev)
  {
  	if (bdev->bd_disk == NULL)
  		return NULL;
  
  	return bdev_get_queue(bdev);
  }
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1693
1694
1695
1696
1697
1698
1699
  static ssize_t sysfs_blk_trace_attr_show(struct device *dev,
  					 struct device_attribute *attr,
  					 char *buf)
  {
  	struct hd_struct *p = dev_to_part(dev);
  	struct request_queue *q;
  	struct block_device *bdev;
6f9cff84d   Jan Kara   blktrace: Protect...
1700
  	struct blk_trace *bt;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1701
  	ssize_t ret = -ENXIO;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1702
1703
  	bdev = bdget(part_devt(p));
  	if (bdev == NULL)
01b284f9b   Arnd Bergmann   blktrace: remove ...
1704
  		goto out;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1705

b125130b2   Li Zefan   blktrace: avoid a...
1706
  	q = blk_trace_get_queue(bdev);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1707
1708
  	if (q == NULL)
  		goto out_bdput;
b125130b2   Li Zefan   blktrace: avoid a...
1709

5acb3cc2c   Waiman Long   blktrace: Fix pot...
1710
  	mutex_lock(&q->blk_trace_mutex);
cd649b8bb   Li Zefan   blktrace: remove ...
1711

6f9cff84d   Jan Kara   blktrace: Protect...
1712
1713
  	bt = rcu_dereference_protected(q->blk_trace,
  				       lockdep_is_held(&q->blk_trace_mutex));
cd649b8bb   Li Zefan   blktrace: remove ...
1714
  	if (attr == &dev_attr_enable) {
6f9cff84d   Jan Kara   blktrace: Protect...
1715
1716
  		ret = sprintf(buf, "%u
  ", !!bt);
cd649b8bb   Li Zefan   blktrace: remove ...
1717
1718
  		goto out_unlock_bdev;
  	}
6f9cff84d   Jan Kara   blktrace: Protect...
1719
  	if (bt == NULL)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1720
1721
1722
  		ret = sprintf(buf, "disabled
  ");
  	else if (attr == &dev_attr_act_mask)
6f9cff84d   Jan Kara   blktrace: Protect...
1723
  		ret = blk_trace_mask2str(buf, bt->act_mask);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1724
  	else if (attr == &dev_attr_pid)
6f9cff84d   Jan Kara   blktrace: Protect...
1725
1726
  		ret = sprintf(buf, "%u
  ", bt->pid);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1727
  	else if (attr == &dev_attr_start_lba)
6f9cff84d   Jan Kara   blktrace: Protect...
1728
1729
  		ret = sprintf(buf, "%llu
  ", bt->start_lba);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1730
  	else if (attr == &dev_attr_end_lba)
6f9cff84d   Jan Kara   blktrace: Protect...
1731
1732
  		ret = sprintf(buf, "%llu
  ", bt->end_lba);
cd649b8bb   Li Zefan   blktrace: remove ...
1733
1734
  
  out_unlock_bdev:
5acb3cc2c   Waiman Long   blktrace: Fix pot...
1735
  	mutex_unlock(&q->blk_trace_mutex);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1736
1737
  out_bdput:
  	bdput(bdev);
01b284f9b   Arnd Bergmann   blktrace: remove ...
1738
  out:
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
  	return ret;
  }
  
  static ssize_t sysfs_blk_trace_attr_store(struct device *dev,
  					  struct device_attribute *attr,
  					  const char *buf, size_t count)
  {
  	struct block_device *bdev;
  	struct request_queue *q;
  	struct hd_struct *p;
6f9cff84d   Jan Kara   blktrace: Protect...
1749
  	struct blk_trace *bt;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1750
  	u64 value;
093419971   Li Zefan   blktrace: print h...
1751
  	ssize_t ret = -EINVAL;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1752
1753
1754
1755
1756
  
  	if (count == 0)
  		goto out;
  
  	if (attr == &dev_attr_act_mask) {
5f3394530   Shaohua Li   blktrace: fix int...
1757
  		if (kstrtoull(buf, 0, &value)) {
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1758
  			/* Assume it is a list of trace category names */
093419971   Li Zefan   blktrace: print h...
1759
1760
  			ret = blk_trace_str2mask(buf);
  			if (ret < 0)
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1761
  				goto out;
093419971   Li Zefan   blktrace: print h...
1762
  			value = ret;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1763
  		}
5f3394530   Shaohua Li   blktrace: fix int...
1764
  	} else if (kstrtoull(buf, 0, &value))
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1765
  		goto out;
093419971   Li Zefan   blktrace: print h...
1766
  	ret = -ENXIO;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1767
1768
1769
  	p = dev_to_part(dev);
  	bdev = bdget(part_devt(p));
  	if (bdev == NULL)
01b284f9b   Arnd Bergmann   blktrace: remove ...
1770
  		goto out;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1771

b125130b2   Li Zefan   blktrace: avoid a...
1772
  	q = blk_trace_get_queue(bdev);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1773
1774
  	if (q == NULL)
  		goto out_bdput;
5acb3cc2c   Waiman Long   blktrace: Fix pot...
1775
  	mutex_lock(&q->blk_trace_mutex);
cd649b8bb   Li Zefan   blktrace: remove ...
1776

6f9cff84d   Jan Kara   blktrace: Protect...
1777
1778
  	bt = rcu_dereference_protected(q->blk_trace,
  				       lockdep_is_held(&q->blk_trace_mutex));
cd649b8bb   Li Zefan   blktrace: remove ...
1779
  	if (attr == &dev_attr_enable) {
6f9cff84d   Jan Kara   blktrace: Protect...
1780
  		if (!!value == !!bt) {
757d91400   Steven Rostedt (VMware)   tracing/blktrace:...
1781
1782
1783
  			ret = 0;
  			goto out_unlock_bdev;
  		}
cd649b8bb   Li Zefan   blktrace: remove ...
1784
  		if (value)
9908c3099   Li Zefan   blktrace: support...
1785
  			ret = blk_trace_setup_queue(q, bdev);
cd649b8bb   Li Zefan   blktrace: remove ...
1786
1787
1788
1789
  		else
  			ret = blk_trace_remove_queue(q);
  		goto out_unlock_bdev;
  	}
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1790
  	ret = 0;
6f9cff84d   Jan Kara   blktrace: Protect...
1791
  	if (bt == NULL)
9908c3099   Li Zefan   blktrace: support...
1792
  		ret = blk_trace_setup_queue(q, bdev);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1793
1794
1795
  
  	if (ret == 0) {
  		if (attr == &dev_attr_act_mask)
6f9cff84d   Jan Kara   blktrace: Protect...
1796
  			bt->act_mask = value;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1797
  		else if (attr == &dev_attr_pid)
6f9cff84d   Jan Kara   blktrace: Protect...
1798
  			bt->pid = value;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1799
  		else if (attr == &dev_attr_start_lba)
6f9cff84d   Jan Kara   blktrace: Protect...
1800
  			bt->start_lba = value;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1801
  		else if (attr == &dev_attr_end_lba)
6f9cff84d   Jan Kara   blktrace: Protect...
1802
  			bt->end_lba = value;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1803
  	}
cd649b8bb   Li Zefan   blktrace: remove ...
1804
1805
  
  out_unlock_bdev:
5acb3cc2c   Waiman Long   blktrace: Fix pot...
1806
  	mutex_unlock(&q->blk_trace_mutex);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1807
1808
  out_bdput:
  	bdput(bdev);
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1809
  out:
cd649b8bb   Li Zefan   blktrace: remove ...
1810
  	return ret ? ret : count;
c71a89615   Arnaldo Carvalho de Melo   blktrace: add ftr...
1811
  }
cd649b8bb   Li Zefan   blktrace: remove ...
1812

1d54ad6da   Li Zefan   blktrace: add tra...
1813
1814
1815
1816
  int blk_trace_init_sysfs(struct device *dev)
  {
  	return sysfs_create_group(&dev->kobj, &blk_trace_attr_group);
  }
48c0d4d4c   Zdenek Kabelac   Add missing blk_t...
1817
1818
1819
1820
  void blk_trace_remove_sysfs(struct device *dev)
  {
  	sysfs_remove_group(&dev->kobj, &blk_trace_attr_group);
  }
55782138e   Li Zefan   tracing/events: c...
1821
1822
1823
  #endif /* CONFIG_BLK_DEV_IO_TRACE */
  
  #ifdef CONFIG_EVENT_TRACING
ef295ecf0   Christoph Hellwig   block: better op ...
1824
  void blk_fill_rwbs(char *rwbs, unsigned int op, int bytes)
55782138e   Li Zefan   tracing/events: c...
1825
1826
  {
  	int i = 0;
ef295ecf0   Christoph Hellwig   block: better op ...
1827
  	if (op & REQ_PREFLUSH)
c09c47cae   Namhyung Kim   blktrace: add FLU...
1828
  		rwbs[i++] = 'F';
ef295ecf0   Christoph Hellwig   block: better op ...
1829
  	switch (op & REQ_OP_MASK) {
1b9a9ab78   Mike Christie   blktrace: use op ...
1830
1831
  	case REQ_OP_WRITE:
  	case REQ_OP_WRITE_SAME:
55782138e   Li Zefan   tracing/events: c...
1832
  		rwbs[i++] = 'W';
1b9a9ab78   Mike Christie   blktrace: use op ...
1833
1834
  		break;
  	case REQ_OP_DISCARD:
55782138e   Li Zefan   tracing/events: c...
1835
  		rwbs[i++] = 'D';
1b9a9ab78   Mike Christie   blktrace: use op ...
1836
  		break;
288dab8a3   Christoph Hellwig   block: add a sepa...
1837
1838
1839
1840
  	case REQ_OP_SECURE_ERASE:
  		rwbs[i++] = 'D';
  		rwbs[i++] = 'E';
  		break;
3a5e02ced   Mike Christie   block, drivers: a...
1841
1842
1843
  	case REQ_OP_FLUSH:
  		rwbs[i++] = 'F';
  		break;
1b9a9ab78   Mike Christie   blktrace: use op ...
1844
  	case REQ_OP_READ:
55782138e   Li Zefan   tracing/events: c...
1845
  		rwbs[i++] = 'R';
1b9a9ab78   Mike Christie   blktrace: use op ...
1846
1847
  		break;
  	default:
55782138e   Li Zefan   tracing/events: c...
1848
  		rwbs[i++] = 'N';
1b9a9ab78   Mike Christie   blktrace: use op ...
1849
  	}
55782138e   Li Zefan   tracing/events: c...
1850

ef295ecf0   Christoph Hellwig   block: better op ...
1851
  	if (op & REQ_FUA)
c09c47cae   Namhyung Kim   blktrace: add FLU...
1852
  		rwbs[i++] = 'F';
ef295ecf0   Christoph Hellwig   block: better op ...
1853
  	if (op & REQ_RAHEAD)
55782138e   Li Zefan   tracing/events: c...
1854
  		rwbs[i++] = 'A';
ef295ecf0   Christoph Hellwig   block: better op ...
1855
  	if (op & REQ_SYNC)
55782138e   Li Zefan   tracing/events: c...
1856
  		rwbs[i++] = 'S';
ef295ecf0   Christoph Hellwig   block: better op ...
1857
  	if (op & REQ_META)
55782138e   Li Zefan   tracing/events: c...
1858
1859
1860
1861
  		rwbs[i++] = 'M';
  
  	rwbs[i] = '\0';
  }
9ca8f8e51   Kent Overstreet   Export blk_fill_r...
1862
  EXPORT_SYMBOL_GPL(blk_fill_rwbs);
55782138e   Li Zefan   tracing/events: c...
1863

55782138e   Li Zefan   tracing/events: c...
1864
  #endif /* CONFIG_EVENT_TRACING */