[BACK]Return to blktrace.h CVS log [TXT][DIR] Up to [Development] / linux-2.6-xfs / include / linux

File: [Development] / linux-2.6-xfs / include / linux / Attic / blktrace.h (download)

Revision 1.2, Wed Sep 7 15:13:10 2005 UTC (12 years, 1 month ago) by nathans.longdrop.melbourne.sgi.com
Branch: MAIN
Changes since 1.1: +5 -1 lines

Merge in rev3 of blktrace patch from Jens Axboe.
Merge of 2.6.x-xfs-melb:linux:23729a by kenmcd.

#ifndef BLKTRACE_H
#define BLKTRACE_H

#include <linux/config.h>
#include <linux/blkdev.h>
#include <linux/relayfs_fs.h>

/*
 * Trace categories
 */
enum {
	BLK_TC_READ	= 1 << 0,	/* reads */
	BLK_TC_WRITE	= 1 << 1,	/* writes */
	BLK_TC_BARRIER	= 1 << 2,	/* barrier */
	BLK_TC_SYNC	= 1 << 3,	/* barrier */
	BLK_TC_QUEUE	= 1 << 4,	/* queueing/merging */
	BLK_TC_REQUEUE	= 1 << 5,	/* requeueing */
	BLK_TC_ISSUE	= 1 << 6,	/* issue */
	BLK_TC_COMPLETE	= 1 << 7,	/* completions */
	BLK_TC_FS	= 1 << 8,	/* fs requests */
	BLK_TC_PC	= 1 << 9,	/* pc requests */

	BLK_TC_END	= 1 << 15,	/* only 16-bits, reminder */
};

#define BLK_TC_SHIFT		(16)
#define BLK_TC_ACT(act)		((act) << BLK_TC_SHIFT)

/*
 * Basic trace actions
 */
enum {
	__BLK_TA_QUEUE = 1,		/* queued */
	__BLK_TA_BACKMERGE,		/* back merged to existing rq */
	__BLK_TA_FRONTMERGE,		/* front merge to existing rq */
	__BLK_TA_GETRQ,			/* allocated new request */
	__BLK_TA_SLEEPRQ,		/* sleeping on rq allocation */
	__BLK_TA_REQUEUE,		/* request requeued */
	__BLK_TA_ISSUE,			/* sent to driver */
	__BLK_TA_COMPLETE,		/* completed by driver */
};

/*
 * Trace actions in full. Additionally, read or write is masked
 */
#define BLK_TA_QUEUE		(__BLK_TA_QUEUE | BLK_TC_ACT(BLK_TC_QUEUE))
#define BLK_TA_BACKMERGE	(__BLK_TA_BACKMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
#define BLK_TA_FRONTMERGE	(__BLK_TA_FRONTMERGE | BLK_TC_ACT(BLK_TC_QUEUE))
#define	BLK_TA_GETRQ		(__BLK_TA_GETRQ | BLK_TC_ACT(BLK_TC_QUEUE))
#define	BLK_TA_SLEEPRQ		(__BLK_TA_SLEEPRQ | BLK_TC_ACT(BLK_TC_QUEUE))
#define	BLK_TA_REQUEUE		(__BLK_TA_REQUEUE | BLK_TC_ACT(BLK_TC_REQUEUE))
#define BLK_TA_ISSUE		(__BLK_TA_ISSUE | BLK_TC_ACT(BLK_TC_ISSUE))
#define BLK_TA_COMPLETE		(__BLK_TA_COMPLETE| BLK_TC_ACT(BLK_TC_COMPLETE))

#define BLK_IO_TRACE_MAGIC	0x65617400
#define BLK_IO_TRACE_VERSION	0x03

/*
 * The trace itself
 */
struct blk_io_trace {
	u32 magic;		/* MAGIC << 8 | version */
	u32 sequence;		/* event number */
	u64 time;		/* in microseconds */
	u64 sector;		/* disk offset */
	u32 bytes;		/* transfer length */
	u32 action;		/* what happened */
	u32 pid;		/* who did it */
	u16 cpu;		/* on what cpu did it happen */
	u16 error;		/* completion error */
	u16 pdu_len;		/* length of data after this trace */
};

struct blk_trace {
	struct dentry *dir;
	struct rchan *rchan;
	atomic_t sequence;
	u16 act_mask;
};

/*
 * User setup structure passed with BLKSTARTTRACE
 */
struct blk_user_trace_setup {
	char name[BDEVNAME_SIZE];	/* output */
	u16 act_mask;			/* input */
	u32 buf_size;			/* input */
	u32 buf_nr;			/* input */
};

#if defined(CONFIG_BLK_DEV_IO_TRACE)
extern int blk_start_trace(struct block_device *, char __user *);
extern int blk_stop_trace(struct block_device *);
extern void blk_cleanup_trace(struct blk_trace *);
extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, char *);

static inline void blk_add_trace_rq(struct request_queue *q, struct request *rq,
				    u32 what)
{
	struct blk_trace *bt = q->blk_trace;
	int rw = rq->flags & 0x07;

	if (likely(!bt))
		return;

	if (blk_pc_request(rq)) {
		what |= BLK_TC_ACT(BLK_TC_PC);
		__blk_add_trace(bt, 0, rq->data_len, rw, what, rq->errors, sizeof(rq->cmd), rq->cmd);
	} else  {
		what |= BLK_TC_ACT(BLK_TC_FS);
		__blk_add_trace(bt, rq->hard_sector, rq->hard_nr_sectors << 9, rw, what, rq->errors, 0, NULL);
	}
}

static inline void blk_add_trace_bio(struct request_queue *q, struct bio *bio,
				     u32 what)
{
	struct blk_trace *bt = q->blk_trace;

	if (likely(!bt))
		return;

	__blk_add_trace(bt, bio->bi_sector, bio->bi_size, bio->bi_rw, what, !bio_flagged(bio, BIO_UPTODATE), 0, NULL);
}

static inline void blk_add_trace_generic(struct request_queue *q,
					 struct bio *bio, int rw, u32 what)
{
	struct blk_trace *bt = q->blk_trace;

	if (likely(!bt))
		return;

	if (bio)
		blk_add_trace_bio(q, bio, what);
	else
		__blk_add_trace(bt, 0, 0, rw, what, 0, 0, NULL);
}

#else /* !CONFIG_BLK_DEV_IO_TRACE */
#define blk_start_trace(bdev, arg)		(-EINVAL)
#define blk_stop_trace(bdev)			(-EINVAL)
#define blk_cleanup_trace(bt)			do { } while (0)
#define blk_add_trace_rq(q, rq, what)		do { } while (0)
#define blk_add_trace_bio(q, rq, what)		do { } while (0)
#define blk_add_trace_generic(q, rq, rw, what)	do { } while (0)
#endif /* CONFIG_BLK_DEV_IO_TRACE */

#endif