| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 
|---|
| 2 | /* | 
|---|
| 3 | * Events for filesystem locks | 
|---|
| 4 | * | 
|---|
| 5 | * Copyright 2013 Jeff Layton <jlayton@poochiereds.net> | 
|---|
| 6 | */ | 
|---|
| 7 | #undef TRACE_SYSTEM | 
|---|
| 8 | #define TRACE_SYSTEM filelock | 
|---|
| 9 |  | 
|---|
| 10 | #if !defined(_TRACE_FILELOCK_H) || defined(TRACE_HEADER_MULTI_READ) | 
|---|
| 11 | #define _TRACE_FILELOCK_H | 
|---|
| 12 |  | 
|---|
| 13 | #include <linux/tracepoint.h> | 
|---|
| 14 | #include <linux/fs.h> | 
|---|
| 15 | #include <linux/device.h> | 
|---|
| 16 | #include <linux/kdev_t.h> | 
|---|
| 17 |  | 
|---|
| 18 | #define show_fl_flags(val)						\ | 
|---|
| 19 | __print_flags(val, "|", 					\ | 
|---|
| 20 | { FL_POSIX,		"FL_POSIX" },			\ | 
|---|
| 21 | { FL_FLOCK,		"FL_FLOCK" },			\ | 
|---|
| 22 | { FL_DELEG,		"FL_DELEG" },			\ | 
|---|
| 23 | { FL_ACCESS,		"FL_ACCESS" },			\ | 
|---|
| 24 | { FL_EXISTS,		"FL_EXISTS" },			\ | 
|---|
| 25 | { FL_LEASE,		"FL_LEASE" },			\ | 
|---|
| 26 | { FL_CLOSE,		"FL_CLOSE" },			\ | 
|---|
| 27 | { FL_SLEEP,		"FL_SLEEP" },			\ | 
|---|
| 28 | { FL_DOWNGRADE_PENDING,	"FL_DOWNGRADE_PENDING" },	\ | 
|---|
| 29 | { FL_UNLOCK_PENDING,	"FL_UNLOCK_PENDING" },		\ | 
|---|
| 30 | { FL_OFDLCK,		"FL_OFDLCK" },			\ | 
|---|
| 31 | { FL_RECLAIM,		"FL_RECLAIM"}) | 
|---|
| 32 |  | 
|---|
| 33 | #define show_fl_type(val)				\ | 
|---|
| 34 | __print_symbolic(val,				\ | 
|---|
| 35 | { F_RDLCK, "F_RDLCK" },		\ | 
|---|
| 36 | { F_WRLCK, "F_WRLCK" },		\ | 
|---|
| 37 | { F_UNLCK, "F_UNLCK" }) | 
|---|
| 38 |  | 
|---|
| 39 | TRACE_EVENT(locks_get_lock_context, | 
|---|
| 40 | TP_PROTO(struct inode *inode, int type, struct file_lock_context *ctx), | 
|---|
| 41 |  | 
|---|
| 42 | TP_ARGS(inode, type, ctx), | 
|---|
| 43 |  | 
|---|
| 44 | TP_STRUCT__entry( | 
|---|
| 45 | __field(unsigned long, i_ino) | 
|---|
| 46 | __field(dev_t, s_dev) | 
|---|
| 47 | __field(unsigned char, type) | 
|---|
| 48 | __field(struct file_lock_context *, ctx) | 
|---|
| 49 | ), | 
|---|
| 50 |  | 
|---|
| 51 | TP_fast_assign( | 
|---|
| 52 | __entry->s_dev = inode->i_sb->s_dev; | 
|---|
| 53 | __entry->i_ino = inode->i_ino; | 
|---|
| 54 | __entry->type = type; | 
|---|
| 55 | __entry->ctx = ctx; | 
|---|
| 56 | ), | 
|---|
| 57 |  | 
|---|
| 58 | TP_printk( "dev=0x%x:0x%x ino=0x%lx type=%s ctx=%p", | 
|---|
| 59 | MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | 
|---|
| 60 | __entry->i_ino, show_fl_type(__entry->type), __entry->ctx) | 
|---|
| 61 | ); | 
|---|
| 62 |  | 
|---|
| 63 | DECLARE_EVENT_CLASS(filelock_lock, | 
|---|
| 64 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | 
|---|
| 65 |  | 
|---|
| 66 | TP_ARGS(inode, fl, ret), | 
|---|
| 67 |  | 
|---|
| 68 | TP_STRUCT__entry( | 
|---|
| 69 | __field(struct file_lock *, fl) | 
|---|
| 70 | __field(unsigned long, i_ino) | 
|---|
| 71 | __field(dev_t, s_dev) | 
|---|
| 72 | __field(struct file_lock_core *, blocker) | 
|---|
| 73 | __field(fl_owner_t, owner) | 
|---|
| 74 | __field(unsigned int, pid) | 
|---|
| 75 | __field(unsigned int, flags) | 
|---|
| 76 | __field(unsigned char, type) | 
|---|
| 77 | __field(loff_t, fl_start) | 
|---|
| 78 | __field(loff_t, fl_end) | 
|---|
| 79 | __field(int, ret) | 
|---|
| 80 | ), | 
|---|
| 81 |  | 
|---|
| 82 | TP_fast_assign( | 
|---|
| 83 | __entry->fl = fl ? fl : NULL; | 
|---|
| 84 | __entry->s_dev = inode->i_sb->s_dev; | 
|---|
| 85 | __entry->i_ino = inode->i_ino; | 
|---|
| 86 | __entry->blocker = fl ? fl->c.flc_blocker : NULL; | 
|---|
| 87 | __entry->owner = fl ? fl->c.flc_owner : NULL; | 
|---|
| 88 | __entry->pid = fl ? fl->c.flc_pid : 0; | 
|---|
| 89 | __entry->flags = fl ? fl->c.flc_flags : 0; | 
|---|
| 90 | __entry->type = fl ? fl->c.flc_type : 0; | 
|---|
| 91 | __entry->fl_start = fl ? fl->fl_start : 0; | 
|---|
| 92 | __entry->fl_end = fl ? fl->fl_end : 0; | 
|---|
| 93 | __entry->ret = ret; | 
|---|
| 94 | ), | 
|---|
| 95 |  | 
|---|
| 96 | TP_printk( "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_pid=%u fl_flags=%s fl_type=%s fl_start=%lld fl_end=%lld ret=%d", | 
|---|
| 97 | __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | 
|---|
| 98 | __entry->i_ino, __entry->blocker, __entry->owner, | 
|---|
| 99 | __entry->pid, show_fl_flags(__entry->flags), | 
|---|
| 100 | show_fl_type(__entry->type), | 
|---|
| 101 | __entry->fl_start, __entry->fl_end, __entry->ret) | 
|---|
| 102 | ); | 
|---|
| 103 |  | 
|---|
| 104 | DEFINE_EVENT(filelock_lock, posix_lock_inode, | 
|---|
| 105 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | 
|---|
| 106 | TP_ARGS(inode, fl, ret)); | 
|---|
| 107 |  | 
|---|
| 108 | DEFINE_EVENT(filelock_lock, fcntl_setlk, | 
|---|
| 109 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | 
|---|
| 110 | TP_ARGS(inode, fl, ret)); | 
|---|
| 111 |  | 
|---|
| 112 | DEFINE_EVENT(filelock_lock, locks_remove_posix, | 
|---|
| 113 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | 
|---|
| 114 | TP_ARGS(inode, fl, ret)); | 
|---|
| 115 |  | 
|---|
| 116 | DEFINE_EVENT(filelock_lock, flock_lock_inode, | 
|---|
| 117 | TP_PROTO(struct inode *inode, struct file_lock *fl, int ret), | 
|---|
| 118 | TP_ARGS(inode, fl, ret)); | 
|---|
| 119 |  | 
|---|
| 120 | DECLARE_EVENT_CLASS(filelock_lease, | 
|---|
| 121 | TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 122 |  | 
|---|
| 123 | TP_ARGS(inode, fl), | 
|---|
| 124 |  | 
|---|
| 125 | TP_STRUCT__entry( | 
|---|
| 126 | __field(struct file_lease *, fl) | 
|---|
| 127 | __field(unsigned long, i_ino) | 
|---|
| 128 | __field(dev_t, s_dev) | 
|---|
| 129 | __field(struct file_lock_core *, blocker) | 
|---|
| 130 | __field(fl_owner_t, owner) | 
|---|
| 131 | __field(unsigned int, flags) | 
|---|
| 132 | __field(unsigned char, type) | 
|---|
| 133 | __field(unsigned long, break_time) | 
|---|
| 134 | __field(unsigned long, downgrade_time) | 
|---|
| 135 | ), | 
|---|
| 136 |  | 
|---|
| 137 | TP_fast_assign( | 
|---|
| 138 | __entry->fl = fl ? fl : NULL; | 
|---|
| 139 | __entry->s_dev = inode->i_sb->s_dev; | 
|---|
| 140 | __entry->i_ino = inode->i_ino; | 
|---|
| 141 | __entry->blocker = fl ? fl->c.flc_blocker : NULL; | 
|---|
| 142 | __entry->owner = fl ? fl->c.flc_owner : NULL; | 
|---|
| 143 | __entry->flags = fl ? fl->c.flc_flags : 0; | 
|---|
| 144 | __entry->type = fl ? fl->c.flc_type : 0; | 
|---|
| 145 | __entry->break_time = fl ? fl->fl_break_time : 0; | 
|---|
| 146 | __entry->downgrade_time = fl ? fl->fl_downgrade_time : 0; | 
|---|
| 147 | ), | 
|---|
| 148 |  | 
|---|
| 149 | TP_printk( "fl=%p dev=0x%x:0x%x ino=0x%lx fl_blocker=%p fl_owner=%p fl_flags=%s fl_type=%s fl_break_time=%lu fl_downgrade_time=%lu", | 
|---|
| 150 | __entry->fl, MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | 
|---|
| 151 | __entry->i_ino, __entry->blocker, __entry->owner, | 
|---|
| 152 | show_fl_flags(__entry->flags), | 
|---|
| 153 | show_fl_type(__entry->type), | 
|---|
| 154 | __entry->break_time, __entry->downgrade_time) | 
|---|
| 155 | ); | 
|---|
| 156 |  | 
|---|
| 157 | DEFINE_EVENT(filelock_lease, break_lease_noblock, TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 158 | TP_ARGS(inode, fl)); | 
|---|
| 159 |  | 
|---|
| 160 | DEFINE_EVENT(filelock_lease, break_lease_block, TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 161 | TP_ARGS(inode, fl)); | 
|---|
| 162 |  | 
|---|
| 163 | DEFINE_EVENT(filelock_lease, break_lease_unblock, TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 164 | TP_ARGS(inode, fl)); | 
|---|
| 165 |  | 
|---|
| 166 | DEFINE_EVENT(filelock_lease, generic_delete_lease, TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 167 | TP_ARGS(inode, fl)); | 
|---|
| 168 |  | 
|---|
| 169 | DEFINE_EVENT(filelock_lease, time_out_leases, TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 170 | TP_ARGS(inode, fl)); | 
|---|
| 171 |  | 
|---|
| 172 | TRACE_EVENT(generic_add_lease, | 
|---|
| 173 | TP_PROTO(struct inode *inode, struct file_lease *fl), | 
|---|
| 174 |  | 
|---|
| 175 | TP_ARGS(inode, fl), | 
|---|
| 176 |  | 
|---|
| 177 | TP_STRUCT__entry( | 
|---|
| 178 | __field(unsigned long, i_ino) | 
|---|
| 179 | __field(int, wcount) | 
|---|
| 180 | __field(int, rcount) | 
|---|
| 181 | __field(int, icount) | 
|---|
| 182 | __field(dev_t, s_dev) | 
|---|
| 183 | __field(fl_owner_t, owner) | 
|---|
| 184 | __field(unsigned int, flags) | 
|---|
| 185 | __field(unsigned char, type) | 
|---|
| 186 | ), | 
|---|
| 187 |  | 
|---|
| 188 | TP_fast_assign( | 
|---|
| 189 | __entry->s_dev = inode->i_sb->s_dev; | 
|---|
| 190 | __entry->i_ino = inode->i_ino; | 
|---|
| 191 | __entry->wcount = atomic_read(&inode->i_writecount); | 
|---|
| 192 | __entry->rcount = atomic_read(&inode->i_readcount); | 
|---|
| 193 | __entry->icount = icount_read(inode); | 
|---|
| 194 | __entry->owner = fl->c.flc_owner; | 
|---|
| 195 | __entry->flags = fl->c.flc_flags; | 
|---|
| 196 | __entry->type = fl->c.flc_type; | 
|---|
| 197 | ), | 
|---|
| 198 |  | 
|---|
| 199 | TP_printk( "dev=0x%x:0x%x ino=0x%lx wcount=%d rcount=%d icount=%d fl_owner=%p fl_flags=%s fl_type=%s", | 
|---|
| 200 | MAJOR(__entry->s_dev), MINOR(__entry->s_dev), | 
|---|
| 201 | __entry->i_ino, __entry->wcount, __entry->rcount, | 
|---|
| 202 | __entry->icount, __entry->owner, | 
|---|
| 203 | show_fl_flags(__entry->flags), | 
|---|
| 204 | show_fl_type(__entry->type)) | 
|---|
| 205 | ); | 
|---|
| 206 |  | 
|---|
| 207 | TRACE_EVENT(leases_conflict, | 
|---|
| 208 | TP_PROTO(bool conflict, struct file_lease *lease, struct file_lease *breaker), | 
|---|
| 209 |  | 
|---|
| 210 | TP_ARGS(conflict, lease, breaker), | 
|---|
| 211 |  | 
|---|
| 212 | TP_STRUCT__entry( | 
|---|
| 213 | __field(void *, lease) | 
|---|
| 214 | __field(void *, breaker) | 
|---|
| 215 | __field(unsigned int, l_fl_flags) | 
|---|
| 216 | __field(unsigned int, b_fl_flags) | 
|---|
| 217 | __field(unsigned char, l_fl_type) | 
|---|
| 218 | __field(unsigned char, b_fl_type) | 
|---|
| 219 | __field(bool, conflict) | 
|---|
| 220 | ), | 
|---|
| 221 |  | 
|---|
| 222 | TP_fast_assign( | 
|---|
| 223 | __entry->lease = lease; | 
|---|
| 224 | __entry->l_fl_flags = lease->c.flc_flags; | 
|---|
| 225 | __entry->l_fl_type = lease->c.flc_type; | 
|---|
| 226 | __entry->breaker = breaker; | 
|---|
| 227 | __entry->b_fl_flags = breaker->c.flc_flags; | 
|---|
| 228 | __entry->b_fl_type = breaker->c.flc_type; | 
|---|
| 229 | __entry->conflict = conflict; | 
|---|
| 230 | ), | 
|---|
| 231 |  | 
|---|
| 232 | TP_printk( "conflict %d: lease=%p fl_flags=%s fl_type=%s; breaker=%p fl_flags=%s fl_type=%s", | 
|---|
| 233 | __entry->conflict, | 
|---|
| 234 | __entry->lease, | 
|---|
| 235 | show_fl_flags(__entry->l_fl_flags), | 
|---|
| 236 | show_fl_type(__entry->l_fl_type), | 
|---|
| 237 | __entry->breaker, | 
|---|
| 238 | show_fl_flags(__entry->b_fl_flags), | 
|---|
| 239 | show_fl_type(__entry->b_fl_type)) | 
|---|
| 240 | ); | 
|---|
| 241 |  | 
|---|
| 242 | #endif /* _TRACE_FILELOCK_H */ | 
|---|
| 243 |  | 
|---|
| 244 | /* This part must be outside protection */ | 
|---|
| 245 | #include <trace/define_trace.h> | 
|---|
| 246 |  | 
|---|