| /* SPDX-License-Identifier: GPL-2.0 */ | |
| #undef TRACE_SYSTEM | |
| #define TRACE_SYSTEM bcache | |
| #if !defined(_TRACE_BCACHE_H) || defined(TRACE_HEADER_MULTI_READ) | |
| #define _TRACE_BCACHE_H | |
| #include <linux/tracepoint.h> | |
| DECLARE_EVENT_CLASS(bcache_request, | |
| TP_PROTO(struct bcache_device *d, struct bio *bio), | |
| TP_ARGS(d, bio), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(unsigned int, orig_major ) | |
| __field(unsigned int, orig_minor ) | |
| __field(sector_t, sector ) | |
| __field(dev_t, orig_sector ) | |
| __field(unsigned int, nr_sector ) | |
| __array(char, rwbs, 6 ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = bio_dev(bio); | |
| __entry->orig_major = d->disk->major; | |
| __entry->orig_minor = d->disk->first_minor; | |
| __entry->sector = bio->bi_iter.bi_sector; | |
| __entry->orig_sector = bio->bi_iter.bi_sector - 16; | |
| __entry->nr_sector = bio->bi_iter.bi_size >> 9; | |
| blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); | |
| ), | |
| TP_printk("%d,%d %s %llu + %u (from %d,%d @ %llu)", | |
| MAJOR(__entry->dev), MINOR(__entry->dev), | |
| __entry->rwbs, (unsigned long long)__entry->sector, | |
| __entry->nr_sector, __entry->orig_major, __entry->orig_minor, | |
| (unsigned long long)__entry->orig_sector) | |
| ); | |
| DECLARE_EVENT_CLASS(bkey, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k), | |
| TP_STRUCT__entry( | |
| __field(u32, size ) | |
| __field(u32, inode ) | |
| __field(u64, offset ) | |
| __field(bool, dirty ) | |
| ), | |
| TP_fast_assign( | |
| __entry->inode = KEY_INODE(k); | |
| __entry->offset = KEY_OFFSET(k); | |
| __entry->size = KEY_SIZE(k); | |
| __entry->dirty = KEY_DIRTY(k); | |
| ), | |
| TP_printk("%u:%llu len %u dirty %u", __entry->inode, | |
| __entry->offset, __entry->size, __entry->dirty) | |
| ); | |
| DECLARE_EVENT_CLASS(btree_node, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b), | |
| TP_STRUCT__entry( | |
| __field(size_t, bucket ) | |
| ), | |
| TP_fast_assign( | |
| __entry->bucket = PTR_BUCKET_NR(b->c, &b->key, 0); | |
| ), | |
| TP_printk("bucket %zu", __entry->bucket) | |
| ); | |
| /* request.c */ | |
| DEFINE_EVENT(bcache_request, bcache_request_start, | |
| TP_PROTO(struct bcache_device *d, struct bio *bio), | |
| TP_ARGS(d, bio) | |
| ); | |
| DEFINE_EVENT(bcache_request, bcache_request_end, | |
| TP_PROTO(struct bcache_device *d, struct bio *bio), | |
| TP_ARGS(d, bio) | |
| ); | |
| DECLARE_EVENT_CLASS(bcache_bio, | |
| TP_PROTO(struct bio *bio), | |
| TP_ARGS(bio), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(sector_t, sector ) | |
| __field(unsigned int, nr_sector ) | |
| __array(char, rwbs, 6 ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = bio_dev(bio); | |
| __entry->sector = bio->bi_iter.bi_sector; | |
| __entry->nr_sector = bio->bi_iter.bi_size >> 9; | |
| blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); | |
| ), | |
| TP_printk("%d,%d %s %llu + %u", | |
| MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, | |
| (unsigned long long)__entry->sector, __entry->nr_sector) | |
| ); | |
| DEFINE_EVENT(bcache_bio, bcache_bypass_sequential, | |
| TP_PROTO(struct bio *bio), | |
| TP_ARGS(bio) | |
| ); | |
| DEFINE_EVENT(bcache_bio, bcache_bypass_congested, | |
| TP_PROTO(struct bio *bio), | |
| TP_ARGS(bio) | |
| ); | |
| TRACE_EVENT(bcache_read, | |
| TP_PROTO(struct bio *bio, bool hit, bool bypass), | |
| TP_ARGS(bio, hit, bypass), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(sector_t, sector ) | |
| __field(unsigned int, nr_sector ) | |
| __array(char, rwbs, 6 ) | |
| __field(bool, cache_hit ) | |
| __field(bool, bypass ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = bio_dev(bio); | |
| __entry->sector = bio->bi_iter.bi_sector; | |
| __entry->nr_sector = bio->bi_iter.bi_size >> 9; | |
| blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); | |
| __entry->cache_hit = hit; | |
| __entry->bypass = bypass; | |
| ), | |
| TP_printk("%d,%d %s %llu + %u hit %u bypass %u", | |
| MAJOR(__entry->dev), MINOR(__entry->dev), | |
| __entry->rwbs, (unsigned long long)__entry->sector, | |
| __entry->nr_sector, __entry->cache_hit, __entry->bypass) | |
| ); | |
| TRACE_EVENT(bcache_write, | |
| TP_PROTO(struct cache_set *c, u64 inode, struct bio *bio, | |
| bool writeback, bool bypass), | |
| TP_ARGS(c, inode, bio, writeback, bypass), | |
| TP_STRUCT__entry( | |
| __array(char, uuid, 16 ) | |
| __field(u64, inode ) | |
| __field(sector_t, sector ) | |
| __field(unsigned int, nr_sector ) | |
| __array(char, rwbs, 6 ) | |
| __field(bool, writeback ) | |
| __field(bool, bypass ) | |
| ), | |
| TP_fast_assign( | |
| memcpy(__entry->uuid, c->sb.set_uuid, 16); | |
| __entry->inode = inode; | |
| __entry->sector = bio->bi_iter.bi_sector; | |
| __entry->nr_sector = bio->bi_iter.bi_size >> 9; | |
| blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); | |
| __entry->writeback = writeback; | |
| __entry->bypass = bypass; | |
| ), | |
| TP_printk("%pU inode %llu %s %llu + %u hit %u bypass %u", | |
| __entry->uuid, __entry->inode, | |
| __entry->rwbs, (unsigned long long)__entry->sector, | |
| __entry->nr_sector, __entry->writeback, __entry->bypass) | |
| ); | |
| DEFINE_EVENT(bcache_bio, bcache_read_retry, | |
| TP_PROTO(struct bio *bio), | |
| TP_ARGS(bio) | |
| ); | |
| DEFINE_EVENT(bkey, bcache_cache_insert, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| /* Journal */ | |
| DECLARE_EVENT_CLASS(cache_set, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c), | |
| TP_STRUCT__entry( | |
| __array(char, uuid, 16 ) | |
| ), | |
| TP_fast_assign( | |
| memcpy(__entry->uuid, c->sb.set_uuid, 16); | |
| ), | |
| TP_printk("%pU", __entry->uuid) | |
| ); | |
| DEFINE_EVENT(bkey, bcache_journal_replay_key, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| DEFINE_EVENT(cache_set, bcache_journal_full, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| DEFINE_EVENT(cache_set, bcache_journal_entry_full, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| TRACE_EVENT(bcache_journal_write, | |
| TP_PROTO(struct bio *bio, u32 keys), | |
| TP_ARGS(bio, keys), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(sector_t, sector ) | |
| __field(unsigned int, nr_sector ) | |
| __array(char, rwbs, 6 ) | |
| __field(u32, nr_keys ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = bio_dev(bio); | |
| __entry->sector = bio->bi_iter.bi_sector; | |
| __entry->nr_sector = bio->bi_iter.bi_size >> 9; | |
| __entry->nr_keys = keys; | |
| blk_fill_rwbs(__entry->rwbs, bio->bi_opf, bio->bi_iter.bi_size); | |
| ), | |
| TP_printk("%d,%d %s %llu + %u keys %u", | |
| MAJOR(__entry->dev), MINOR(__entry->dev), __entry->rwbs, | |
| (unsigned long long)__entry->sector, __entry->nr_sector, | |
| __entry->nr_keys) | |
| ); | |
| /* Btree */ | |
| DEFINE_EVENT(cache_set, bcache_btree_cache_cannibalize, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| DEFINE_EVENT(btree_node, bcache_btree_read, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b) | |
| ); | |
| TRACE_EVENT(bcache_btree_write, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b), | |
| TP_STRUCT__entry( | |
| __field(size_t, bucket ) | |
| __field(unsigned, block ) | |
| __field(unsigned, keys ) | |
| ), | |
| TP_fast_assign( | |
| __entry->bucket = PTR_BUCKET_NR(b->c, &b->key, 0); | |
| __entry->block = b->written; | |
| __entry->keys = b->keys.set[b->keys.nsets].data->keys; | |
| ), | |
| TP_printk("bucket %zu written block %u + %u", | |
| __entry->bucket, __entry->block, __entry->keys) | |
| ); | |
| DEFINE_EVENT(btree_node, bcache_btree_node_alloc, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b) | |
| ); | |
| DEFINE_EVENT(cache_set, bcache_btree_node_alloc_fail, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| DEFINE_EVENT(btree_node, bcache_btree_node_free, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b) | |
| ); | |
| TRACE_EVENT(bcache_btree_gc_coalesce, | |
| TP_PROTO(unsigned nodes), | |
| TP_ARGS(nodes), | |
| TP_STRUCT__entry( | |
| __field(unsigned, nodes ) | |
| ), | |
| TP_fast_assign( | |
| __entry->nodes = nodes; | |
| ), | |
| TP_printk("coalesced %u nodes", __entry->nodes) | |
| ); | |
| DEFINE_EVENT(cache_set, bcache_gc_start, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| DEFINE_EVENT(cache_set, bcache_gc_end, | |
| TP_PROTO(struct cache_set *c), | |
| TP_ARGS(c) | |
| ); | |
| DEFINE_EVENT(bkey, bcache_gc_copy, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| DEFINE_EVENT(bkey, bcache_gc_copy_collision, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| TRACE_EVENT(bcache_btree_insert_key, | |
| TP_PROTO(struct btree *b, struct bkey *k, unsigned op, unsigned status), | |
| TP_ARGS(b, k, op, status), | |
| TP_STRUCT__entry( | |
| __field(u64, btree_node ) | |
| __field(u32, btree_level ) | |
| __field(u32, inode ) | |
| __field(u64, offset ) | |
| __field(u32, size ) | |
| __field(u8, dirty ) | |
| __field(u8, op ) | |
| __field(u8, status ) | |
| ), | |
| TP_fast_assign( | |
| __entry->btree_node = PTR_BUCKET_NR(b->c, &b->key, 0); | |
| __entry->btree_level = b->level; | |
| __entry->inode = KEY_INODE(k); | |
| __entry->offset = KEY_OFFSET(k); | |
| __entry->size = KEY_SIZE(k); | |
| __entry->dirty = KEY_DIRTY(k); | |
| __entry->op = op; | |
| __entry->status = status; | |
| ), | |
| TP_printk("%u for %u at %llu(%u): %u:%llu len %u dirty %u", | |
| __entry->status, __entry->op, | |
| __entry->btree_node, __entry->btree_level, | |
| __entry->inode, __entry->offset, | |
| __entry->size, __entry->dirty) | |
| ); | |
| DECLARE_EVENT_CLASS(btree_split, | |
| TP_PROTO(struct btree *b, unsigned keys), | |
| TP_ARGS(b, keys), | |
| TP_STRUCT__entry( | |
| __field(size_t, bucket ) | |
| __field(unsigned, keys ) | |
| ), | |
| TP_fast_assign( | |
| __entry->bucket = PTR_BUCKET_NR(b->c, &b->key, 0); | |
| __entry->keys = keys; | |
| ), | |
| TP_printk("bucket %zu keys %u", __entry->bucket, __entry->keys) | |
| ); | |
| DEFINE_EVENT(btree_split, bcache_btree_node_split, | |
| TP_PROTO(struct btree *b, unsigned keys), | |
| TP_ARGS(b, keys) | |
| ); | |
| DEFINE_EVENT(btree_split, bcache_btree_node_compact, | |
| TP_PROTO(struct btree *b, unsigned keys), | |
| TP_ARGS(b, keys) | |
| ); | |
| DEFINE_EVENT(btree_node, bcache_btree_set_root, | |
| TP_PROTO(struct btree *b), | |
| TP_ARGS(b) | |
| ); | |
| TRACE_EVENT(bcache_keyscan, | |
| TP_PROTO(unsigned nr_found, | |
| unsigned start_inode, uint64_t start_offset, | |
| unsigned end_inode, uint64_t end_offset), | |
| TP_ARGS(nr_found, | |
| start_inode, start_offset, | |
| end_inode, end_offset), | |
| TP_STRUCT__entry( | |
| __field(__u32, nr_found ) | |
| __field(__u32, start_inode ) | |
| __field(__u64, start_offset ) | |
| __field(__u32, end_inode ) | |
| __field(__u64, end_offset ) | |
| ), | |
| TP_fast_assign( | |
| __entry->nr_found = nr_found; | |
| __entry->start_inode = start_inode; | |
| __entry->start_offset = start_offset; | |
| __entry->end_inode = end_inode; | |
| __entry->end_offset = end_offset; | |
| ), | |
| TP_printk("found %u keys from %u:%llu to %u:%llu", __entry->nr_found, | |
| __entry->start_inode, __entry->start_offset, | |
| __entry->end_inode, __entry->end_offset) | |
| ); | |
| /* Allocator */ | |
| TRACE_EVENT(bcache_invalidate, | |
| TP_PROTO(struct cache *ca, size_t bucket), | |
| TP_ARGS(ca, bucket), | |
| TP_STRUCT__entry( | |
| __field(unsigned, sectors ) | |
| __field(dev_t, dev ) | |
| __field(__u64, offset ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = ca->bdev->bd_dev; | |
| __entry->offset = bucket << ca->set->bucket_bits; | |
| __entry->sectors = GC_SECTORS_USED(&ca->buckets[bucket]); | |
| ), | |
| TP_printk("invalidated %u sectors at %d,%d sector=%llu", | |
| __entry->sectors, MAJOR(__entry->dev), | |
| MINOR(__entry->dev), __entry->offset) | |
| ); | |
| TRACE_EVENT(bcache_alloc, | |
| TP_PROTO(struct cache *ca, size_t bucket), | |
| TP_ARGS(ca, bucket), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(__u64, offset ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = ca->bdev->bd_dev; | |
| __entry->offset = bucket << ca->set->bucket_bits; | |
| ), | |
| TP_printk("allocated %d,%d sector=%llu", MAJOR(__entry->dev), | |
| MINOR(__entry->dev), __entry->offset) | |
| ); | |
| TRACE_EVENT(bcache_alloc_fail, | |
| TP_PROTO(struct cache *ca, unsigned reserve), | |
| TP_ARGS(ca, reserve), | |
| TP_STRUCT__entry( | |
| __field(dev_t, dev ) | |
| __field(unsigned, free ) | |
| __field(unsigned, free_inc ) | |
| __field(unsigned, blocked ) | |
| ), | |
| TP_fast_assign( | |
| __entry->dev = ca->bdev->bd_dev; | |
| __entry->free = fifo_used(&ca->free[reserve]); | |
| __entry->free_inc = fifo_used(&ca->free_inc); | |
| __entry->blocked = atomic_read(&ca->set->prio_blocked); | |
| ), | |
| TP_printk("alloc fail %d,%d free %u free_inc %u blocked %u", | |
| MAJOR(__entry->dev), MINOR(__entry->dev), __entry->free, | |
| __entry->free_inc, __entry->blocked) | |
| ); | |
| /* Background writeback */ | |
| DEFINE_EVENT(bkey, bcache_writeback, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| DEFINE_EVENT(bkey, bcache_writeback_collision, | |
| TP_PROTO(struct bkey *k), | |
| TP_ARGS(k) | |
| ); | |
| #endif /* _TRACE_BCACHE_H */ | |
| /* This part must be outside protection */ | |
| #include <trace/define_trace.h> |