xref: /linux/include/linux/blktrace_api.h (revision cdd5b5a9761fd66d17586e4f4ba6588c70e640ea)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
22056a782SJens Axboe #ifndef BLKTRACE_H
32056a782SJens Axboe #define BLKTRACE_H
42056a782SJens Axboe 
524b83debSChristoph Hellwig #include <linux/blk-mq.h>
62056a782SJens Axboe #include <linux/relay.h>
762c2a7d9SArnd Bergmann #include <linux/compat.h>
8607ca46eSDavid Howells #include <uapi/linux/blktrace_api.h>
9a404d557SJan Kara #include <linux/list.h>
10919dbca8SBart Van Assche #include <linux/blk_types.h>
112056a782SJens Axboe 
12c0ddffa8SSven Schuetz #if defined(CONFIG_BLK_DEV_IO_TRACE)
13157f9c00SArnaldo Carvalho de Melo 
14157f9c00SArnaldo Carvalho de Melo #include <linux/sysfs.h>
15157f9c00SArnaldo Carvalho de Melo 
162056a782SJens Axboe struct blk_trace {
172056a782SJens Axboe 	int trace_state;
182056a782SJens Axboe 	struct rchan *rchan;
1943cf38ebSTejun Heo 	unsigned long __percpu *sequence;
2043cf38ebSTejun Heo 	unsigned char __percpu *msg_data;
212056a782SJens Axboe 	u16 act_mask;
222056a782SJens Axboe 	u64 start_lba;
232056a782SJens Axboe 	u64 end_lba;
242056a782SJens Axboe 	u32 pid;
252056a782SJens Axboe 	u32 dev;
262056a782SJens Axboe 	struct dentry *dir;
27a404d557SJan Kara 	struct list_head running_list;
282056a782SJens Axboe 	atomic_t dropped;
292056a782SJens Axboe };
302056a782SJens Axboe 
312056a782SJens Axboe extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
32165125e1SJens Axboe extern void blk_trace_shutdown(struct request_queue *);
33f4a6a61cSChristoph Hellwig __printf(3, 4) void __blk_trace_note_message(struct blk_trace *bt,
34f4a6a61cSChristoph Hellwig 		struct cgroup_subsys_state *css, const char *fmt, ...);
35171044d4SArnd Bergmann 
369d5f09a4SAlan D. Brunelle /**
379d5f09a4SAlan D. Brunelle  * blk_add_trace_msg - Add a (simple) message to the blktrace stream
389d5f09a4SAlan D. Brunelle  * @q:		queue the io is for
399d5f09a4SAlan D. Brunelle  * @fmt:	format to print message in
409d5f09a4SAlan D. Brunelle  * args...	Variable argument list for format
419d5f09a4SAlan D. Brunelle  *
429d5f09a4SAlan D. Brunelle  * Description:
439d5f09a4SAlan D. Brunelle  *     Records a (simple) message onto the blktrace stream.
449d5f09a4SAlan D. Brunelle  *
459d5f09a4SAlan D. Brunelle  *     NOTE: BLK_TN_MAX_MSG characters are output at most.
469d5f09a4SAlan D. Brunelle  *     NOTE: Can not use 'static inline' due to presence of var args...
479d5f09a4SAlan D. Brunelle  *
489d5f09a4SAlan D. Brunelle  **/
49f4a6a61cSChristoph Hellwig #define blk_add_cgroup_trace_msg(q, css, fmt, ...)			\
509d5f09a4SAlan D. Brunelle 	do {								\
51c780e86dSJan Kara 		struct blk_trace *bt;					\
52c780e86dSJan Kara 									\
53c780e86dSJan Kara 		rcu_read_lock();					\
54c780e86dSJan Kara 		bt = rcu_dereference((q)->blk_trace);			\
559d5f09a4SAlan D. Brunelle 		if (unlikely(bt))					\
56f4a6a61cSChristoph Hellwig 			__blk_trace_note_message(bt, css, fmt, ##__VA_ARGS__);\
57c780e86dSJan Kara 		rcu_read_unlock();					\
589d5f09a4SAlan D. Brunelle 	} while (0)
5935fe6d76SShaohua Li #define blk_add_trace_msg(q, fmt, ...)					\
6035fe6d76SShaohua Li 	blk_add_cgroup_trace_msg(q, NULL, fmt, ##__VA_ARGS__)
6164565911SJens Axboe #define BLK_TN_MAX_MSG		128
622056a782SJens Axboe 
blk_trace_note_message_enabled(struct request_queue * q)6359fa0224SShaohua Li static inline bool blk_trace_note_message_enabled(struct request_queue *q)
6459fa0224SShaohua Li {
65c780e86dSJan Kara 	struct blk_trace *bt;
66c780e86dSJan Kara 	bool ret;
67c780e86dSJan Kara 
68c780e86dSJan Kara 	rcu_read_lock();
69c780e86dSJan Kara 	bt = rcu_dereference(q->blk_trace);
70c780e86dSJan Kara 	ret = bt && (bt->act_mask & BLK_TC_NOTIFY);
71c780e86dSJan Kara 	rcu_read_unlock();
72c780e86dSJan Kara 	return ret;
7359fa0224SShaohua Li }
7459fa0224SShaohua Li 
75a54895faSChristoph Hellwig extern void blk_add_driver_data(struct request *rq, void *data, size_t len);
767da975a2SMartin K. Petersen extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev,
77d0deef5bSShawn Du 			   struct block_device *bdev,
786da127adSChristof Schmitt 			   char __user *arg);
797da975a2SMartin K. Petersen extern int blk_trace_startstop(struct request_queue *q, int start);
807da975a2SMartin K. Petersen extern int blk_trace_remove(struct request_queue *q);
81157f9c00SArnaldo Carvalho de Melo 
822056a782SJens Axboe #else /* !CONFIG_BLK_DEV_IO_TRACE */
832056a782SJens Axboe # define blk_trace_ioctl(bdev, cmd, arg)		(-ENOTTY)
842056a782SJens Axboe # define blk_trace_shutdown(q)				do { } while (0)
85a54895faSChristoph Hellwig # define blk_add_driver_data(rq, data, len)		do {} while (0)
86d0deef5bSShawn Du # define blk_trace_setup(q, name, dev, bdev, arg)	(-ENOTTY)
876da127adSChristof Schmitt # define blk_trace_startstop(q, start)			(-ENOTTY)
889d5f09a4SAlan D. Brunelle # define blk_add_trace_msg(q, fmt, ...)			do { } while (0)
8935fe6d76SShaohua Li # define blk_add_cgroup_trace_msg(q, cg, fmt, ...)	do { } while (0)
9059fa0224SShaohua Li # define blk_trace_note_message_enabled(q)		(false)
91*cbe7cff4SYu Kuai 
blk_trace_remove(struct request_queue * q)92*cbe7cff4SYu Kuai static inline int blk_trace_remove(struct request_queue *q)
93*cbe7cff4SYu Kuai {
94*cbe7cff4SYu Kuai 	return -ENOTTY;
95*cbe7cff4SYu Kuai }
962056a782SJens Axboe #endif /* CONFIG_BLK_DEV_IO_TRACE */
97d0deef5bSShawn Du 
982669b19fSStephen Rothwell #ifdef CONFIG_COMPAT
992669b19fSStephen Rothwell 
1002669b19fSStephen Rothwell struct compat_blk_user_trace_setup {
101f8c5e944SChen Gang 	char name[BLKTRACE_BDEV_SIZE];
1022669b19fSStephen Rothwell 	u16 act_mask;
1032669b19fSStephen Rothwell 	u32 buf_size;
1042669b19fSStephen Rothwell 	u32 buf_nr;
1052669b19fSStephen Rothwell 	compat_u64 start_lba;
1062669b19fSStephen Rothwell 	compat_u64 end_lba;
1072669b19fSStephen Rothwell 	u32 pid;
1082669b19fSStephen Rothwell };
1092669b19fSStephen Rothwell #define BLKTRACESETUP32 _IOWR(0x12, 115, struct compat_blk_user_trace_setup)
1102669b19fSStephen Rothwell 
1112669b19fSStephen Rothwell #endif
1122669b19fSStephen Rothwell 
113919dbca8SBart Van Assche void blk_fill_rwbs(char *rwbs, blk_opf_t opf);
11455782138SLi Zefan 
blk_rq_trace_sector(struct request * rq)11548b77ad6SChristoph Hellwig static inline sector_t blk_rq_trace_sector(struct request *rq)
11648b77ad6SChristoph Hellwig {
1170803de78SJan Kara 	/*
1180803de78SJan Kara 	 * Tracing should ignore starting sector for passthrough requests and
1190803de78SJan Kara 	 * requests where starting sector didn't get set.
1200803de78SJan Kara 	 */
1210803de78SJan Kara 	if (blk_rq_is_passthrough(rq) || blk_rq_pos(rq) == (sector_t)-1)
1220803de78SJan Kara 		return 0;
1230803de78SJan Kara 	return blk_rq_pos(rq);
12448b77ad6SChristoph Hellwig }
12548b77ad6SChristoph Hellwig 
blk_rq_trace_nr_sectors(struct request * rq)12648b77ad6SChristoph Hellwig static inline unsigned int blk_rq_trace_nr_sectors(struct request *rq)
12748b77ad6SChristoph Hellwig {
12857292b58SChristoph Hellwig 	return blk_rq_is_passthrough(rq) ? 0 : blk_rq_sectors(rq);
12948b77ad6SChristoph Hellwig }
13055782138SLi Zefan 
1312056a782SJens Axboe #endif
132