diff options
Diffstat (limited to 'include/trace')
27 files changed, 1580 insertions, 325 deletions
diff --git a/include/trace/define_remote_events.h b/include/trace/define_remote_events.h index 676e803dc144..78346ac77585 100644 --- a/include/trace/define_remote_events.h +++ b/include/trace/define_remote_events.h @@ -35,17 +35,26 @@ do { \ #define RE_PRINTK(__args...) __args -#define REMOTE_EVENT(__name, __id, __struct, __printk) \ - REMOTE_EVENT_FORMAT(__name, __struct); \ +#define REMOTE_EVENT_PRINT_FUNC(__name, __printk) \ static void remote_event_print_##__name(void *evt, struct trace_seq *seq) \ { \ struct remote_event_format_##__name __maybe_unused *__entry = evt; \ trace_seq_puts(seq, #__name); \ - remote_printk(__printk); \ + __printk; \ } + +#define REMOTE_EVENT(__name, __id, __struct, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + REMOTE_EVENT_PRINT_FUNC(__name, remote_printk(__printk)) + +#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \ + REMOTE_EVENT_FORMAT(__name, __struct); \ + REMOTE_EVENT_PRINT_FUNC(__name, __printk) + #include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) #undef REMOTE_EVENT +#undef REMOTE_EVENT_CUSTOM_PRINTK #undef RE_PRINTK #undef re_field #define re_field(__type, __field) \ @@ -70,4 +79,8 @@ do { \ .print_fmt = remote_event_print_fmt_##__name, \ .print = remote_event_print_##__name, \ } + +#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk) \ + REMOTE_EVENT(__name, __id, RE_STRUCT(__struct), "\"Unknown\"") + #include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE) diff --git a/include/trace/events/bridge.h b/include/trace/events/bridge.h index 3fe4725c83ff..f676516b33fa 100644 --- a/include/trace/events/bridge.h +++ b/include/trace/events/bridge.h @@ -68,13 +68,14 @@ TRACE_EVENT(br_fdb_external_learn_add, TRACE_EVENT(fdb_delete, - TP_PROTO(struct net_bridge *br, struct net_bridge_fdb_entry *f), + TP_PROTO(struct net_bridge *br, struct net_bridge_fdb_entry *f, + const struct net_bridge_port *dst), - TP_ARGS(br, f), + TP_ARGS(br, f, dst), TP_STRUCT__entry( __string(br_dev, br->dev->name) - __string(dev, f->dst ? f->dst->dev->name : "null") + __string(dev, dst ? dst->dev->name : "null") __array(unsigned char, addr, ETH_ALEN) __field(u16, vid) ), diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h index 9259bc71049e..a19233e8ae78 100644 --- a/include/trace/events/cachefiles.h +++ b/include/trace/events/cachefiles.h @@ -52,6 +52,8 @@ enum cachefiles_coherency_trace { cachefiles_coherency_check_ok, cachefiles_coherency_check_type, cachefiles_coherency_check_xattr, + cachefiles_coherency_discontiguous, + cachefiles_coherency_remove, cachefiles_coherency_set_fail, cachefiles_coherency_set_ok, cachefiles_coherency_vol_check_cmp, @@ -63,9 +65,11 @@ enum cachefiles_coherency_trace { }; enum cachefiles_trunc_trace { + cachefiles_trunc_clear_padding, cachefiles_trunc_dio_adjust, cachefiles_trunc_expand_tmpfile, cachefiles_trunc_shrink, + cachefiles_trunc_zap, }; enum cachefiles_prepare_read_trace { @@ -80,11 +84,14 @@ enum cachefiles_prepare_read_trace { }; enum cachefiles_error_trace { + cachefiles_trace_alignment_error, + cachefiles_trace_create_nospace, cachefiles_trace_fallocate_error, cachefiles_trace_getxattr_error, cachefiles_trace_link_error, cachefiles_trace_lookup_error, cachefiles_trace_mkdir_error, + cachefiles_trace_mkdir_nospace, cachefiles_trace_notify_change_error, cachefiles_trace_open_error, cachefiles_trace_read_error, @@ -97,6 +104,8 @@ enum cachefiles_error_trace { cachefiles_trace_trunc_error, cachefiles_trace_unlink_error, cachefiles_trace_write_error, + cachefiles_trace_write_nospace, + cachefiles_trace_write_nospace_2, }; #endif @@ -136,6 +145,8 @@ enum cachefiles_error_trace { EM(cachefiles_coherency_check_ok, "OK ") \ EM(cachefiles_coherency_check_type, "BAD type") \ EM(cachefiles_coherency_check_xattr, "BAD xatt") \ + EM(cachefiles_coherency_discontiguous, "--- gap ") \ + EM(cachefiles_coherency_remove, "REMOVE ") \ EM(cachefiles_coherency_set_fail, "SET fail") \ EM(cachefiles_coherency_set_ok, "SET ok ") \ EM(cachefiles_coherency_vol_check_cmp, "VOL BAD cmp ") \ @@ -146,9 +157,11 @@ enum cachefiles_error_trace { E_(cachefiles_coherency_vol_set_ok, "VOL SET ok ") #define cachefiles_trunc_traces \ + EM(cachefiles_trunc_clear_padding, "CLRPAD") \ EM(cachefiles_trunc_dio_adjust, "DIOADJ") \ EM(cachefiles_trunc_expand_tmpfile, "EXPTMP") \ - E_(cachefiles_trunc_shrink, "SHRINK") + EM(cachefiles_trunc_shrink, "SHRINK") \ + E_(cachefiles_trunc_zap, "ZAP ") #define cachefiles_prepare_read_traces \ EM(cachefiles_trace_read_after_eof, "after-eof ") \ @@ -161,11 +174,14 @@ enum cachefiles_error_trace { E_(cachefiles_trace_read_seek_nxio, "seek-enxio") #define cachefiles_error_traces \ + EM(cachefiles_trace_alignment_error, "align") \ + EM(cachefiles_trace_create_nospace, "create-nospace") \ EM(cachefiles_trace_fallocate_error, "fallocate") \ EM(cachefiles_trace_getxattr_error, "getxattr") \ EM(cachefiles_trace_link_error, "link") \ EM(cachefiles_trace_lookup_error, "lookup") \ EM(cachefiles_trace_mkdir_error, "mkdir") \ + EM(cachefiles_trace_mkdir_nospace, "mkdir-nospace") \ EM(cachefiles_trace_notify_change_error, "notify_change") \ EM(cachefiles_trace_open_error, "open") \ EM(cachefiles_trace_read_error, "read") \ @@ -177,7 +193,9 @@ enum cachefiles_error_trace { EM(cachefiles_trace_tmpfile_error, "tmpfile") \ EM(cachefiles_trace_trunc_error, "trunc") \ EM(cachefiles_trace_unlink_error, "unlink") \ - E_(cachefiles_trace_write_error, "write") + EM(cachefiles_trace_write_error, "write") \ + EM(cachefiles_trace_write_nospace, "write-nospace") \ + E_(cachefiles_trace_write_nospace_2, "write-nospace-2") /* @@ -371,12 +389,12 @@ TRACE_EVENT(cachefiles_rename, TRACE_EVENT(cachefiles_coherency, TP_PROTO(struct cachefiles_object *obj, - ino_t ino, - u64 disk_aux, + ino_t ino, uoff_t obj_size, + const void *disk_aux, enum cachefiles_content content, enum cachefiles_coherency_trace why), - TP_ARGS(obj, ino, disk_aux, content, why), + TP_ARGS(obj, ino, obj_size, disk_aux, content, why), /* Note that obj may be NULL */ TP_STRUCT__entry( @@ -384,23 +402,41 @@ TRACE_EVENT(cachefiles_coherency, __field(enum cachefiles_coherency_trace, why) __field(enum cachefiles_content, content) __field(u64, ino) + __field(u64, obj_size) __field(u64, aux) __field(u64, disk_aux) ), TP_fast_assign( + union { + __be16 s[4]; + __be64 ll; + } x; + __entry->obj = obj->debug_id; __entry->why = why; __entry->content = content; __entry->ino = ino; + __entry->obj_size = obj_size; __entry->aux = be64_to_cpup((__be64 *)obj->cookie->inline_aux); - __entry->disk_aux = disk_aux; + + /* cachefiles_xattr::data is 2-byte aligned but not 8-byte aligned. */ + if (disk_aux) { + x.s[0] = ((__be16 *)disk_aux)[0]; + x.s[1] = ((__be16 *)disk_aux)[1]; + x.s[2] = ((__be16 *)disk_aux)[2]; + x.s[3] = ((__be16 *)disk_aux)[3]; + __entry->disk_aux = be64_to_cpu(x.ll); + } else { + __entry->disk_aux = 0; + } ), - TP_printk("o=%08x %s B=%llx c=%u aux=%llx dsk=%llx", + TP_printk("o=%08x %s B=%llx oz=%llx c=%u aux=%llx dsk=%llx", __entry->obj, __print_symbolic(__entry->why, cachefiles_coherency_traces), __entry->ino, + __entry->obj_size, __entry->content, __entry->aux, __entry->disk_aux) @@ -434,7 +470,7 @@ TRACE_EVENT(cachefiles_vol_coherency, TRACE_EVENT(cachefiles_prep_read, TP_PROTO(struct cachefiles_object *obj, - loff_t start, + uoff_t start, size_t len, unsigned short flags, enum netfs_io_source source, @@ -449,7 +485,7 @@ TRACE_EVENT(cachefiles_prep_read, __field(enum netfs_io_source, source) __field(enum cachefiles_prepare_read_trace, why) __field(size_t, len) - __field(loff_t, start) + __field(uoff_t, start) __field(unsigned int, netfs_inode) __field(unsigned int, cache_inode) ), @@ -477,16 +513,16 @@ TRACE_EVENT(cachefiles_prep_read, TRACE_EVENT(cachefiles_read, TP_PROTO(struct cachefiles_object *obj, struct inode *backer, - loff_t start, + uoff_t start, size_t len), TP_ARGS(obj, backer, start, len), TP_STRUCT__entry( - __field(unsigned int, obj) - __field(unsigned int, backer) - __field(size_t, len) - __field(loff_t, start) + __field(unsigned int, obj) + __field(unsigned int, backer) + __field(size_t, len) + __field(uoff_t, start) ), TP_fast_assign( @@ -506,16 +542,16 @@ TRACE_EVENT(cachefiles_read, TRACE_EVENT(cachefiles_write, TP_PROTO(struct cachefiles_object *obj, struct inode *backer, - loff_t start, + uoff_t start, size_t len), TP_ARGS(obj, backer, start, len), TP_STRUCT__entry( - __field(unsigned int, obj) - __field(unsigned int, backer) - __field(size_t, len) - __field(loff_t, start) + __field(unsigned int, obj) + __field(unsigned int, backer) + __field(size_t, len) + __field(uoff_t, start) ), TP_fast_assign( @@ -534,7 +570,7 @@ TRACE_EVENT(cachefiles_write, TRACE_EVENT(cachefiles_trunc, TP_PROTO(struct cachefiles_object *obj, struct inode *backer, - loff_t from, loff_t to, enum cachefiles_trunc_trace why), + uoff_t from, uoff_t to, enum cachefiles_trunc_trace why), TP_ARGS(obj, backer, from, to, why), @@ -542,8 +578,8 @@ TRACE_EVENT(cachefiles_trunc, __field(unsigned int, obj) __field(unsigned int, backer) __field(enum cachefiles_trunc_trace, why) - __field(loff_t, from) - __field(loff_t, to) + __field(uoff_t, from) + __field(uoff_t, to) ), TP_fast_assign( @@ -679,6 +715,26 @@ TRACE_EVENT(cachefiles_io_error, __entry->error) ); +TRACE_EVENT(cachefiles_no_space, + TP_PROTO(struct cachefiles_object *obj, enum cachefiles_error_trace trace), + + TP_ARGS(obj, trace), + + TP_STRUCT__entry( + __field(unsigned int, obj) + __field(enum cachefiles_error_trace, trace) + ), + + TP_fast_assign( + __entry->obj = obj ? obj->debug_id : 0; + __entry->trace = trace; + ), + + TP_printk("o=%08x %s", + __entry->obj, + __print_symbolic(__entry->trace, cachefiles_error_traces)) + ); + #endif /* _TRACE_CACHEFILES_H */ /* This part must be outside protection */ diff --git a/include/trace/events/dma.h b/include/trace/events/dma.h index 9df02c1511de..b06d8f99922d 100644 --- a/include/trace/events/dma.h +++ b/include/trace/events/dma.h @@ -134,7 +134,7 @@ DECLARE_EVENT_CLASS(dma_alloc_class, TP_fast_assign( __assign_str(device); __entry->virt_addr = virt_addr; - __entry->dma_addr = dma_addr; + __entry->dma_addr = virt_addr ? dma_addr : 0; __entry->size = size; __entry->flags = flags; __entry->dir = dir; diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h index 7028a28316fa..92048da9dae4 100644 --- a/include/trace/events/ext4.h +++ b/include/trace/events/ext4.h @@ -3157,6 +3157,215 @@ TRACE_EVENT(ext4_move_extent_exit, __entry->ret) ); +DECLARE_EVENT_CLASS(ext4_set_iomap_class, + TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, + loff_t offset, loff_t length, unsigned int flags), + TP_ARGS(inode, map, offset, length, flags), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(ext4_lblk_t, m_lblk) + __field(ext4_fsblk_t, pblk) + __field(unsigned int, m_len) + __field(unsigned int, m_flags) + __field(u64, m_seq) + __field(loff_t, offset) + __field(loff_t, length) + __field(unsigned int, iomap_flags) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->m_lblk = map->m_lblk; + __entry->pblk = map->m_pblk; + __entry->m_len = map->m_len; + __entry->m_flags = map->m_flags; + __entry->m_seq = map->m_seq; + __entry->offset = offset; + __entry->length = length; + __entry->iomap_flags = flags; + + ), + TP_printk("dev %d:%d ino %llu m_lblk %u pblk %llu m_len %u m_flags %s m_seq %llu orig_off 0x%llx orig_len 0x%llx iomap_flags 0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->m_lblk, __entry->pblk, __entry->m_len, + show_mflags(__entry->m_flags), __entry->m_seq, + __entry->offset, __entry->length, __entry->iomap_flags) +) + +#define DEFINE_SET_IOMAP_EVENT(name) \ +DEFINE_EVENT(ext4_set_iomap_class, name, \ + TP_PROTO(struct inode *inode, struct ext4_map_blocks *map, \ + loff_t offset, loff_t length, unsigned int flags), \ + TP_ARGS(inode, map, offset, length, flags)) + +DEFINE_SET_IOMAP_EVENT(ext4_iomap_buffered_read_begin); +DEFINE_SET_IOMAP_EVENT(ext4_iomap_buffered_write_begin); +DEFINE_SET_IOMAP_EVENT(ext4_iomap_map_writeback_range); +DEFINE_SET_IOMAP_EVENT(ext4_iomap_zero_begin); + +DECLARE_EVENT_CLASS(ext4_iomap_disksize_pending, + TP_PROTO(struct inode *inode), + TP_ARGS(inode), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, i_disksize) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->i_disksize = READ_ONCE(EXT4_I(inode)->i_disksize); + ), + TP_printk("dev %d:%d ino %llu i_disksize %lld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->i_disksize) +); + +DEFINE_EVENT(ext4_iomap_disksize_pending, ext4_iomap_mark_disksize_pending, + TP_PROTO(struct inode *inode), + TP_ARGS(inode) +); + +DEFINE_EVENT(ext4_iomap_disksize_pending, ext4_iomap_clear_disksize_pending, + TP_PROTO(struct inode *inode), + TP_ARGS(inode) +); + +DEFINE_EVENT(ext4_iomap_disksize_pending, ext4_iomap_wait_disksize_pending, + TP_PROTO(struct inode *inode), + TP_ARGS(inode) +); + +/* disksize pending I/O tracepoints for iomap Buffered I/O path */ +DECLARE_EVENT_CLASS(ext4_iomap_wb_disksize_pending, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size), + TP_ARGS(inode, io_offset, io_size), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, io_offset) + __field(size_t, io_size) + __field(loff_t, i_size) + __field(loff_t, i_disksize) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->io_offset = io_offset; + __entry->io_size = io_size; + __entry->i_size = i_size_read(inode); + __entry->i_disksize = READ_ONCE(EXT4_I(inode)->i_disksize); + ), + TP_printk("dev %d:%d ino %llu io_offset %lld io_size %zu i_size %lld i_disksize %lld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->io_offset, __entry->io_size, + __entry->i_size, __entry->i_disksize) +); + +DEFINE_EVENT(ext4_iomap_wb_disksize_pending, + ext4_iomap_wb_disksize_pending_submit, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size), + TP_ARGS(inode, io_offset, io_size) +); + +DEFINE_EVENT(ext4_iomap_wb_disksize_pending, + ext4_iomap_wb_disksize_pending_wait, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size), + TP_ARGS(inode, io_offset, io_size) +); + +TRACE_EVENT(ext4_iomap_wb_disksize_pending_complete, + TP_PROTO(struct inode *inode, loff_t io_offset, size_t io_size, + int ret), + TP_ARGS(inode, io_offset, io_size, ret), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, io_offset) + __field(size_t, io_size) + __field(loff_t, i_size) + __field(loff_t, i_disksize) + __field(int, ret) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->io_offset = io_offset; + __entry->io_size = io_size; + __entry->i_size = i_size_read(inode); + __entry->i_disksize = READ_ONCE(EXT4_I(inode)->i_disksize); + __entry->ret = ret; + ), + TP_printk("dev %d:%d ino %llu io_offset %lld io_size %zu ret %d i_size %lld i_disksize %lld", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->io_offset, __entry->io_size, + __entry->ret, __entry->i_size, __entry->i_disksize) +); + +/* i_disksize update tracepoint */ +TRACE_EVENT(ext4_iomap_wb_update_disksize, + TP_PROTO(struct inode *inode, loff_t end, loff_t i_size, + loff_t i_disksize, loff_t new_disksize, + bool is_disksize_grow), + TP_ARGS(inode, end, i_size, i_disksize, new_disksize, + is_disksize_grow), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, end) + __field(loff_t, i_size) + __field(loff_t, i_disksize) + __field(loff_t, new_disksize) + __field(bool, is_disksize_grow) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->end = end; + __entry->i_size = i_size; + __entry->i_disksize = i_disksize; + __entry->new_disksize = new_disksize; + __entry->is_disksize_grow = is_disksize_grow; + ), + TP_printk("dev %d:%d ino %llu end %lld i_size %lld i_disksize %lld new_disksize %lld is_disksize_grow %d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->end, __entry->i_size, + __entry->i_disksize, __entry->new_disksize, + __entry->is_disksize_grow) +); + +/* Block zero EOF tracepoint */ +TRACE_EVENT(ext4_block_zero_eof, + TP_PROTO(struct inode *inode, loff_t from, loff_t length, + bool did_zero, bool zero_written), + TP_ARGS(inode, from, length, did_zero, zero_written), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u64, ino) + __field(loff_t, from) + __field(loff_t, length) + __field(loff_t, i_size) + __field(loff_t, i_disksize) + __field(bool, did_zero) + __field(bool, zero_written) + ), + TP_fast_assign( + __entry->dev = inode->i_sb->s_dev; + __entry->ino = inode->i_ino; + __entry->from = from; + __entry->length = length; + __entry->i_size = inode->i_size; + __entry->i_disksize = READ_ONCE(EXT4_I(inode)->i_disksize); + __entry->did_zero = did_zero; + __entry->zero_written = zero_written; + ), + TP_printk("dev %d:%d ino %llu zero EOF from %lld length %lld i_size %lld i_disksize %lld did_zero %d zero_written %d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, + __entry->from, __entry->length, __entry->i_size, + __entry->i_disksize, __entry->did_zero, __entry->zero_written) +); + #endif /* _TRACE_EXT4_H */ /* This part must be outside protection */ diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index d53be932df01..df4cd346ae72 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1430,6 +1430,50 @@ DEFINE_EVENT(f2fs__folio, f2fs_set_page_dirty, TP_ARGS(folio, type) ); +DECLARE_EVENT_CLASS(f2fs__cached_block, + + TP_PROTO(struct f2fs_cached_block *block, int type), + + TP_ARGS(block, type), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(pgoff_t, index) + __field(int, type) + __field(int, dirty) + __field(int, uptodate) + ), + + TP_fast_assign( + __entry->dev = block->cache->sbi->sb->s_dev; + __entry->index = block->index; + __entry->type = type; + __entry->dirty = f2fs_cache_test_dirty(block); + __entry->uptodate = f2fs_cache_test_uptodate(block); + ), + + TP_printk("dev = (%d,%d), %s, index = %lu, dirty = %d, uptodate = %d", + show_dev(__entry->dev), + show_block_type(__entry->type), + (unsigned long)__entry->index, + __entry->dirty, + __entry->uptodate) +); + +DEFINE_EVENT(f2fs__cached_block, f2fs_write_cache, + + TP_PROTO(struct f2fs_cached_block *block, int type), + + TP_ARGS(block, type) +); + +DEFINE_EVENT(f2fs__cached_block, f2fs_cache_set_dirty, + + TP_PROTO(struct f2fs_cached_block *block, int type), + + TP_ARGS(block, type) +); + TRACE_EVENT(f2fs_replace_atomic_write_block, TP_PROTO(struct inode *inode, struct inode *cow_inode, pgoff_t index, @@ -1574,6 +1618,33 @@ TRACE_EVENT(f2fs_writepages, __entry->for_sync) ); +TRACE_EVENT(f2fs_write_caches, + + TP_PROTO(struct f2fs_sb_info *sbi, long nr_to_write, long nwritten, int type), + + TP_ARGS(sbi, nr_to_write, nwritten, type), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(long, nr_to_write) + __field(long, nwritten) + __field(int, type) + ), + + TP_fast_assign( + __entry->dev = sbi->sb->s_dev; + __entry->nr_to_write = nr_to_write; + __entry->nwritten = nwritten; + __entry->type = type; + ), + + TP_printk("dev = (%d,%d), %s, nr_to_write = %ld, nwritten = %ld", + show_dev(__entry->dev), + show_block_type(__entry->type), + __entry->nr_to_write, + __entry->nwritten) +); + TRACE_EVENT(f2fs_readpages, TP_PROTO(struct inode *inode, pgoff_t start, unsigned int nrpage), diff --git a/include/trace/events/fib.h b/include/trace/events/fib.h index feb28b359eff..e0ee14d6ca45 100644 --- a/include/trace/events/fib.h +++ b/include/trace/events/fib.h @@ -15,9 +15,10 @@ TRACE_EVENT(fib_table_lookup, TP_PROTO(u32 tb_id, const struct flowi4 *flp, - const struct fib_nh_common *nhc, int err), + const struct fib_nh_common *nhc, int err, + const struct net *net), - TP_ARGS(tb_id, flp, nhc, err), + TP_ARGS(tb_id, flp, nhc, err, net), TP_STRUCT__entry( __field( u32, tb_id ) @@ -35,6 +36,7 @@ TRACE_EVENT(fib_table_lookup, __field( u16, sport ) __field( u16, dport ) __array(char, name, IFNAMSIZ ) + __field( u64, net_cookie ) ), TP_fast_assign( @@ -90,13 +92,16 @@ TRACE_EVENT(fib_table_lookup, in6 = (struct in6_addr *)__entry->gw6; *in6 = in6addr_any; } + + __entry->net_cookie = net->net_cookie; ), - TP_printk("table %u oif %d iif %d proto %u %pI4/%u -> %pI4/%u tos %d scope %d flags %x ==> dev %s gw %pI4/%pI6c err %d", + TP_printk("table %u oif %d iif %d proto %u %pI4/%u -> %pI4/%u tos %d scope %d flags %x ==> dev %s gw %pI4/%pI6c err %d net_cookie %llu", __entry->tb_id, __entry->oif, __entry->iif, __entry->proto, __entry->src, __entry->sport, __entry->dst, __entry->dport, __entry->tos, __entry->scope, __entry->flags, - __entry->name, __entry->gw4, __entry->gw6, __entry->err) + __entry->name, __entry->gw4, __entry->gw6, __entry->err, + __entry->net_cookie) ); #endif /* _TRACE_FIB_H */ diff --git a/include/trace/events/fib6.h b/include/trace/events/fib6.h index 8d22b2e98d48..e58facd2d7d4 100644 --- a/include/trace/events/fib6.h +++ b/include/trace/events/fib6.h @@ -34,6 +34,7 @@ TRACE_EVENT(fib6_table_lookup, __field( u8, rt_type ) __array( char, name, IFNAMSIZ ) __array( __u8, gw, 16 ) + __field( u64, net_cookie ) ), TP_fast_assign( @@ -76,13 +77,16 @@ TRACE_EVENT(fib6_table_lookup, in6 = (struct in6_addr *)__entry->gw; *in6 = res->nh->fib_nh_gw6; } + + __entry->net_cookie = net->net_cookie; ), - TP_printk("table %3u oif %d iif %d proto %u %pI6c/%u -> %pI6c/%u flowlabel %#x tos %d scope %d flags %x ==> dev %s gw %pI6c err %d", + TP_printk("table %3u oif %d iif %d proto %u %pI6c/%u -> %pI6c/%u flowlabel %#x tos %d scope %d flags %x ==> dev %s gw %pI6c err %d net_cookie %llu", __entry->tb_id, __entry->oif, __entry->iif, __entry->proto, __entry->src, __entry->sport, __entry->dst, __entry->dport, __entry->flowlabel, __entry->tos, __entry->scope, - __entry->flags, __entry->name, __entry->gw, __entry->err) + __entry->flags, __entry->name, __entry->gw, __entry->err, + __entry->net_cookie) ); #endif /* _TRACE_FIB6_H */ diff --git a/include/trace/events/fscache.h b/include/trace/events/fscache.h index f1a73aa83fbb..8735d428ebd9 100644 --- a/include/trace/events/fscache.h +++ b/include/trace/events/fscache.h @@ -460,13 +460,13 @@ TRACE_EVENT(fscache_relinquish, ); TRACE_EVENT(fscache_invalidate, - TP_PROTO(struct fscache_cookie *cookie, loff_t new_size), + TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size), TP_ARGS(cookie, new_size), TP_STRUCT__entry( __field(unsigned int, cookie ) - __field(loff_t, new_size ) + __field(uoff_t, new_size ) ), TP_fast_assign( @@ -479,14 +479,14 @@ TRACE_EVENT(fscache_invalidate, ); TRACE_EVENT(fscache_resize, - TP_PROTO(struct fscache_cookie *cookie, loff_t new_size), + TP_PROTO(struct fscache_cookie *cookie, uoff_t new_size), TP_ARGS(cookie, new_size), TP_STRUCT__entry( __field(unsigned int, cookie ) - __field(loff_t, old_size ) - __field(loff_t, new_size ) + __field(uoff_t, old_size ) + __field(uoff_t, new_size ) ), TP_fast_assign( diff --git a/include/trace/events/huge_memory.h b/include/trace/events/huge_memory.h index 5a48c5406cce..5fb4d92cfd84 100644 --- a/include/trace/events/huge_memory.h +++ b/include/trace/events/huge_memory.h @@ -55,10 +55,10 @@ SCAN_STATUS TRACE_EVENT(mm_khugepaged_scan_pmd, - TP_PROTO(struct mm_struct *mm, struct folio *folio, + TP_PROTO(struct mm_struct *mm, unsigned long pfn, int referenced, int none_or_zero, int status, int unmapped), - TP_ARGS(mm, folio, referenced, none_or_zero, status, unmapped), + TP_ARGS(mm, pfn, referenced, none_or_zero, status, unmapped), TP_STRUCT__entry( __field(struct mm_struct *, mm) @@ -71,7 +71,7 @@ TRACE_EVENT(mm_khugepaged_scan_pmd, TP_fast_assign( __entry->mm = mm; - __entry->pfn = folio ? folio_pfn(folio) : -1; + __entry->pfn = pfn; __entry->referenced = referenced; __entry->none_or_zero = none_or_zero; __entry->status = status; @@ -178,10 +178,10 @@ TRACE_EVENT(mm_collapse_huge_page_swapin, TRACE_EVENT(mm_khugepaged_scan_file, - TP_PROTO(struct mm_struct *mm, struct folio *folio, struct file *file, + TP_PROTO(struct mm_struct *mm, unsigned long pfn, struct file *file, int present, int swap, int result), - TP_ARGS(mm, folio, file, present, swap, result), + TP_ARGS(mm, pfn, file, present, swap, result), TP_STRUCT__entry( __field(struct mm_struct *, mm) @@ -194,7 +194,7 @@ TRACE_EVENT(mm_khugepaged_scan_file, TP_fast_assign( __entry->mm = mm; - __entry->pfn = folio ? folio_pfn(folio) : -1; + __entry->pfn = pfn; __assign_str(filename); __entry->present = present; __entry->swap = swap; @@ -211,10 +211,10 @@ TRACE_EVENT(mm_khugepaged_scan_file, ); TRACE_EVENT(mm_khugepaged_collapse_file, - TP_PROTO(struct mm_struct *mm, struct folio *new_folio, pgoff_t index, + TP_PROTO(struct mm_struct *mm, unsigned long new_pfn, pgoff_t index, unsigned long addr, bool is_shmem, struct file *file, int nr, int result), - TP_ARGS(mm, new_folio, index, addr, is_shmem, file, nr, result), + TP_ARGS(mm, new_pfn, index, addr, is_shmem, file, nr, result), TP_STRUCT__entry( __field(struct mm_struct *, mm) __field(unsigned long, hpfn) @@ -228,7 +228,7 @@ TRACE_EVENT(mm_khugepaged_collapse_file, TP_fast_assign( __entry->mm = mm; - __entry->hpfn = new_folio ? folio_pfn(new_folio) : -1; + __entry->hpfn = new_pfn; __entry->index = index; __entry->addr = addr; __entry->is_shmem = is_shmem; diff --git a/include/trace/events/icmp.h b/include/trace/events/icmp.h index 09ae115099df..6937b778ae54 100644 --- a/include/trace/events/icmp.h +++ b/include/trace/events/icmp.h @@ -27,17 +27,20 @@ TRACE_EVENT(icmp_send, TP_fast_assign( struct iphdr *iph = ip_hdr(skb); - struct udphdr *uh = udp_hdr(skb); - int proto_4 = iph->protocol; + struct udphdr _uh, *uh = NULL; __be32 *p32; __entry->skbaddr = skb; __entry->type = type; __entry->code = code; - if (proto_4 != IPPROTO_UDP || (u8 *)uh < skb->head || - (u8 *)uh + sizeof(struct udphdr) - > skb_tail_pointer(skb)) { + if (iph->protocol == IPPROTO_UDP) + uh = skb_header_pointer(skb, + skb_network_offset(skb) + + (iph->ihl << 2), + sizeof(_uh), &_uh); + + if (!uh) { __entry->sport = 0; __entry->dport = 0; __entry->ulen = 0; diff --git a/include/trace/events/iocost.h b/include/trace/events/iocost.h index e772b1bc60d6..eb711343ce4f 100644 --- a/include/trace/events/iocost.h +++ b/include/trace/events/iocost.h @@ -34,6 +34,9 @@ DECLARE_EVENT_CLASS(iocost_iocg_state, ), TP_fast_assign( + u32 hwa, hwi; + + iocg_hweight_cache(iocg, &hwa, &hwi); __assign_str(devname); __assign_str(cgroup); __entry->now = now->now; @@ -44,8 +47,8 @@ DECLARE_EVENT_CLASS(iocost_iocg_state, __entry->vtime = vtime; __entry->weight = iocg->weight; __entry->inuse = iocg->inuse; - __entry->hweight_active = iocg->hweight_active; - __entry->hweight_inuse = iocg->hweight_inuse; + __entry->hweight_active = hwa; + __entry->hweight_inuse = hwi; ), TP_printk("[%s:%s] now=%llu:%llu vrate=%llu " diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h index b282e3a86769..07013f88e655 100644 --- a/include/trace/events/kvm.h +++ b/include/trace/events/kvm.h @@ -4,8 +4,14 @@ #include <linux/tracepoint.h> +#undef UNPACK_KVM +#define UNPACK_KVM(name) name #undef TRACE_SYSTEM -#define TRACE_SYSTEM kvm +#define TRACE_SYSTEM UNPACK_KVM(KVM_DEV_NAME) +#undef TRACE_SYSTEM_VAR +#define TRACE_SYSTEM_VAR kvm +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE kvm #define ERSN(x) { KVM_EXIT_##x, "KVM_EXIT_" #x } @@ -358,13 +364,13 @@ TRACE_EVENT(kvm_dirty_ring_exit, TP_printk("vcpu %d", __entry->vcpu_id) ); -#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES +#ifdef CONFIG_KVM_VM_MEMORY_ATTRIBUTES /* * @start: Starting address of guest memory range * @end: End address of guest memory range * @attr: The value of the attribute being set. */ -TRACE_EVENT(kvm_vm_set_mem_attributes, +TRACE_EVENT(kvm_set_vm_mem_attributes, TP_PROTO(gfn_t start, gfn_t end, unsigned long attr), TP_ARGS(start, end, attr), @@ -383,7 +389,7 @@ TRACE_EVENT(kvm_vm_set_mem_attributes, TP_printk("%#016llx -- %#016llx [0x%lx]", __entry->start, __entry->end, __entry->attr) ); -#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */ +#endif /* CONFIG_KVM_VM_MEMORY_ATTRIBUTES */ TRACE_EVENT(kvm_unmap_hva_range, TP_PROTO(unsigned long start, unsigned long end), diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h index f82588f6f90e..6d9d9e7c7ca2 100644 --- a/include/trace/events/landlock.h +++ b/include/trace/events/landlock.h @@ -10,14 +10,19 @@ #if !defined(_TRACE_LANDLOCK_H) || defined(TRACE_HEADER_MULTI_READ) #define _TRACE_LANDLOCK_H +#include <linux/in.h> +#include <linux/in6.h> #include <linux/landlock.h> +#include <linux/socket.h> #include <linux/string.h> #include <linux/string_helpers.h> #include <linux/tracepoint.h> #include <linux/trace_seq.h> #include <net/af_unix.h> +enum landlock_request_type; struct dentry; +struct landlock_blockers; struct landlock_domain; struct landlock_hierarchy; struct landlock_rule; @@ -26,8 +31,26 @@ struct path; struct sock; struct task_struct; +static_assert(sizeof(access_mask_t) <= sizeof(u64)); + +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_ACCESS); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NET_ACCESS); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NAMESPACE); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_CAPABILITY); + #ifdef CREATE_TRACE_POINTS +/* About 6 KiB, leaving about 2 KiB for sibling helpers and fixed fields. */ +#define TRACE_UNTRUSTED_STR_OUTPUT_SIZE \ + (TRACE_SEQ_BUFFER_SIZE - TRACE_SEQ_BUFFER_SIZE / 4) + +/* + * A raw UTF-8 ellipsis (…) marks truncation and cannot collide with escaped + * input: ESCAPE_NAP renders every non-ASCII input byte in octal. + */ +#define TRACE_TRUNCATION_MARKER "\xe2\x80\xa6" + /* * Escapes @len bytes of an untrusted string into the trace sequence @p so it * cannot inject field separators or control characters into the ftrace text @@ -37,33 +60,59 @@ struct task_struct; * NUL-terminated or carries embedded NUL bytes (an abstract socket name) is * escaped in full instead of being truncated at the first NUL. * - * Return: a pointer into @p's buffer, or NULL if @src is NULL or the buffer is - * exhausted (normal when the trace buffer is full). + * Strings that exceed the output limit retain the largest complete escaped + * prefix followed by the truncation marker. + * + * Return: a pointer into @p's buffer, or NULL if @src is NULL or the fixed + * output reservation is unavailable. */ static inline const char * __trace_print_untrusted_str(struct trace_seq *p, const char *src, size_t len) { + const unsigned int escape_flags = ESCAPE_SPACE | ESCAPE_SPECIAL | + ESCAPE_NAP | ESCAPE_APPEND | + ESCAPE_OCTAL; + const size_t marker_len = sizeof(TRACE_TRUNCATION_MARKER) - 1; + size_t buf_size, prefix_len, prefix_size; int escaped_size; char *buf; - size_t buf_size = seq_buf_get_buf(&p->seq, &buf); - const char *ret = trace_seq_buffer_ptr(p); + const char *ret; - /* Buffer exhaustion is normal when the trace buffer is full. */ - if (!src || buf_size == 0) + buf_size = seq_buf_get_buf(&p->seq, &buf); + if (!src || buf_size < TRACE_UNTRUSTED_STR_OUTPUT_SIZE) return NULL; - escaped_size = - string_escape_mem(src, len, buf, buf_size, - ESCAPE_SPACE | ESCAPE_SPECIAL | ESCAPE_NAP | - ESCAPE_APPEND | ESCAPE_OCTAL, - " ='\"\\"); - if (unlikely(escaped_size >= buf_size)) { - /* We need some room for the final '\0'. */ - seq_buf_set_overflow(&p->seq); - p->full = 1; - return NULL; + ret = trace_seq_buffer_ptr(p); + escaped_size = string_escape_mem(src, len, buf, + TRACE_UNTRUSTED_STR_OUTPUT_SIZE, + escape_flags, " ='\"\\"); + if (likely(escaped_size < TRACE_UNTRUSTED_STR_OUTPUT_SIZE)) { + seq_buf_commit(&p->seq, escaped_size); + trace_seq_putc(p, 0); + return ret; } - seq_buf_commit(&p->seq, escaped_size); + + prefix_len = 0; + prefix_size = 0; + while (prefix_len < len) { + const char *const src_char = src + prefix_len; + int char_size; + + char_size = string_escape_mem(src_char, 1, NULL, 0, + escape_flags, " ='\"\\"); + if (char_size > TRACE_UNTRUSTED_STR_OUTPUT_SIZE - marker_len - + 1 - prefix_size) + break; + prefix_size += char_size; + prefix_len++; + } + + escaped_size = string_escape_mem(src, prefix_len, buf, prefix_size, + escape_flags, " ='\"\\"); + if (WARN_ON_ONCE(escaped_size != prefix_size)) + return NULL; + memcpy(buf + prefix_size, TRACE_TRUNCATION_MARKER, marker_len); + seq_buf_commit(&p->seq, prefix_size + marker_len); trace_seq_putc(p, 0); return ret; } @@ -72,7 +121,7 @@ __trace_print_untrusted_str(struct trace_seq *p, const char *src, size_t len) * Fills the dense per-domain-layer array layers (one access mask per layer, * indexed by level - 1) from rule's sparse layer stack, keeping only the * requested rights (access_request). Layers with no matching rule entry get - * a zero mask. Shared by the check_rule_fs and check_rule_net events. + * a zero mask. Shared by the check_rule_inode and check_rule_net_port events. * * rule->layers is sorted by ascending level, with levels in the domain's * [1, num_layers] range (see landlock_merge_ruleset()), so every entry maps @@ -146,6 +195,9 @@ static inline const char *__trace_landlock_print_layers( /* Maps a shared _LANDLOCK_*_NAMES entry to a __print_flags() pair. */ #define _LANDLOCK_NAME_ENTRY(mask, name) { mask, name } +#define _LANDLOCK_FS_BLOCKER_TYPE_NAMES \ + { LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY, "change_topology" } + /** * DOC: Landlock trace events * @@ -156,22 +208,22 @@ static inline const char *__trace_landlock_print_layers( * Decision context * ~~~~~~~~~~~~~~~~ * - * A denial event, together with the lifecycle events, exposes the full - * set of inputs the verdict consumed, so a consumer that tracked domain - * creation (landlock_create_ruleset, landlock_create_domain) can verify - * or reproduce the Landlock decision rather than merely observe it - * happened. In who/what/why terms: who is the denying domain (the domain - * field, always the subject that enforced the policy, never the current - * task), what is the operation and its object, and why is every other - * input the verdict weighed. + * A denial event identifies the domain whose policy denied the request, the + * Landlock operation and policy object that were checked, and the blocker or + * domain relationship responsible for the denial. When tracing starts with + * sandbox construction, ruleset and domain events provide the policy history + * needed to interpret these identifiers. The denying domain is the subject + * that enforced the policy, not necessarily current. Generic tracepoints can + * provide additional operational context. * * Lifecycle consistency * ~~~~~~~~~~~~~~~~~~~~~~ * - * Lifecycle events are balanced: a creation event always has a matching - * deallocation event and vice versa, so an eBPF program can model object - * lifetimes from the trace stream without reconciliation logic. A creation - * event fires while the object is still private to the calling thread + * Lifecycle emission is balanced: a creation event always has a matching + * deallocation event and vice versa. A consumer that observes an object's + * complete lifetime can model it from this pair; one that attaches late or + * loses exported records must reconcile incomplete state. A creation event + * fires while the object is still private to the calling thread * (landlock_create_ruleset fires before the ruleset's file descriptor is * installed, so it cannot race a concurrent :manpage:`close(2)`); if fd * installation later fails and the ruleset is freed, free_ruleset still @@ -207,8 +259,8 @@ static inline const char *__trace_landlock_print_layers( * Field encoding * ~~~~~~~~~~~~~~ * - * Fields that mirror the Landlock UAPI use the same C types and endianness - * (e.g. network ports are __u64 in host endianness, like + * Fields that mirror the Landlock UAPI preserve their widths and endianness + * (e.g. network ports are u64 in host endianness, like * landlock_net_port_attr.port). Per-event details, such as where a value * is byte-swapped, live in the field's own kdoc. * @@ -226,13 +278,14 @@ static inline const char *__trace_landlock_print_layers( * Every denial event shares three fields. domain is the ID of the * innermost domain that blocked the access. same_exec tells whether the * current task is the same executable that entered that domain. logged is - * the domain's audit-logging decision for this denial (its log_status is - * enabled and the per-execution flag selected by same_exec is set); a - * stateless ftrace filter can select the denials the domain submits to - * audit with logged==1, without reconstructing it from the per-execution - * log flags. Denial events order their fields as domain, same_exec, - * logged, then blockers (deny_access events only), then the type-specific - * object fields, then any variable-length field. + * the complete audit-submission selection for this denial: the domain's + * log_status and per-execution flag, per-object or per-member quiet rules, + * and request-specific no-audit options. This excludes global audit state + * and audit-side filters. A stateless ftrace filter can select the denials + * the domain submits to audit with logged==1, without reconstructing those + * inputs. Denial events order their shared fields as domain, same_exec, + * and logged. Access and permission denial events follow these with the + * blockers verdict input, type-specific fields, and any variable-length field. * * Relational referents * ~~~~~~~~~~~~~~~~~~~~~ @@ -245,6 +298,16 @@ static inline const char *__trace_landlock_print_layers( * the two parties without kernel-internal state. The ID is a scalar * snapshot, not a live domain pointer that could dangle: an optional * relational referent is a scalar (0 sentinel), not a nullable pointer. + * Nonzero IDs are unique within one boot. For ptrace, same_exec instead + * describes the tracer, even for + * PTRACE_TRACEME, and may differ from the current task. + * + * Blocker fields + * ~~~~~~~~~~~~~~ + * + * Blocker arguments identify the request type and carry its final missing + * access subset when applicable. The type determines how to interpret the + * access value. */ /* @@ -283,26 +346,31 @@ TRACE_EVENT(landlock_create_ruleset, TP_ARGS(ruleset), TP_STRUCT__entry( - __field( __u64, ruleset_id ) - __field( __u32, ruleset_version ) - __field( access_mask_t, handled_fs ) - __field( access_mask_t, handled_net ) - __field( access_mask_t, scoped ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, handled_fs ) + __field( access_mask_t, handled_net ) + __field( access_mask_t, scoped ) + __field( access_mask_t, handled_permissions ) ), TP_fast_assign( __entry->ruleset_id = ruleset->id; __entry->ruleset_version = ruleset->version; - __entry->handled_fs = ruleset->handled_masks.fs; - __entry->handled_net = ruleset->handled_masks.net; - __entry->scoped = ruleset->handled_masks.scope; + __entry->handled_fs = ruleset->layer.handled.fs; + __entry->handled_net = ruleset->layer.handled.net; + __entry->scoped = ruleset->layer.handled.scope; + __entry->handled_permissions = + ruleset->layer.handled.permissions; ), - TP_printk("ruleset=%llx.%u handled_fs=%s handled_net=%s scoped=%s", + TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s handled_permissions=%s", __entry->ruleset_id, __entry->ruleset_version, __print_flags(__entry->handled_fs, "|", _LANDLOCK_ACCESS_FS_NAMES), __print_flags(__entry->handled_net, "|", _LANDLOCK_ACCESS_NET_NAMES), - __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES)) + __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES), + __print_flags(__entry->handled_permissions, "|", + _LANDLOCK_PERMISSION_NAMES)) ); /** @@ -323,8 +391,8 @@ TRACE_EVENT(landlock_free_ruleset, TP_ARGS(ruleset), TP_STRUCT__entry( - __field( __u64, ruleset_id ) - __field( __u32, ruleset_version ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) ), TP_fast_assign( @@ -332,17 +400,19 @@ TRACE_EVENT(landlock_free_ruleset, __entry->ruleset_version = ruleset->version; ), - TP_printk("ruleset=%llx.%u", + TP_printk("ruleset=%llx.%llu", __entry->ruleset_id, __entry->ruleset_version) ); /** - * landlock_add_rule_fs - Filesystem rule added to a ruleset + * landlock_add_rule_path_beneath - Path-beneath rule added to a ruleset * * @ruleset: Source ruleset (never NULL). - * @access_rights: Effective access mask stored in the rule, not the raw - * sys_landlock_add_rule() argument (unhandled rights - * added). + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @access_rights: Canonical per-call access mask passed to + * landlock_insert_rule() after normalization, not the raw + * sys_landlock_add_rule() argument or accumulated rule. * @path: Filesystem path for the rule (never NULL). * @pathname: Resolved absolute path string (never NULL; error placeholder * on resolution failure). @@ -351,17 +421,17 @@ TRACE_EVENT(landlock_free_ruleset, * the reported ruleset is a stable snapshot that no concurrent writer can * change. */ -TRACE_EVENT(landlock_add_rule_fs, +TRACE_EVENT(landlock_add_rule_path_beneath, - TP_PROTO(const struct landlock_ruleset *ruleset, - access_mask_t access_rights, const struct path *path, + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 access_rights, const struct path *path, const char *pathname), - TP_ARGS(ruleset, access_rights, path, pathname), + TP_ARGS(ruleset, flags, access_rights, path, pathname), TP_STRUCT__entry( - __field( __u64, ruleset_id ) - __field( __u32, ruleset_version ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) __field( access_mask_t, access_rights ) __field( dev_t, dev ) __field( ino_t, ino ) @@ -382,7 +452,7 @@ TRACE_EVENT(landlock_add_rule_fs, __assign_str(pathname); ), - TP_printk("ruleset=%llx.%u access_rights=%s dev=%u:%u ino=%lu path=%s", + TP_printk("ruleset=%llx.%llu access_rights=%s dev=%u:%u ino=%lu path=%s", __entry->ruleset_id, __entry->ruleset_version, __print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_FS_NAMES), MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, @@ -391,31 +461,33 @@ TRACE_EVENT(landlock_add_rule_fs, ); /** - * landlock_add_rule_net - Network port rule added to a ruleset + * landlock_add_rule_net_port - Network-port rule added to a ruleset * * @ruleset: Source ruleset (never NULL). - * @access_rights: Effective access mask stored in the rule, not the raw - * sys_landlock_add_rule() argument (unhandled rights - * added). - * @port: Network port, the landlock_net_port_attr.port UAPI value - * forwarded directly. + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @access_rights: Canonical per-call access mask passed to + * landlock_insert_rule() after normalization, not the raw + * sys_landlock_add_rule() argument or accumulated rule. + * @port: Network port in host endianness, forwarded directly from + * &landlock_net_port_attr.port. * * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so * the reported ruleset is a stable snapshot that no concurrent writer can * change. */ -TRACE_EVENT(landlock_add_rule_net, +TRACE_EVENT(landlock_add_rule_net_port, - TP_PROTO(const struct landlock_ruleset *ruleset, - access_mask_t access_rights, __u64 port), + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 access_rights, u64 port), - TP_ARGS(ruleset, access_rights, port), + TP_ARGS(ruleset, flags, access_rights, port), TP_STRUCT__entry( - __field( __u64, ruleset_id ) - __field( __u32, ruleset_version ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) __field( access_mask_t, access_rights ) - __field( __u64, port ) + __field( u64, port ) ), TP_fast_assign( @@ -426,13 +498,110 @@ TRACE_EVENT(landlock_add_rule_net, __entry->port = port; ), - TP_printk("ruleset=%llx.%u access_rights=%s port=%llu", + TP_printk("ruleset=%llx.%llu access_rights=%s port=%llu", __entry->ruleset_id, __entry->ruleset_version, __print_flags(__entry->access_rights, "|", _LANDLOCK_ACCESS_NET_NAMES), __entry->port) ); /** + * landlock_add_rule_namespace - Namespace rule added to a ruleset + * + * @ruleset: Source ruleset (never NULL). + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @permissions: Validated permission mask from the rule attribute. + * @allowed_namespace_types: Effective known namespace types allowed by this + * call, using CLONE_NEW* values. + * @quiet_namespace_types: Effective known namespace types quieted by this + * call, using CLONE_NEW* values. + * + * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so + * the reported ruleset is a stable snapshot that no concurrent writer can + * change. + */ +TRACE_EVENT(landlock_add_rule_namespace, + + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 permissions, u64 allowed_namespace_types, + u64 quiet_namespace_types), + + TP_ARGS(ruleset, flags, permissions, allowed_namespace_types, + quiet_namespace_types), + + TP_STRUCT__entry( + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, permissions ) + __field( u64, allowed_namespace_types ) + __field( u64, quiet_namespace_types ) + ), + + TP_fast_assign( + lockdep_assert_held(&ruleset->lock); + __entry->ruleset_id = ruleset->id; + __entry->ruleset_version = ruleset->version; + __entry->permissions = permissions; + __entry->allowed_namespace_types = allowed_namespace_types; + __entry->quiet_namespace_types = quiet_namespace_types; + ), + + TP_printk("ruleset=%llx.%llu permissions=%s allowed_namespace_types=0x%llx quiet_namespace_types=0x%llx", + __entry->ruleset_id, __entry->ruleset_version, + __print_flags(__entry->permissions, "|", + _LANDLOCK_PERMISSION_NAMES), + __entry->allowed_namespace_types, + __entry->quiet_namespace_types) +); + +/** + * landlock_add_rule_capability - Capability rule added to a ruleset + * + * @ruleset: Source ruleset (never NULL). + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @permissions: Validated permission mask from the rule attribute. + * @allowed_capabilities: Effective known capabilities allowed by this call. + * @quiet_capabilities: Effective known capabilities quieted by this call. + * + * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so + * the reported ruleset is a stable snapshot that no concurrent writer can + * change. + */ +TRACE_EVENT(landlock_add_rule_capability, + + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 permissions, u64 allowed_capabilities, + u64 quiet_capabilities), + + TP_ARGS(ruleset, flags, permissions, allowed_capabilities, + quiet_capabilities), + + TP_STRUCT__entry( + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, permissions ) + __field( u64, allowed_capabilities ) + __field( u64, quiet_capabilities ) + ), + + TP_fast_assign( + lockdep_assert_held(&ruleset->lock); + __entry->ruleset_id = ruleset->id; + __entry->ruleset_version = ruleset->version; + __entry->permissions = permissions; + __entry->allowed_capabilities = allowed_capabilities; + __entry->quiet_capabilities = quiet_capabilities; + ), + + TP_printk("ruleset=%llx.%llu permissions=%s allowed_capabilities=0x%llx quiet_capabilities=0x%llx", + __entry->ruleset_id, __entry->ruleset_version, + __print_flags(__entry->permissions, "|", + _LANDLOCK_PERMISSION_NAMES), + __entry->allowed_capabilities, __entry->quiet_capabilities) +); + +/** * landlock_create_domain - New domain created * * @domain: Newly created domain (never NULL, immutable after creation). @@ -459,10 +628,10 @@ TRACE_EVENT(landlock_create_domain, TP_ARGS(domain, ruleset), TP_STRUCT__entry( - __field( __u64, domain_id ) - __field( __u64, parent_id ) - __field( __u64, ruleset_id ) - __field( __u32, ruleset_version ) + __field( u64, domain_id ) + __field( u64, parent_id ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) ), TP_fast_assign( @@ -474,7 +643,7 @@ TRACE_EVENT(landlock_create_domain, __entry->ruleset_version = ruleset->version; ), - TP_printk("domain=%llx parent=%llx ruleset=%llx.%u", + TP_printk("domain=%llx parent=%llx ruleset=%llx.%llu", __entry->domain_id, __entry->parent_id, __entry->ruleset_id, __entry->ruleset_version) ); @@ -521,7 +690,7 @@ TRACE_EVENT(landlock_enforce_domain, TP_ARGS(domain, complete, process_wide, no_new_privs), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, complete ) __field( bool, process_wide ) __field( bool, no_new_privs ) @@ -559,8 +728,8 @@ TRACE_EVENT(landlock_free_domain, TP_ARGS(hierarchy), TP_STRUCT__entry( - __field( __u64, domain_id ) - __field( __u64, denials ) + __field( u64, domain_id ) + __field( u64, denials ) ), TP_fast_assign( @@ -573,7 +742,7 @@ TRACE_EVENT(landlock_free_domain, ); /** - * landlock_check_rule_fs - Filesystem rule evaluated during access check + * landlock_check_rule_inode - Inode rule evaluated during access check * * @domain: Enforcing domain (never NULL). * @rule: Matching rule with per-layer access masks (never NULL). @@ -586,16 +755,16 @@ TRACE_EVENT(landlock_free_domain, * domain layer. See Documentation/trace/events-landlock.rst for how to * interpret it. */ -TRACE_EVENT(landlock_check_rule_fs, +TRACE_EVENT(landlock_check_rule_inode, TP_PROTO(const struct landlock_domain *domain, const struct landlock_rule *rule, - access_mask_t access_request, const struct dentry *dentry), + u64 access_request, const struct dentry *dentry), TP_ARGS(domain, rule, access_request, dentry), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( access_mask_t, access_request ) __field( dev_t, dev ) __field( ino_t, ino ) @@ -612,7 +781,8 @@ TRACE_EVENT(landlock_check_rule_fs, __trace_landlock_fill_layers(__get_dynamic_array(grants), __get_dynamic_array_len(grants) / sizeof(access_mask_t), - rule, access_request); + rule, + (access_mask_t)access_request); ), TP_printk("domain=%llx access_request=%s dev=%u:%u ino=%lu grants=%s", @@ -623,7 +793,7 @@ TRACE_EVENT(landlock_check_rule_fs, ); /** - * landlock_check_rule_net - Network port rule evaluated during access check + * landlock_check_rule_net_port - Network port rule evaluated * * @domain: Enforcing domain (never NULL). * @rule: Matching rule with per-layer access masks (never NULL). @@ -635,18 +805,18 @@ TRACE_EVENT(landlock_check_rule_fs, * layer. See Documentation/trace/events-landlock.rst for how to * interpret it. */ -TRACE_EVENT(landlock_check_rule_net, +TRACE_EVENT(landlock_check_rule_net_port, TP_PROTO(const struct landlock_domain *domain, const struct landlock_rule *rule, - access_mask_t access_request, __u64 port), + u64 access_request, u64 port), TP_ARGS(domain, rule, access_request, port), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( access_mask_t, access_request ) - __field( __u64, port ) + __field( u64, port ) __dynamic_array(access_mask_t, grants, domain->num_layers) ), @@ -659,7 +829,8 @@ TRACE_EVENT(landlock_check_rule_net, __trace_landlock_fill_layers(__get_dynamic_array(grants), __get_dynamic_array_len(grants) / sizeof(access_mask_t), - rule, access_request); + rule, + (access_mask_t)access_request); ), TP_printk("domain=%llx access_request=%s port=%llu grants=%s", @@ -676,8 +847,7 @@ TRACE_EVENT(landlock_check_rule_net, * domain field. * @same_exec: Whether the current task entered the denying domain itself. * @logged: The domain's audit-logging decision for this denial. - * @blockers: Access mask that was blocked (zero for a mount-topology - * change, whose only blocker is the operation itself). + * @blockers: Request type and final missing access subset (never NULL). * @path: Filesystem path that was denied (never NULL). * @pathname: Resolved path string (never NULL; an error placeholder on * resolution failure). @@ -687,16 +857,17 @@ TRACE_EVENT(landlock_check_rule_net, TRACE_EVENT(landlock_deny_access_fs, TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, - bool logged, access_mask_t blockers, const struct path *path, - const char *pathname), + bool logged, const struct landlock_blockers *blockers, + const struct path *path, const char *pathname), TP_ARGS(hierarchy, same_exec, logged, blockers, path, pathname), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, same_exec ) __field( bool, logged ) - __field( access_mask_t, blockers ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) __field( dev_t, dev ) __field( ino_t, ino ) __string( pathname, pathname ) @@ -708,7 +879,8 @@ TRACE_EVENT(landlock_deny_access_fs, __entry->domain_id = hierarchy->id; __entry->same_exec = same_exec; __entry->logged = logged; - __entry->blockers = blockers; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; __entry->dev = path->dentry->d_sb->s_dev; /* * A negative dentry has no backing inode, so mirror the @@ -720,12 +892,20 @@ TRACE_EVENT(landlock_deny_access_fs, TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s dev=%u:%u ino=%lu path=%s", __entry->domain_id, __entry->same_exec, __entry->logged, - __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_FS_NAMES), + __entry->blockers_type == LANDLOCK_REQUEST_FS_ACCESS ? + __print_flags(__entry->blockers_access, "|", _LANDLOCK_ACCESS_FS_NAMES) : + __print_symbolic(__entry->blockers_type, + _LANDLOCK_FS_BLOCKER_TYPE_NAMES), MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, __trace_print_untrusted_str(p, __get_str(pathname), __get_dynamic_array_len(pathname) - 1)) ); +static_assert(offsetof(struct sockaddr_in, sin_port) == + offsetof(struct sockaddr_in6, sin6_port)); +static_assert(sizeof_field(struct sockaddr_in, sin_port) == + sizeof_field(struct sockaddr_in6, sin6_port)); + /** * landlock_deny_access_net - Network access denied * @@ -733,67 +913,183 @@ TRACE_EVENT(landlock_deny_access_fs, * domain field. * @same_exec: Whether the current task entered the denying domain itself. * @logged: The domain's audit-logging decision for this denial. - * @blockers: Access mask that was blocked. - * @sk: Socket object (never NULL), read without a socket lock, so its - * fields are a best-effort snapshot. The denied endpoint is not - * available: the hook runs before :manpage:`bind(2)` / - * :manpage:`connect(2)` sets the socket addresses. - * @sport: Source port in host endianness, set for bind denials (zero for - * an autobind/ephemeral port); zero for connect and send denials. - * @dport: Destination port in host endianness, set for connect and send - * denials; zero for bind denials, and also zero for a UDP send to - * an AF_UNSPEC address on an IPv6 socket (indistinguishable from a - * real destination port 0). The bind-vs-connect direction is - * given by @blockers, not by which port is set. - * - * Emitted when a Landlock domain denies a network operation. - * - * The port fields are converted from the socket's network byte order to - * host endianness before emitting. + * @blockers: Request type and final missing access subset (never NULL). + * @sk: Socket object (never NULL), read without a socket lock, so its fields + * are a best-effort snapshot. + * @socket_family: Socket-family snapshot used by the verdict. + * @address: Authoritative address checked by the verdict (never NULL). + * The producer copies @addrlen bytes from the checked address and + * zeroes the remaining storage before emission. The + * &sockaddr_in.sin_port or &sockaddr_in6.sin6_port member, when + * present, remains in network endianness. + * @addrlen: Validated signed length of @address. + * + * Emitted when a Landlock domain denies a network operation. The blocker + * identifies whether the address is a bind or connect/send policy object. + * The flattened port field is converted from the checked address to host + * endianness, or is -1 when no port was checked. Zero is a valid checked + * port. */ TRACE_EVENT(landlock_deny_access_net, TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, - bool logged, access_mask_t blockers, const struct sock *sk, - __u64 sport, __u64 dport), + bool logged, const struct landlock_blockers *blockers, + const struct sock *sk, u16 socket_family, + const struct sockaddr_storage *address, int addrlen), + + TP_ARGS(hierarchy, same_exec, logged, blockers, sk, socket_family, + address, addrlen), + + TP_STRUCT__entry( + __field( u64, domain_id ) + __field( bool, same_exec ) + __field( bool, logged ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) + __field( s64, port ) + ), + + TP_fast_assign( + const struct sockaddr *const addr = + (const struct sockaddr *)address; + const bool has_port = + addrlen >= (int)offsetofend(struct sockaddr_in, sin_port) && + (addr->sa_family == AF_INET || + addr->sa_family == AF_INET6 || + (addr->sa_family == AF_UNSPEC && + socket_family == AF_INET)); + + __entry->domain_id = hierarchy->id; + __entry->same_exec = same_exec; + __entry->logged = logged; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; + __entry->port = + has_port ? + ntohs(((const struct sockaddr_in *)addr)->sin_port) : + -1; + ), + + TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s port=%lld", + __entry->domain_id, __entry->same_exec, __entry->logged, + __entry->blockers_type == LANDLOCK_REQUEST_NET_ACCESS ? + __print_flags(__entry->blockers_access, "|", _LANDLOCK_ACCESS_NET_NAMES) : + "unknown", + __entry->port) +); + +/** + * landlock_deny_permission_namespace - Namespace use denied + * + * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the + * domain field. + * @same_exec: Whether the current task entered the denying domain itself. + * @logged: Whether this denial was selected for audit logging. + * @blockers: Request type and final missing permission subset (never NULL). + * @namespace_type: CLONE_NEW* namespace type that was denied. + * @namespace_id: Namespace ID, or 0 when creation was denied. + * + * Emitted when a Landlock domain denies namespace use. + */ +TRACE_EVENT(landlock_deny_permission_namespace, + + TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, + bool logged, const struct landlock_blockers *blockers, + u32 namespace_type, u64 namespace_id), - TP_ARGS(hierarchy, same_exec, logged, blockers, sk, sport, dport), + TP_ARGS(hierarchy, same_exec, logged, blockers, namespace_type, + namespace_id), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, same_exec ) __field( bool, logged ) - __field( access_mask_t, blockers ) - __field( __u64, sport ) - __field( __u64, dport ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) + __field( u32, namespace_type ) + __field( u64, namespace_id ) ), TP_fast_assign( __entry->domain_id = hierarchy->id; __entry->same_exec = same_exec; __entry->logged = logged; - __entry->blockers = blockers; - __entry->sport = sport; - __entry->dport = dport; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; + __entry->namespace_type = namespace_type; + __entry->namespace_id = namespace_id; ), - TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s sport=%llu dport=%llu", + TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s namespace_type=0x%x namespace_id=%llu", __entry->domain_id, __entry->same_exec, __entry->logged, - __print_flags(__entry->blockers, "|", _LANDLOCK_ACCESS_NET_NAMES), - __entry->sport, __entry->dport) + __entry->blockers_type == LANDLOCK_REQUEST_NAMESPACE ? + __print_flags(__entry->blockers_access, "|", + _LANDLOCK_PERMISSION_BLOCKER_NAMES) : + "unknown", + __entry->namespace_type, __entry->namespace_id) ); /** - * landlock_deny_ptrace - Ptrace access denied by a Landlock domain + * landlock_deny_permission_capability - Capability use denied * * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the * domain field. * @same_exec: Whether the current task entered the denying domain itself. + * @logged: Whether this denial was selected for audit logging. + * @blockers: Request type and final missing permission subset (never NULL). + * @capability: CAP_* number that was denied. + * + * Emitted when a Landlock domain denies capability use, except for checks + * made with CAP_OPT_NOAUDIT, which are denied without emitting this event. + */ +TRACE_EVENT(landlock_deny_permission_capability, + + TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, + bool logged, const struct landlock_blockers *blockers, + int capability), + + TP_ARGS(hierarchy, same_exec, logged, blockers, capability), + + TP_STRUCT__entry( + __field( u64, domain_id ) + __field( bool, same_exec ) + __field( bool, logged ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) + __field( int, capability ) + ), + + TP_fast_assign( + __entry->domain_id = hierarchy->id; + __entry->same_exec = same_exec; + __entry->logged = logged; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; + __entry->capability = capability; + ), + + TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s capability=%d", + __entry->domain_id, __entry->same_exec, __entry->logged, + __entry->blockers_type == LANDLOCK_REQUEST_CAPABILITY ? + __print_flags(__entry->blockers_access, "|", + _LANDLOCK_PERMISSION_BLOCKER_NAMES) : + "unknown", + __entry->capability) +); + +/** + * landlock_deny_ptrace - Ptrace access denied by a Landlock domain + * + * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the + * domain field. + * @same_exec: Whether the tracer entered the denying domain itself. * @logged: The domain's audit-logging decision for this denial. * @tracee_domain_id: The tracee's Landlock domain ID, or 0 if the tracee * is unsandboxed. * @tracee: The target task ptrace acted on (never NULL). tracee_pid is * the init-namespace TGID (like audit's opid). + * @tracer: The tracer or proposed tracer (never NULL); for PTRACE_TRACEME + * this is the parent, not the syscall caller. * * Emitted when a Landlock domain denies a ptrace operation. */ @@ -801,15 +1097,16 @@ TRACE_EVENT(landlock_deny_ptrace, TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, bool logged, u64 tracee_domain_id, - const struct task_struct *tracee), + const struct task_struct *tracee, + const struct task_struct *tracer), - TP_ARGS(hierarchy, same_exec, logged, tracee_domain_id, tracee), + TP_ARGS(hierarchy, same_exec, logged, tracee_domain_id, tracee, tracer), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, same_exec ) __field( bool, logged ) - __field( __u64, tracee_domain_id) + __field( u64, tracee_domain_id) __field( pid_t, tracee_pid ) __string( tracee_comm, tracee->comm ) ), @@ -836,12 +1133,14 @@ TRACE_EVENT(landlock_deny_ptrace, * * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the * domain field. - * @same_exec: Whether the current task entered the denying domain itself. + * @same_exec: Whether the policy subject entered the denying domain itself. * @logged: The domain's audit-logging decision for this denial. * @target_domain_id: The target's Landlock domain ID, or 0 if the target * is unsandboxed. * @target: The task the signal was aimed at (never NULL). target_pid is * the init-namespace TGID (like audit's opid). + * @signal: The signal selected by the denied check. Zero is a permission + * probe, not an absent value. * * Emitted when a Landlock domain denies signal delivery to a scoped-out * target. @@ -850,15 +1149,15 @@ TRACE_EVENT(landlock_deny_scope_signal, TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, bool logged, u64 target_domain_id, - const struct task_struct *target), + const struct task_struct *target, int signal), - TP_ARGS(hierarchy, same_exec, logged, target_domain_id, target), + TP_ARGS(hierarchy, same_exec, logged, target_domain_id, target, signal), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, same_exec ) __field( bool, logged ) - __field( __u64, target_domain_id) + __field( u64, target_domain_id) __field( pid_t, target_pid ) __string( target_comm, target->comm ) ), @@ -904,10 +1203,10 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket, TP_ARGS(hierarchy, same_exec, logged, peer_domain_id, peer), TP_STRUCT__entry( - __field( __u64, domain_id ) + __field( u64, domain_id ) __field( bool, same_exec ) __field( bool, logged ) - __field( __u64, peer_domain_id ) + __field( u64, peer_domain_id ) __field( pid_t, peer_pid ) /* * Abstract socket names are untrusted binary data from @@ -937,13 +1236,12 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket, __entry->logged = logged; __entry->peer_domain_id = peer_domain_id; /* - * Best-effort (0 for a datagram peer). sk_peer_pid is - * canonically guarded by sk->sk_peer_lock, but the target - * peer's peercred is set once and not updated concurrently in - * these hooks, so this READ_ONCE() is safe; sun_path is the - * reliable identifier. + * Best-effort (0 for a datagram peer). The caller holds the + * peer's AF_UNIX state lock, serializing published peercred + * updates. The peer socket keeps a reference to sk_peer_pid + * through pid_nr(); sun_path is the reliable identifier. */ - peer_pid = READ_ONCE(peer->sk_peer_pid); + peer_pid = READ_ONCE(peer->sk_peer_pid[PIDTYPE_TGID]); __entry->peer_pid = peer_pid ? pid_nr(peer_pid) : 0; __assign_str(sun_path); ), @@ -955,6 +1253,7 @@ TRACE_EVENT(landlock_deny_scope_abstract_unix_socket, __get_dynamic_array_len(sun_path) - 1)) ); +#undef _LANDLOCK_FS_BLOCKER_TYPE_NAMES #undef _LANDLOCK_NAME_ENTRY #endif /* _TRACE_LANDLOCK_H */ diff --git a/include/trace/events/mmflags.h b/include/trace/events/mmflags.h index 935893e5ea53..3c153b3ad845 100644 --- a/include/trace/events/mmflags.h +++ b/include/trace/events/mmflags.h @@ -144,7 +144,7 @@ TRACE_DEFINE_ENUM(___GFP_LAST_BIT); DEF_PAGEFLAG_NAME(owner_2), \ DEF_PAGEFLAG_NAME(arch_1), \ DEF_PAGEFLAG_NAME(reserved), \ - DEF_PAGEFLAG_NAME(private), \ + DEF_PAGEFLAG_NAME(folio), \ DEF_PAGEFLAG_NAME(private_2), \ DEF_PAGEFLAG_NAME(writeback), \ DEF_PAGEFLAG_NAME(head), \ @@ -168,6 +168,10 @@ IF_HAVE_PG_ARCH_3(arch_3) #define __VM_ARCH_SPECIFIC_1 {VM_SAO, "sao" } #elif defined(CONFIG_PARISC) #define __VM_ARCH_SPECIFIC_1 {VM_GROWSUP, "growsup" } +#elif defined(CONFIG_SPARC64) +#define __VM_ARCH_SPECIFIC_1 {VM_SPARC_ADI, "adi" } +#elif defined(CONFIG_ARM64) +#define __VM_ARCH_SPECIFIC_1 {VM_ARM64_BTI, "bti" } #elif !defined(CONFIG_MMU) #define __VM_ARCH_SPECIFIC_1 {VM_MAPPED_COPY,"mappedcopy" } #else @@ -198,6 +202,37 @@ IF_HAVE_PG_ARCH_3(arch_3) # define IF_HAVE_VM_DROPPABLE(flag, name) #endif +#ifdef CONFIG_ARCH_HAS_PKEYS +# define IF_HAVE_VM_PKEY(flag, name) {flag, name}, +#if CONFIG_ARCH_PKEY_BITS > 3 +# define IF_HAVE_VM_PKEY3(flag, name) {flag, name}, +#else +# define IF_HAVE_VM_PKEY3(flag, name) +#endif +#if CONFIG_ARCH_PKEY_BITS > 4 +# define IF_HAVE_VM_PKEY4(flag, name) {flag, name}, +#else +# define IF_HAVE_VM_PKEY4(flag, name) +#endif +#else +# define IF_HAVE_VM_PKEY(flag, name) +# define IF_HAVE_VM_PKEY3(flag, name) +# define IF_HAVE_VM_PKEY4(flag, name) +#endif + +#ifdef CONFIG_ARM64_MTE +# define IF_HAVE_VM_MTE(flag, name) {flag, name}, +#else +# define IF_HAVE_VM_MTE(flag, name) +#endif + +#if defined(CONFIG_X86_USER_SHADOW_STACK) || defined(CONFIG_RISCV_USER_CFI) || \ + defined(CONFIG_ARM64_GCS) +# define IF_HAVE_VM_SHADOW_STACK(flag, name) {flag, name}, +#else +# define IF_HAVE_VM_SHADOW_STACK(flag, name) +#endif + #define __def_vmaflag_names \ {VM_READ, "read" }, \ {VM_WRITE, "write" }, \ @@ -233,6 +268,14 @@ IF_HAVE_VM_SOFTDIRTY(VM_SOFTDIRTY, "softdirty" ) \ {VM_HUGEPAGE, "hugepage" }, \ {VM_NOHUGEPAGE, "nohugepage" }, \ IF_HAVE_VM_DROPPABLE(VM_DROPPABLE, "droppable" ) \ +IF_HAVE_VM_PKEY(VM_PKEY_BIT0, "pkey_bit0") \ +IF_HAVE_VM_PKEY(VM_PKEY_BIT1, "pkey_bit1") \ +IF_HAVE_VM_PKEY(VM_PKEY_BIT2, "pkey_bit2") \ +IF_HAVE_VM_PKEY3(VM_PKEY_BIT3, "pkey_bit3") \ +IF_HAVE_VM_PKEY4(VM_PKEY_BIT4, "pkey_bit4") \ +IF_HAVE_VM_MTE(VM_MTE, "mte") \ +IF_HAVE_VM_MTE(VM_MTE_ALLOWED, "mte_allowed") \ +IF_HAVE_VM_SHADOW_STACK(VM_SHADOW_STACK, "shadow_stack") \ {VM_MERGEABLE, "mergeable" } \ #define show_vma_flags(flags) \ diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h index 082cb03c6131..bf1e1f185b05 100644 --- a/include/trace/events/netfs.h +++ b/include/trace/events/netfs.h @@ -30,8 +30,7 @@ EM(netfs_write_trace_dio_write, "DIO-WRITE") \ EM(netfs_write_trace_unbuffered_write, "UNB-WRITE") \ EM(netfs_write_trace_writeback, "WRITEBACK") \ - EM(netfs_write_trace_writeback_single, "WB-SINGLE") \ - E_(netfs_write_trace_writethrough, "WRITETHRU") + E_(netfs_write_trace_writeback_single, "WB-SINGLE") #define netfs_rreq_origins \ EM(NETFS_READAHEAD, "RA") \ @@ -43,13 +42,17 @@ EM(NETFS_DIO_READ, "DR") \ EM(NETFS_WRITEBACK, "WB") \ EM(NETFS_WRITEBACK_SINGLE, "W1") \ - EM(NETFS_WRITETHROUGH, "WT") \ EM(NETFS_UNBUFFERED_WRITE, "UW") \ EM(NETFS_DIO_WRITE, "DW") \ E_(NETFS_PGPRIV2_COPY_TO_CACHE, "2C") #define netfs_rreq_traces \ + EM(netfs_rreq_trace_all_queued, "ALL-Q ") \ EM(netfs_rreq_trace_assess, "ASSESS ") \ + EM(netfs_rreq_trace_cache_cancelled, "CA-CNCL") \ + EM(netfs_rreq_trace_cache_failed, "CA-FAIL") \ + EM(netfs_rreq_trace_cache_fail_collect, "CA-F-CO") \ + EM(netfs_rreq_trace_cache_no_space, "CA-NOSP") \ EM(netfs_rreq_trace_collect, "COLLECT") \ EM(netfs_rreq_trace_complete, "COMPLET") \ EM(netfs_rreq_trace_copy, "COPY ") \ @@ -58,10 +61,14 @@ EM(netfs_rreq_trace_end_copy_to_cache, "END-C2C") \ EM(netfs_rreq_trace_free, "FREE ") \ EM(netfs_rreq_trace_intr, "INTR ") \ + EM(netfs_rreq_trace_inval_cache, "INVL-CA") \ EM(netfs_rreq_trace_ki_complete, "KI-CMPL") \ + EM(netfs_rreq_trace_ra_put_ref, "RA-PUT ") \ EM(netfs_rreq_trace_recollect, "RECLLCT") \ EM(netfs_rreq_trace_redirty, "REDIRTY") \ EM(netfs_rreq_trace_resubmit, "RESUBMT") \ + EM(netfs_rreq_trace_retry_begin, "RETRY-BEGIN") \ + EM(netfs_rreq_trace_retry_end, "RETRY-END") \ EM(netfs_rreq_trace_set_abandon, "S-ABNDN") \ EM(netfs_rreq_trace_set_pause, "PAUSE ") \ EM(netfs_rreq_trace_unlock, "UNLOCK ") \ @@ -70,9 +77,11 @@ EM(netfs_rreq_trace_unpause, "UNPAUSE") \ EM(netfs_rreq_trace_wait_ip, "WAIT-IP") \ EM(netfs_rreq_trace_wait_pause, "--PAUSED--") \ + EM(netfs_rreq_trace_wait_put_ra_refs, "WAIT-P-RA") \ EM(netfs_rreq_trace_wait_quiesce, "WAIT-QUIESCE") \ EM(netfs_rreq_trace_waited_ip, "DONE-IP") \ EM(netfs_rreq_trace_waited_pause, "--UNPAUSED--") \ + EM(netfs_rreq_trace_waited_put_ra_refs, "DONE-P-RA") \ EM(netfs_rreq_trace_waited_quiesce, "DONE-QUIESCE") \ EM(netfs_rreq_trace_wake_ip, "WAKE-IP") \ EM(netfs_rreq_trace_wake_queue, "WAKE-Q ") \ @@ -91,8 +100,10 @@ EM(netfs_sreq_trace_abandoned, "ABNDN") \ EM(netfs_sreq_trace_add_donations, "+DON ") \ EM(netfs_sreq_trace_added, "ADD ") \ + EM(netfs_sreq_trace_cache_nofile, "CA-!F") \ EM(netfs_sreq_trace_cache_nowrite, "CA-NW") \ EM(netfs_sreq_trace_cache_prepare, "CA-PR") \ + EM(netfs_sreq_trace_cache_waitfail, "CA-!W") \ EM(netfs_sreq_trace_cache_write, "CA-WR") \ EM(netfs_sreq_trace_cancel, "CANCL") \ EM(netfs_sreq_trace_clear, "CLEAR") \ @@ -131,12 +142,12 @@ #define netfs_failures \ EM(netfs_fail_check_write_begin, "check-write-begin") \ - EM(netfs_fail_copy_to_cache, "copy-to-cache") \ EM(netfs_fail_dio_read_short, "dio-read-short") \ EM(netfs_fail_dio_read_zero, "dio-read-zero") \ EM(netfs_fail_read, "read") \ EM(netfs_fail_short_read, "short-read") \ EM(netfs_fail_prepare_write, "prep-write") \ + EM(netfs_fail_upload, "upload") \ E_(netfs_fail_write, "write") #define netfs_rreq_ref_traces \ @@ -191,12 +202,11 @@ EM(netfs_folio_trace_alloc_buffer, "alloc-buf") \ EM(netfs_folio_trace_cancel_copy, "cancel-copy") \ EM(netfs_folio_trace_cancel_store, "cancel-store") \ - EM(netfs_folio_trace_clear, "clear") \ - EM(netfs_folio_trace_clear_cc, "clear-cc") \ - EM(netfs_folio_trace_clear_g, "clear-g") \ - EM(netfs_folio_trace_clear_s, "clear-s") \ - EM(netfs_folio_trace_copy_to_cache, "mark-copy") \ EM(netfs_folio_trace_end_copy, "end-copy") \ + EM(netfs_folio_trace_endwb, "endwb") \ + EM(netfs_folio_trace_endwb_cc, "endwb-cc") \ + EM(netfs_folio_trace_endwb_g, "endwb-g") \ + EM(netfs_folio_trace_endwb_s, "endwb-s") \ EM(netfs_folio_trace_filled_gaps, "filled-gaps") \ EM(netfs_folio_trace_invalidate_all, "inval-all") \ EM(netfs_folio_trace_invalidate_front, "inval-front") \ @@ -206,21 +216,22 @@ EM(netfs_folio_trace_kill_cc, "kill-cc") \ EM(netfs_folio_trace_kill_g, "kill-g") \ EM(netfs_folio_trace_kill_s, "kill-s") \ + EM(netfs_folio_trace_mark_copy, "mark-copy") \ EM(netfs_folio_trace_mkwrite, "mkwrite") \ EM(netfs_folio_trace_mkwrite_plus, "mkwrite+") \ - EM(netfs_folio_trace_not_under_wback, "!wback") \ EM(netfs_folio_trace_not_locked, "!locked") \ + EM(netfs_folio_trace_not_under_wback, "!wback") \ + EM(netfs_folio_trace_pgpriv2_copy, "pgpriv2-copy") \ EM(netfs_folio_trace_put, "put") \ EM(netfs_folio_trace_read, "read") \ EM(netfs_folio_trace_read_done, "read-done") \ EM(netfs_folio_trace_read_gaps, "read-gaps") \ EM(netfs_folio_trace_read_unlock, "read-unlock") \ EM(netfs_folio_trace_redirtied, "redirtied") \ + EM(netfs_folio_trace_sched_copy, "sched-copy") \ EM(netfs_folio_trace_store, "store") \ EM(netfs_folio_trace_store_copy, "store-copy") \ - EM(netfs_folio_trace_store_plus, "store+") \ - EM(netfs_folio_trace_wthru, "wthru") \ - E_(netfs_folio_trace_wthru_plus, "wthru+") + E_(netfs_folio_trace_store_plus, "store+") #define netfs_collect_contig_traces \ EM(netfs_contig_trace_collect, "Collect") \ @@ -296,7 +307,7 @@ netfs_folioq_traces; TRACE_EVENT(netfs_read, TP_PROTO(struct netfs_io_request *rreq, - loff_t start, size_t len, + uoff_t start, size_t len, enum netfs_read_trace what), TP_ARGS(rreq, start, len, what), @@ -304,8 +315,9 @@ TRACE_EVENT(netfs_read, TP_STRUCT__entry( __field(unsigned int, rreq) __field(unsigned int, cookie) - __field(loff_t, i_size) - __field(loff_t, start) + __field(unsigned int, object) + __field(uoff_t, i_size) + __field(uoff_t, start) __field(size_t, len) __field(enum netfs_read_trace, what) __field(u64, netfs_inode) @@ -313,7 +325,8 @@ TRACE_EVENT(netfs_read, TP_fast_assign( __entry->rreq = rreq->debug_id; - __entry->cookie = rreq->cache_resources.debug_id; + __entry->cookie = rreq->cache_resources.cookie_id; + __entry->object = rreq->cache_resources.object_id; __entry->i_size = rreq->i_size; __entry->start = start; __entry->len = len; @@ -321,10 +334,10 @@ TRACE_EVENT(netfs_read, __entry->netfs_inode = rreq->inode->i_ino; ), - TP_printk("R=%08x %s c=%08x ni=%llx s=%llx l=%zx sz=%llx", + TP_printk("R=%08x %s c=%08x o=%08x ni=%llx s=%llx l=%zx sz=%llx", __entry->rreq, __print_symbolic(__entry->what, netfs_read_traces), - __entry->cookie, + __entry->cookie, __entry->object, __entry->netfs_inode, __entry->start, __entry->len, __entry->i_size) ); @@ -372,7 +385,7 @@ TRACE_EVENT(netfs_sreq, __field(u8, slot) __field(size_t, len) __field(size_t, transferred) - __field(loff_t, start) + __field(uoff_t, start) ), TP_fast_assign( @@ -413,7 +426,7 @@ TRACE_EVENT(netfs_failure, __field(enum netfs_failure, what) __field(size_t, len) __field(size_t, transferred) - __field(loff_t, start) + __field(uoff_t, start) ), TP_fast_assign( @@ -496,6 +509,7 @@ TRACE_EVENT(netfs_folio, TP_STRUCT__entry( __field(u64, ino) __field(pgoff_t, index) + __field(unsigned long, pfn) __field(unsigned int, nr) __field(enum netfs_folio_trace, why) ), @@ -506,9 +520,11 @@ TRACE_EVENT(netfs_folio, __entry->why = why; __entry->index = folio->index; __entry->nr = folio_nr_pages(folio); + __entry->pfn = folio_pfn(folio); ), - TP_printk("i=%05llx ix=%05lx-%05lx %s", + TP_printk("p=%lx i=%05llx ix=%05lx-%05lx %s", + __entry->pfn, __entry->ino, __entry->index, __entry->index + __entry->nr - 1, __print_symbolic(__entry->why, netfs_folio_traces)) ); @@ -519,10 +535,10 @@ TRACE_EVENT(netfs_write_iter, TP_ARGS(iocb, from), TP_STRUCT__entry( - __field(unsigned long long, start) - __field(size_t, len) - __field(unsigned int, flags) - __field(unsigned int, ino) + __field(uoff_t, start) + __field(size_t, len) + __field(unsigned int, flags) + __field(unsigned int, ino) ), TP_fast_assign( @@ -545,27 +561,27 @@ TRACE_EVENT(netfs_write, TP_STRUCT__entry( __field(unsigned int, wreq) __field(unsigned int, cookie) + __field(unsigned int, object) __field(unsigned int, ino) __field(enum netfs_write_trace, what) - __field(unsigned long long, start) - __field(unsigned long long, len) + __field(uoff_t, start) + __field(uoff_t, len) ), TP_fast_assign( - struct netfs_inode *__ctx = netfs_inode(wreq->inode); - struct fscache_cookie *__cookie = netfs_i_cookie(__ctx); __entry->wreq = wreq->debug_id; - __entry->cookie = __cookie ? __cookie->debug_id : 0; + __entry->cookie = wreq->cache_resources.cookie_id; + __entry->object = wreq->cache_resources.object_id; __entry->ino = wreq->inode->i_ino; __entry->what = what; __entry->start = wreq->start; __entry->len = wreq->len; ), - TP_printk("R=%08x %s c=%08x i=%x by=%llx-%llx", + TP_printk("R=%08x %s c=%08x o=%08x i=%x by=%llx-%llx", __entry->wreq, __print_symbolic(__entry->what, netfs_write_traces), - __entry->cookie, + __entry->cookie, __entry->object, __entry->ino, __entry->start, __entry->start + __entry->len - 1) ); @@ -577,25 +593,26 @@ TRACE_EVENT(netfs_copy2cache, TP_ARGS(rreq, creq), TP_STRUCT__entry( - __field(unsigned int, rreq) - __field(unsigned int, creq) - __field(unsigned int, cookie) - __field(unsigned int, ino) + __field(unsigned int, rreq) + __field(unsigned int, creq) + __field(unsigned int, cookie) + __field(unsigned int, object) + __field(unsigned int, ino) ), TP_fast_assign( - struct netfs_inode *__ctx = netfs_inode(rreq->inode); - struct fscache_cookie *__cookie = netfs_i_cookie(__ctx); __entry->rreq = rreq->debug_id; __entry->creq = creq->debug_id; - __entry->cookie = __cookie ? __cookie->debug_id : 0; + __entry->cookie = rreq->cache_resources.cookie_id; + __entry->object = rreq->cache_resources.object_id; __entry->ino = rreq->inode->i_ino; ), - TP_printk("R=%08x CR=%08x c=%08x i=%x ", + TP_printk("R=%08x CR=%08x c=%08x o=%08x i=%x ", __entry->rreq, __entry->creq, __entry->cookie, + __entry->object, __entry->ino) ); @@ -605,10 +622,10 @@ TRACE_EVENT(netfs_collect, TP_ARGS(wreq), TP_STRUCT__entry( - __field(unsigned int, wreq) - __field(unsigned int, len) - __field(unsigned long long, transferred) - __field(unsigned long long, start) + __field(unsigned int, wreq) + __field(unsigned int, len) + __field(uoff_t, transferred) + __field(uoff_t, start) ), TP_fast_assign( @@ -631,12 +648,12 @@ TRACE_EVENT(netfs_collect_sreq, TP_ARGS(wreq, subreq), TP_STRUCT__entry( - __field(unsigned int, wreq) - __field(unsigned int, subreq) - __field(unsigned int, stream) - __field(unsigned int, len) - __field(unsigned int, transferred) - __field(unsigned long long, start) + __field(unsigned int, wreq) + __field(unsigned int, subreq) + __field(unsigned int, stream) + __field(unsigned int, len) + __field(unsigned int, transferred) + __field(uoff_t, start) ), TP_fast_assign( @@ -655,37 +672,30 @@ TRACE_EVENT(netfs_collect_sreq, TRACE_EVENT(netfs_collect_folio, TP_PROTO(const struct netfs_io_request *wreq, - const struct folio *folio, - unsigned long long fend, - unsigned long long collected_to), + const struct folio *folio), - TP_ARGS(wreq, folio, fend, collected_to), + TP_ARGS(wreq, folio), TP_STRUCT__entry( __field(unsigned int, wreq) __field(unsigned long, index) - __field(unsigned long long, fend) - __field(unsigned long long, cleaned_to) - __field(unsigned long long, collected_to) + __field(unsigned int, nr) ), TP_fast_assign( __entry->wreq = wreq->debug_id; __entry->index = folio->index; - __entry->fend = fend; - __entry->cleaned_to = wreq->cleaned_to; - __entry->collected_to = collected_to; + __entry->nr = folio_nr_pages(folio); ), - TP_printk("R=%08x ix=%05lx r=%llx-%llx t=%llx/%llx", + TP_printk("R=%08x ix=%05lx-%05lx", __entry->wreq, __entry->index, - (unsigned long long)__entry->index * PAGE_SIZE, __entry->fend, - __entry->cleaned_to, __entry->collected_to) + __entry->index + __entry->nr - 1) ); TRACE_EVENT(netfs_collect_state, TP_PROTO(const struct netfs_io_request *wreq, - unsigned long long collected_to, + uoff_t collected_to, unsigned int notes), TP_ARGS(wreq, collected_to, notes), @@ -693,8 +703,8 @@ TRACE_EVENT(netfs_collect_state, TP_STRUCT__entry( __field(unsigned int, wreq) __field(unsigned int, notes) - __field(unsigned long long, collected_to) - __field(unsigned long long, cleaned_to) + __field(uoff_t, collected_to) + __field(uoff_t, cleaned_to) ), TP_fast_assign( @@ -713,7 +723,7 @@ TRACE_EVENT(netfs_collect_state, TRACE_EVENT(netfs_collect_gap, TP_PROTO(const struct netfs_io_request *wreq, const struct netfs_io_stream *stream, - unsigned long long jump_to, char type), + uoff_t jump_to, char type), TP_ARGS(wreq, stream, jump_to, type), @@ -721,8 +731,8 @@ TRACE_EVENT(netfs_collect_gap, __field(unsigned int, wreq) __field(unsigned char, stream) __field(unsigned char, type) - __field(unsigned long long, from) - __field(unsigned long long, to) + __field(uoff_t, from) + __field(uoff_t, to) ), TP_fast_assign( @@ -747,8 +757,8 @@ TRACE_EVENT(netfs_collect_stream, TP_STRUCT__entry( __field(unsigned int, wreq) __field(unsigned char, stream) - __field(unsigned long long, collected_to) - __field(unsigned long long, issued_to) + __field(uoff_t, collected_to) + __field(uoff_t, issued_to) ), TP_fast_assign( @@ -786,6 +796,27 @@ TRACE_EVENT(netfs_folioq, __print_symbolic(__entry->trace, netfs_folioq_traces)) ); +TRACE_EVENT(netfs_read_progress_at, + TP_PROTO(const struct netfs_io_request *rreq), + + TP_ARGS(rreq), + + TP_STRUCT__entry( + __field(unsigned int, rreq) + __field(size_t, progress_at) + __field(size_t, cleaned_to) + ), + + TP_fast_assign( + __entry->rreq = rreq->debug_id; + __entry->cleaned_to = rreq->cleaned_to - rreq->start; + __entry->progress_at = rreq->progress_at; + ), + + TP_printk("R=%08x cln=%zx prg=%zx", + __entry->rreq, __entry->cleaned_to, __entry->progress_at) + ); + #undef EM #undef E_ #endif /* _TRACE_NETFS_H */ diff --git a/include/trace/events/ntfs3.h b/include/trace/events/ntfs3.h new file mode 100644 index 000000000000..750300068984 --- /dev/null +++ b/include/trace/events/ntfs3.h @@ -0,0 +1,389 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ntfs3 + +#if !defined(_TRACE_NTFS3_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_NTFS3_H + +#include <linux/fs.h> +#include <linux/tracepoint.h> + +TRACE_EVENT(ntfs3_fill_super, + TP_PROTO(struct super_block *sb, bool ro, u32 cluster_size, + u32 record_size, u32 index_size, int err), + TP_ARGS(sb, ro, cluster_size, record_size, index_size, err), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u32, cluster_size) + __field(u32, record_size) + __field(u32, index_size) + __field(int, err) + __field(bool, ro) + ), + TP_fast_assign( + __entry->dev = sb->s_bdev->bd_dev; + __entry->cluster_size = cluster_size; + __entry->record_size = record_size; + __entry->index_size = index_size; + __entry->err = err; + __entry->ro = ro; + ), + TP_printk("dev=(%d,%d) ro=%d cluster=%u record=%u index=%u err=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ro, + __entry->cluster_size, __entry->record_size, + __entry->index_size, __entry->err) +); + +TRACE_EVENT(ntfs3_init_from_boot, + TP_PROTO(struct super_block *sb, u32 media_sector_size, + u32 boot_sector_size, bool used_alt_boot, int err), + TP_ARGS(sb, media_sector_size, boot_sector_size, used_alt_boot, err), + TP_STRUCT__entry( + __field(dev_t, dev) + __field(u32, media_sector_size) + __field(u32, boot_sector_size) + __field(int, err) + __field(bool, used_alt_boot) + ), + TP_fast_assign( + __entry->dev = sb->s_bdev->bd_dev; + __entry->media_sector_size = media_sector_size; + __entry->boot_sector_size = boot_sector_size; + __entry->err = err; + __entry->used_alt_boot = used_alt_boot; + ), + TP_printk("dev=(%d,%d) media_sector=%u boot_sector=%u alt_boot=%d err=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->media_sector_size, __entry->boot_sector_size, + __entry->used_alt_boot, __entry->err) +); + +TRACE_EVENT(ntfs3_log_replay, + TP_PROTO(struct inode *inode, bool initialized, int err), + TP_ARGS(inode, initialized, err), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(loff_t, size) + __field(dev_t, dev) + __field(int, err) + __field(bool, initialized) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->size = i_size_read(inode); + __entry->dev = inode->i_sb->s_dev; + __entry->err = err; + __entry->initialized = initialized; + ), + TP_printk("dev=(%d,%d) ino=%lu size=%lld initialized=%d err=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, + __entry->size, __entry->initialized, __entry->err) +); + +TRACE_EVENT(ntfs3_lookup, + TP_PROTO(struct inode *dir, struct dentry *dentry), + TP_ARGS(dir, dentry), + TP_STRUCT__entry( + __field(unsigned long, parent_ino) + __field(dev_t, dev) + __string(name, dentry->d_name.name) + ), + TP_fast_assign( + __entry->parent_ino = dir->i_ino; + __entry->dev = dir->i_sb->s_dev; + __assign_str(name); + ), + TP_printk("dev=(%d,%d) parent=%lu name=%s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->parent_ino, __get_str(name)) +); + +TRACE_EVENT(ntfs3_rename, + TP_PROTO(struct inode *dir, struct dentry *dentry, + struct inode *new_dir, struct dentry *new_dentry), + TP_ARGS(dir, dentry, new_dir, new_dentry), + TP_STRUCT__entry( + __field(unsigned long, dir_ino) + __field(unsigned long, new_dir_ino) + __field(unsigned long, ino) + __field(dev_t, dev) + __string(old_name, dentry->d_name.name) + __string(new_name, new_dentry->d_name.name) + ), + TP_fast_assign( + __entry->dir_ino = dir->i_ino; + __entry->new_dir_ino = new_dir->i_ino; + __entry->ino = d_inode(dentry)->i_ino; + __entry->dev = dir->i_sb->s_dev; + __assign_str(old_name); + __assign_str(new_name); + ), + TP_printk("dev=(%d,%d) dir=%lu new_dir=%lu ino=%lu old=%s new=%s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->dir_ino, __entry->new_dir_ino, __entry->ino, + __get_str(old_name), __get_str(new_name)) +); + +TRACE_EVENT(ntfs3_create_inode, + TP_PROTO(struct inode *dir, struct dentry *dentry), + TP_ARGS(dir, dentry), + TP_STRUCT__entry( + __field(unsigned long, parent_ino) + __field(dev_t, dev) + __string(name, dentry->d_name.name) + ), + TP_fast_assign( + __entry->parent_ino = dir->i_ino; + __entry->dev = dir->i_sb->s_dev; + __assign_str(name); + ), + TP_printk("dev=(%d,%d) parent=%lu name=%s", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->parent_ino, __get_str(name)) +); + +TRACE_EVENT(ntfs3_dir_search_u, + TP_PROTO(struct inode *dir, unsigned int name_len), + TP_ARGS(dir, name_len), + TP_STRUCT__entry( + __field(unsigned long, dir_ino) + __field(dev_t, dev) + __field(unsigned int, name_len) + ), + TP_fast_assign( + __entry->dir_ino = dir->i_ino; + __entry->dev = dir->i_sb->s_dev; + __entry->name_len = name_len; + ), + TP_printk("dev=(%d,%d) dir=%lu name_len=%u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->dir_ino, __entry->name_len) +); + +TRACE_EVENT(ntfs3_indx_find, + TP_PROTO(struct inode *inode, u8 type, size_t key_len), + TP_ARGS(inode, type, key_len), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(size_t, key_len) + __field(dev_t, dev) + __field(u8, type) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->key_len = key_len; + __entry->dev = inode->i_sb->s_dev; + __entry->type = type; + ), + TP_printk("dev=(%d,%d) ino=%lu type=%u key_len=%zu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->type, __entry->key_len) +); + +TRACE_EVENT(ntfs3_indx_insert_entry, + TP_PROTO(struct inode *inode, u8 type, u16 key_len, bool undo), + TP_ARGS(inode, type, key_len, undo), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(dev_t, dev) + __field(u16, key_len) + __field(u8, type) + __field(bool, undo) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->key_len = key_len; + __entry->type = type; + __entry->undo = undo; + ), + TP_printk("dev=(%d,%d) ino=%lu type=%u key_len=%u undo=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->type, __entry->key_len, + __entry->undo) +); + +TRACE_EVENT(ntfs3_indx_delete_entry, + TP_PROTO(struct inode *inode, u8 type, u32 key_len), + TP_ARGS(inode, type, key_len), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(u32, key_len) + __field(dev_t, dev) + __field(u8, type) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->key_len = key_len; + __entry->dev = inode->i_sb->s_dev; + __entry->type = type; + ), + TP_printk("dev=(%d,%d) ino=%lu type=%u key_len=%u", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->type, __entry->key_len) +); + +TRACE_EVENT(ntfs3_attr_allocate_clusters, + TP_PROTO(struct super_block *sb, u64 vcn, u64 lcn, u64 len, u32 opt), + TP_ARGS(sb, vcn, lcn, len, opt), + TP_STRUCT__entry( + __field(u64, vcn) + __field(u64, lcn) + __field(u64, len) + __field(dev_t, dev) + __field(u32, opt) + ), + TP_fast_assign( + __entry->vcn = vcn; + __entry->lcn = lcn; + __entry->len = len; + __entry->dev = sb->s_dev; + __entry->opt = opt; + ), + TP_printk("dev=(%d,%d) vcn=%llu lcn=%llu len=%llu opt=0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->vcn, __entry->lcn, __entry->len, __entry->opt) +); + +TRACE_EVENT(ntfs3_attr_set_size_ex, + TP_PROTO(struct inode *inode, u32 type, u64 old_size, u64 new_size, + bool keep_prealloc, bool no_da), + TP_ARGS(inode, type, old_size, new_size, keep_prealloc, no_da), + TP_STRUCT__entry( + __field(u64, old_size) + __field(u64, new_size) + __field(unsigned long, ino) + __field(dev_t, dev) + __field(u32, type) + __field(bool, keep_prealloc) + __field(bool, no_da) + ), + TP_fast_assign( + __entry->old_size = old_size; + __entry->new_size = new_size; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->type = type; + __entry->keep_prealloc = keep_prealloc; + __entry->no_da = no_da; + ), + TP_printk("dev=(%d,%d) ino=%lu type=0x%x old_size=%llu new_size=%llu keep_prealloc=%d no_da=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, + __entry->type, __entry->old_size, __entry->new_size, + __entry->keep_prealloc, __entry->no_da) +); + +TRACE_EVENT(ntfs3_attr_data_get_block, + TP_PROTO(struct inode *inode, u64 vcn, u64 clen, bool *new, + bool zero, bool no_da), + TP_ARGS(inode, vcn, clen, new, zero, no_da), + TP_STRUCT__entry( + __field(u64, vcn) + __field(u64, clen) + __field(unsigned long, ino) + __field(dev_t, dev) + __field(bool, create) + __field(bool, zero) + __field(bool, no_da) + ), + TP_fast_assign( + __entry->vcn = vcn; + __entry->clen = clen; + __entry->ino = inode->i_ino; + __entry->dev = inode->i_sb->s_dev; + __entry->create = !!new; + __entry->zero = zero; + __entry->no_da = no_da; + ), + TP_printk("dev=(%d,%d) ino=%lu vcn=%llu clen=%llu create=%d zero=%d no_da=%d", + MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, + __entry->vcn, __entry->clen, __entry->create, + __entry->zero, __entry->no_da) +); + +TRACE_EVENT(ntfs3_iomap_begin, + TP_PROTO(struct inode *inode, loff_t offset, loff_t length, + unsigned int flags), + TP_ARGS(inode, offset, length, flags), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(loff_t, offset) + __field(loff_t, length) + __field(dev_t, dev) + __field(unsigned int, flags) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->offset = offset; + __entry->length = length; + __entry->dev = inode->i_sb->s_dev; + __entry->flags = flags; + ), + TP_printk("dev=(%d,%d) ino=%lu offset=%lld length=%lld flags=0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->offset, __entry->length, + __entry->flags) +); + +TRACE_EVENT(ntfs3_iomap_end, + TP_PROTO(struct inode *inode, loff_t pos, loff_t length, + ssize_t written, unsigned int flags), + TP_ARGS(inode, pos, length, written, flags), + TP_STRUCT__entry( + __field(unsigned long, ino) + __field(loff_t, pos) + __field(loff_t, length) + __field(ssize_t, written) + __field(dev_t, dev) + __field(unsigned int, flags) + ), + TP_fast_assign( + __entry->ino = inode->i_ino; + __entry->pos = pos; + __entry->length = length; + __entry->written = written; + __entry->dev = inode->i_sb->s_dev; + __entry->flags = flags; + ), + TP_printk("dev=(%d,%d) ino=%lu pos=%lld length=%lld written=%zd flags=0x%x", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->pos, __entry->length, + __entry->written, __entry->flags) +); + +DECLARE_EVENT_CLASS(ntfs3_file_class, + TP_PROTO(struct kiocb *iocb, struct iov_iter *iter), + TP_ARGS(iocb, iter), + TP_STRUCT__entry( + __field(loff_t, size) + __field(loff_t, offset) + __field(size_t, count) + __field(unsigned long, ino) + __field(dev_t, dev) + ), + TP_fast_assign( + __entry->size = i_size_read(file_inode(iocb->ki_filp)); + __entry->offset = iocb->ki_pos; + __entry->count = iov_iter_count(iter); + __entry->ino = file_inode(iocb->ki_filp)->i_ino; + __entry->dev = file_inode(iocb->ki_filp)->i_sb->s_dev; + ), + TP_printk("dev=(%d,%d) ino=%lu size=%lld pos=%lld bytecount=%zu", + MAJOR(__entry->dev), MINOR(__entry->dev), + __entry->ino, __entry->size, __entry->offset, + __entry->count) +); + +DEFINE_EVENT(ntfs3_file_class, ntfs3_file_read_iter, + TP_PROTO(struct kiocb *iocb, struct iov_iter *iter), + TP_ARGS(iocb, iter) +); + +DEFINE_EVENT(ntfs3_file_class, ntfs3_file_write_iter, + TP_PROTO(struct kiocb *iocb, struct iov_iter *iter), + TP_ARGS(iocb, iter) +); + +#endif /* _TRACE_NTFS3_H */ + +#include <trace/define_trace.h> diff --git a/include/trace/events/pagemap.h b/include/trace/events/pagemap.h index 36c3a90f0acc..5d47b774633a 100644 --- a/include/trace/events/pagemap.h +++ b/include/trace/events/pagemap.h @@ -22,7 +22,7 @@ (folio_test_swapcache(folio) ? PAGEMAP_SWAPCACHE : 0) | \ (folio_test_swapbacked(folio) ? PAGEMAP_SWAPBACKED : 0) | \ (folio_test_mappedtodisk(folio) ? PAGEMAP_MAPPEDDISK : 0) | \ - (folio_test_private(folio) ? PAGEMAP_BUFFERS : 0) \ + (folio_has_attached_private(folio) ? PAGEMAP_BUFFERS : 0) \ ) TRACE_EVENT(mm_lru_insertion, diff --git a/include/trace/events/power.h b/include/trace/events/power.h index 370f8df2fdb4..4d17eb307b6a 100644 --- a/include/trace/events/power.h +++ b/include/trace/events/power.h @@ -497,6 +497,7 @@ DEFINE_EVENT(dev_pm_qos_request, dev_pm_qos_remove_request, TP_ARGS(name, type, new_value) ); +#ifdef CONFIG_CPU_IDLE_GOV_HALTPOLL TRACE_EVENT(guest_halt_poll_ns, TP_PROTO(bool grow, unsigned int new, unsigned int old), @@ -525,6 +526,8 @@ TRACE_EVENT(guest_halt_poll_ns, trace_guest_halt_poll_ns(true, new, old) #define trace_guest_halt_poll_ns_shrink(new, old) \ trace_guest_halt_poll_ns(false, new, old) +#endif /* CONFIG_CPU_IDLE_GOV_HALTPOLL */ + #endif /* _TRACE_POWER_H */ /* This part must be outside protection */ diff --git a/include/trace/events/rxrpc.h b/include/trace/events/rxrpc.h index 704a10de6670..56dc9b614071 100644 --- a/include/trace/events/rxrpc.h +++ b/include/trace/events/rxrpc.h @@ -20,16 +20,16 @@ /* AFS errors */ \ EM(afs_abort_general_error, "afs-error") \ EM(afs_abort_interrupted, "afs-intr") \ - EM(afs_abort_oom, "afs-oom") \ EM(afs_abort_op_not_supported, "afs-op-notsupp") \ EM(afs_abort_probeuuid_negative, "afs-probeuuid-neg") \ EM(afs_abort_send_data_error, "afs-send-data") \ + EM(afs_abort_send_error, "afs-send-error") \ EM(afs_abort_unmarshal_error, "afs-unmarshal") \ EM(afs_abort_unsupported_sec_class, "afs-unsup-sec-class") \ /* rxperf errors */ \ EM(rxperf_abort_general_error, "rxperf-error") \ - EM(rxperf_abort_oom, "rxperf-oom") \ EM(rxperf_abort_op_not_supported, "rxperf-op-notsupp") \ + EM(rxperf_abort_send_error, "rxperf-send-error") \ EM(rxperf_abort_unmarshal_error, "rxperf-unmarshal") \ /* RxKAD security errors */ \ EM(rxkad_abort_1_short_check, "rxkad1-short-check") \ diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h index 703b7bb68e44..b421c253df00 100644 --- a/include/trace/events/scmi.h +++ b/include/trace/events/scmi.h @@ -7,8 +7,6 @@ #include <linux/tracepoint.h> -#define TRACE_SCMI_MAX_TAG_LEN 6 - TRACE_EVENT(scmi_fc_call, TP_PROTO(u8 protocol_id, u8 msg_id, u32 res_id, u32 val1, u32 val2), TP_ARGS(protocol_id, msg_id, res_id, val1, val2), @@ -156,7 +154,7 @@ TRACE_EVENT(scmi_msg_dump, __field(u8, channel_id) __field(u8, protocol_id) __field(u8, msg_id) - __array(char, tag, TRACE_SCMI_MAX_TAG_LEN) + __string(tag, tag) __field(u16, seq) __field(int, status) __field(size_t, len) @@ -168,7 +166,7 @@ TRACE_EVENT(scmi_msg_dump, __entry->channel_id = channel_id; __entry->protocol_id = protocol_id; __entry->msg_id = msg_id; - strscpy(__entry->tag, tag, TRACE_SCMI_MAX_TAG_LEN); + __assign_str(tag); __entry->seq = seq; __entry->status = status; __entry->len = len; @@ -177,7 +175,7 @@ TRACE_EVENT(scmi_msg_dump, TP_printk("id=%d ch=%02X pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s", __entry->id, __entry->channel_id, __entry->protocol_id, - __entry->tag, __entry->msg_id, __entry->seq, __entry->status, + __get_str(tag), __entry->msg_id, __entry->seq, __entry->status, __print_hex_str(__get_dynamic_array(cmd), __entry->len)) ); #endif /* _TRACE_SCMI_H */ diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index c36c72ab7f2b..e8328df587c3 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -303,8 +303,8 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, if (cmd->sense_buffer && SCSI_SENSE_VALID(cmd) && scsi_command_normalize_sense(cmd, &sshdr)) { __entry->sense_key = sshdr.sense_key; - __entry->asc = sshdr.asc; - __entry->ascq = sshdr.ascq; + __entry->asc = scsi_sense_asc(&sshdr); + __entry->ascq = scsi_sense_ascq(&sshdr); } else { __entry->sense_key = 0; __entry->asc = 0; diff --git a/include/trace/events/tegra_apb_dma.h b/include/trace/events/tegra_apb_dma.h index 6d9f5075baa3..c38117c127ef 100644 --- a/include/trace/events/tegra_apb_dma.h +++ b/include/trace/events/tegra_apb_dma.h @@ -11,7 +11,7 @@ TRACE_EVENT(tegra_dma_tx_status, TP_PROTO(struct dma_chan *dc, dma_cookie_t cookie, struct dma_tx_state *state), TP_ARGS(dc, cookie, state), TP_STRUCT__entry( - __string(chan, dev_name(&dc->dev->device)) + __string(chan, dma_chan_name(dc)) __field(dma_cookie_t, cookie) __field(__u32, residue) ), @@ -28,7 +28,7 @@ TRACE_EVENT(tegra_dma_complete_cb, TP_PROTO(struct dma_chan *dc, int count, void *ptr), TP_ARGS(dc, count, ptr), TP_STRUCT__entry( - __string(chan, dev_name(&dc->dev->device)) + __string(chan, dma_chan_name(dc)) __field(int, count) __field(void *, ptr) ), @@ -45,7 +45,7 @@ TRACE_EVENT(tegra_dma_isr, TP_PROTO(struct dma_chan *dc, int irq), TP_ARGS(dc, irq), TP_STRUCT__entry( - __string(chan, dev_name(&dc->dev->device)) + __string(chan, dma_chan_name(dc)) __field(int, irq) ), TP_fast_assign( diff --git a/include/trace/events/timer.h b/include/trace/events/timer.h index ca82fd62dc30..3aa0608c6361 100644 --- a/include/trace/events/timer.h +++ b/include/trace/events/timer.h @@ -302,7 +302,7 @@ DECLARE_EVENT_CLASS(hrtimer_class, * hrtimer_start_expired - Invoked when a expired timer was started * @hrtimer: pointer to struct hrtimer * - * Preceeded by a hrtimer_start tracepoint. + * Preceded by a hrtimer_start tracepoint. */ DEFINE_EVENT(hrtimer_class, hrtimer_start_expired, diff --git a/include/trace/events/vmscan.h b/include/trace/events/vmscan.h index b4bf7b8def1f..8a872990b4be 100644 --- a/include/trace/events/vmscan.h +++ b/include/trace/events/vmscan.h @@ -214,13 +214,6 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_reclaim_be TP_ARGS(gfp_flags, order, memcg) ); - -DEFINE_EVENT(mm_vmscan_direct_reclaim_begin_template, mm_vmscan_memcg_softlimit_reclaim_begin, - - TP_PROTO(gfp_t gfp_flags, int order, struct mem_cgroup *memcg), - - TP_ARGS(gfp_flags, order, memcg) -); #endif /* CONFIG_MEMCG */ DECLARE_EVENT_CLASS(mm_vmscan_direct_reclaim_end_template, @@ -260,13 +253,6 @@ DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_reclaim_end, TP_ARGS(nr_reclaimed, memcg) ); - -DEFINE_EVENT(mm_vmscan_direct_reclaim_end_template, mm_vmscan_memcg_softlimit_reclaim_end, - - TP_PROTO(unsigned long nr_reclaimed, struct mem_cgroup *memcg), - - TP_ARGS(nr_reclaimed, memcg) -); #endif /* CONFIG_MEMCG */ TRACE_EVENT(mm_shrink_slab_start, diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index b0de2bc9ed52..5b820ff8f81a 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h @@ -9,6 +9,7 @@ #include <linux/workqueue.h> struct pool_workqueue; +struct worker_pool; /** * workqueue_queue_work - called when a work gets queued @@ -126,7 +127,152 @@ TRACE_EVENT(workqueue_execute_end, TP_printk("work struct %p: function %ps", __entry->work, __entry->function) ); +/** + * workqueue_cpu_intensive - called when a work item exceeds cpu_intensive threshold + * @pwq: pointer to struct pool_workqueue + * @work: pointer to struct work_struct + * @function: pointer to worker function + * @duration_us: CPU time consumed in microseconds + * + * This event occurs when a concurrency-managed work item runs for longer + * than wq_cpu_intensive_thresh_us without sleeping and is excluded from + * concurrency management to prevent stalling other work items. + */ +TRACE_EVENT(workqueue_cpu_intensive, + + TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, + work_func_t function, u64 duration_us), + + TP_ARGS(pwq, work, function, duration_us), + + TP_STRUCT__entry( + __field( void *, work ) + __field( void *, function ) + __string( workqueue, pwq->wq->name ) + __field( int, cpu ) + __field( u64, duration_us ) + ), + + TP_fast_assign( + __entry->work = work; + __entry->function = function; + __assign_str(workqueue); + __entry->cpu = pwq->pool->cpu; + __entry->duration_us = duration_us; + ), + + TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d duration_us=%llu", + __entry->work, __entry->function, __get_str(workqueue), + __entry->cpu, __entry->duration_us) +); + +/** + * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer + * @pwq: pointer to struct pool_workqueue + * + * This event occurs when a worker pool fails to create a new worker and + * requests the workqueue's rescuer thread to process pending works. + */ +TRACE_EVENT(workqueue_mayday, + + TP_PROTO(struct pool_workqueue *pwq), + + TP_ARGS(pwq), + + TP_STRUCT__entry( + __string( workqueue, pwq->wq->name ) + __field( int, pool_id ) + __field( int, cpu ) + __field( int, nr_active ) + ), + + TP_fast_assign( + __assign_str(workqueue); + __entry->pool_id = pwq->pool->id; + __entry->cpu = pwq->pool->cpu; + __entry->nr_active = pwq->nr_active; + ), + + TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d", + __get_str(workqueue), __entry->pool_id, __entry->cpu, + __entry->nr_active) +); + +/** + * workqueue_rescued - called when a work item is assigned to a rescuer + * @pwq: pointer to struct pool_workqueue + * @work: pointer to struct work_struct + * @function: pointer to worker function + * + * This event occurs when a work item is claimed by a rescuer thread + * to guarantee forward progress. + */ +TRACE_EVENT(workqueue_rescued, + + TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, + work_func_t function), + + TP_ARGS(pwq, work, function), + + TP_STRUCT__entry( + __field( void *, work ) + __field( void *, function ) + __string( workqueue, pwq->wq->name ) + __field( int, cpu ) + ), + + TP_fast_assign( + __entry->work = work; + __entry->function = function; + __assign_str(workqueue); + __entry->cpu = pwq->pool->cpu; + ), + + TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d", + __entry->work, __entry->function, __get_str(workqueue), + __entry->cpu) +); + +/** + * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion + * @pool: pointer to struct worker_pool + * @restarts: number of restarts executed + * @timeout: whether execution hit the time limit (BH_WORKER_JIFFIES) + * @highpri: whether this is a high-priority BH pool + * + * This event occurs when a bottom-half (BH) worker pool running in softirq + * context exhausts its execution time slice or restart limit and must yield + * execution. + */ +TRACE_EVENT(workqueue_bh_budget_yield, + + TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri), + + TP_ARGS(pool, restarts, timeout, highpri), + + TP_STRUCT__entry( + __field( int, pool_id ) + __field( int, cpu ) + __field( int, restarts ) + __field( bool, timeout ) + __field( bool, highpri ) + ), + + TP_fast_assign( + __entry->pool_id = pool->id; + __entry->cpu = pool->cpu; + __entry->restarts = restarts; + __entry->timeout = timeout; + __entry->highpri = highpri; + ), + + TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d", + __entry->pool_id, __entry->cpu, __entry->restarts, + __entry->timeout, __entry->highpri) +); + #endif /* _TRACE_WORKQUEUE_H */ /* This part must be outside protection */ #include <trace/define_trace.h> + diff --git a/include/trace/misc/nfs.h b/include/trace/misc/nfs.h index a394b4d38e18..3146813fc4fe 100644 --- a/include/trace/misc/nfs.h +++ b/include/trace/misc/nfs.h @@ -8,6 +8,7 @@ */ #include <linux/nfs.h> +#include <linux/nfs3.h> #include <linux/nfs4.h> #include <uapi/linux/nfs.h> @@ -358,18 +359,6 @@ TRACE_DEFINE_ENUM(IOMODE_ANY); { IOMODE_RW, "RW" }, \ { IOMODE_ANY, "ANY" }) -#define show_rca_mask(x) \ - __print_flags(x, "|", \ - { BIT(RCA4_TYPE_MASK_RDATA_DLG), "RDATA_DLG" }, \ - { BIT(RCA4_TYPE_MASK_WDATA_DLG), "WDATA_DLG" }, \ - { BIT(RCA4_TYPE_MASK_DIR_DLG), "DIR_DLG" }, \ - { BIT(RCA4_TYPE_MASK_FILE_LAYOUT), "FILE_LAYOUT" }, \ - { BIT(RCA4_TYPE_MASK_BLK_LAYOUT), "BLK_LAYOUT" }, \ - { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MIN), "OBJ_LAYOUT_MIN" }, \ - { BIT(RCA4_TYPE_MASK_OBJ_LAYOUT_MAX), "OBJ_LAYOUT_MAX" }, \ - { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MIN), "OTHER_LAYOUT_MIN" }, \ - { BIT(RCA4_TYPE_MASK_OTHER_LAYOUT_MAX), "OTHER_LAYOUT_MAX" }) - #define show_nfs4_seq4_status(x) \ __print_flags(x, "|", \ { SEQ4_STATUS_CB_PATH_DOWN, "CB_PATH_DOWN" }, \ |
