Skip to content

Commit 051d252

Browse files
committed
afs: Add some callback management tracepoints
Add a couple of tracepoints to track callback management: (1) afs_cb_miss - Logs when we were unable to apply a callback, either due to the inode being discarded or due to a competing thread applying a callback first. (2) afs_cb_break - Logs when we attempted to clear the noted callback promise, either due to the server explicitly breaking the callback, the callback promise lapsing or a local event obsoleting it. Signed-off-by: David Howells <[email protected]>
1 parent fa59f52 commit 051d252

File tree

5 files changed

+97
-17
lines changed

5 files changed

+97
-17
lines changed

fs/afs/callback.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ void afs_init_callback_state(struct afs_server *server)
212212
/*
213213
* actually break a callback
214214
*/
215-
void __afs_break_callback(struct afs_vnode *vnode)
215+
void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
216216
{
217217
_enter("");
218218

@@ -223,13 +223,17 @@ void __afs_break_callback(struct afs_vnode *vnode)
223223

224224
if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB)
225225
afs_lock_may_be_available(vnode);
226+
227+
trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true);
228+
} else {
229+
trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false);
226230
}
227231
}
228232

229-
void afs_break_callback(struct afs_vnode *vnode)
233+
void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
230234
{
231235
write_seqlock(&vnode->cb_lock);
232-
__afs_break_callback(vnode);
236+
__afs_break_callback(vnode, reason);
233237
write_sequnlock(&vnode->cb_lock);
234238
}
235239

@@ -277,6 +281,8 @@ static void afs_break_one_callback(struct afs_server *server,
277281

278282
write_lock(&volume->cb_v_break_lock);
279283
volume->cb_v_break++;
284+
trace_afs_cb_break(fid, volume->cb_v_break,
285+
afs_cb_break_for_volume_callback, false);
280286
write_unlock(&volume->cb_v_break_lock);
281287
} else {
282288
data.volume = NULL;
@@ -285,8 +291,10 @@ static void afs_break_one_callback(struct afs_server *server,
285291
afs_iget5_test, &data);
286292
if (inode) {
287293
vnode = AFS_FS_I(inode);
288-
afs_break_callback(vnode);
294+
afs_break_callback(vnode, afs_cb_break_for_callback);
289295
iput(inode);
296+
} else {
297+
trace_afs_cb_miss(fid, afs_cb_break_for_callback);
290298
}
291299
}
292300
}

fs/afs/dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1367,12 +1367,12 @@ static int afs_dir_remove_link(struct afs_vnode *dvnode, struct dentry *dentry,
13671367
drop_nlink(&vnode->vfs_inode);
13681368
if (vnode->vfs_inode.i_nlink == 0) {
13691369
set_bit(AFS_VNODE_DELETED, &vnode->flags);
1370-
__afs_break_callback(vnode);
1370+
__afs_break_callback(vnode, afs_cb_break_for_unlink);
13711371
}
13721372
write_sequnlock(&vnode->cb_lock);
13731373
ret = 0;
13741374
} else {
1375-
afs_break_callback(vnode);
1375+
afs_break_callback(vnode, afs_cb_break_for_unlink);
13761376

13771377
if (test_bit(AFS_VNODE_DELETED, &vnode->flags))
13781378
kdebug("AFS_VNODE_DELETED");

fs/afs/inode.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ void afs_vnode_commit_status(struct afs_fs_cursor *fc,
283283
if (scb->status.abort_code == VNOVNODE) {
284284
set_bit(AFS_VNODE_DELETED, &vnode->flags);
285285
clear_nlink(&vnode->vfs_inode);
286-
__afs_break_callback(vnode);
286+
__afs_break_callback(vnode, afs_cb_break_for_deleted);
287287
}
288288
} else {
289289
if (scb->have_status)
@@ -594,8 +594,9 @@ bool afs_check_validity(struct afs_vnode *vnode)
594594
struct afs_cb_interest *cbi;
595595
struct afs_server *server;
596596
struct afs_volume *volume = vnode->volume;
597+
enum afs_cb_break_reason need_clear = afs_cb_break_no_break;
597598
time64_t now = ktime_get_real_seconds();
598-
bool valid, need_clear = false;
599+
bool valid;
599600
unsigned int cb_break, cb_s_break, cb_v_break;
600601
int seq = 0;
601602

@@ -613,13 +614,13 @@ bool afs_check_validity(struct afs_vnode *vnode)
613614
vnode->cb_v_break != cb_v_break) {
614615
vnode->cb_s_break = cb_s_break;
615616
vnode->cb_v_break = cb_v_break;
616-
need_clear = true;
617+
need_clear = afs_cb_break_for_vsbreak;
617618
valid = false;
618619
} else if (test_bit(AFS_VNODE_ZAP_DATA, &vnode->flags)) {
619-
need_clear = true;
620+
need_clear = afs_cb_break_for_zap;
620621
valid = false;
621622
} else if (vnode->cb_expires_at - 10 <= now) {
622-
need_clear = true;
623+
need_clear = afs_cb_break_for_lapsed;
623624
valid = false;
624625
} else {
625626
valid = true;
@@ -635,10 +636,12 @@ bool afs_check_validity(struct afs_vnode *vnode)
635636

636637
done_seqretry(&vnode->cb_lock, seq);
637638

638-
if (need_clear) {
639+
if (need_clear != afs_cb_break_no_break) {
639640
write_seqlock(&vnode->cb_lock);
640641
if (cb_break == vnode->cb_break)
641-
__afs_break_callback(vnode);
642+
__afs_break_callback(vnode, need_clear);
643+
else
644+
trace_afs_cb_miss(&vnode->fid, need_clear);
642645
write_sequnlock(&vnode->cb_lock);
643646
valid = false;
644647
}

fs/afs/internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,9 +848,9 @@ extern struct fscache_cookie_def afs_vnode_cache_index_def;
848848
* callback.c
849849
*/
850850
extern void afs_init_callback_state(struct afs_server *);
851-
extern void __afs_break_callback(struct afs_vnode *);
852-
extern void afs_break_callback(struct afs_vnode *);
853-
extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break*);
851+
extern void __afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
852+
extern void afs_break_callback(struct afs_vnode *, enum afs_cb_break_reason);
853+
extern void afs_break_callbacks(struct afs_server *, size_t, struct afs_callback_break *);
854854

855855
extern int afs_register_server_cb_interest(struct afs_vnode *,
856856
struct afs_server_list *, unsigned int);
@@ -1438,7 +1438,7 @@ static inline void afs_check_for_remote_deletion(struct afs_fs_cursor *fc,
14381438
{
14391439
if (fc->ac.error == -ENOENT) {
14401440
set_bit(AFS_VNODE_DELETED, &vnode->flags);
1441-
afs_break_callback(vnode);
1441+
afs_break_callback(vnode, afs_cb_break_for_deleted);
14421442
}
14431443
}
14441444

include/trace/events/afs.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,17 @@ enum afs_flock_operation {
195195
afs_flock_op_wake,
196196
};
197197

198+
enum afs_cb_break_reason {
199+
afs_cb_break_no_break,
200+
afs_cb_break_for_callback,
201+
afs_cb_break_for_deleted,
202+
afs_cb_break_for_lapsed,
203+
afs_cb_break_for_unlink,
204+
afs_cb_break_for_vsbreak,
205+
afs_cb_break_for_volume_callback,
206+
afs_cb_break_for_zap,
207+
};
208+
198209
#endif /* end __AFS_DECLARE_TRACE_ENUMS_ONCE_ONLY */
199210

200211
/*
@@ -374,6 +385,16 @@ enum afs_flock_operation {
374385
EM(afs_flock_op_unlock, "UNLOCK ") \
375386
E_(afs_flock_op_wake, "WAKE ")
376387

388+
#define afs_cb_break_reasons \
389+
EM(afs_cb_break_no_break, "no-break") \
390+
EM(afs_cb_break_for_callback, "break-cb") \
391+
EM(afs_cb_break_for_deleted, "break-del") \
392+
EM(afs_cb_break_for_lapsed, "break-lapsed") \
393+
EM(afs_cb_break_for_unlink, "break-unlink") \
394+
EM(afs_cb_break_for_vsbreak, "break-vs") \
395+
EM(afs_cb_break_for_volume_callback, "break-v-cb") \
396+
E_(afs_cb_break_for_zap, "break-zap")
397+
377398
/*
378399
* Export enum symbols via userspace.
379400
*/
@@ -392,6 +413,7 @@ afs_io_errors;
392413
afs_file_errors;
393414
afs_flock_types;
394415
afs_flock_operations;
416+
afs_cb_break_reasons;
395417

396418
/*
397419
* Now redefine the EM() and E_() macros to map the enums to the strings that
@@ -1171,6 +1193,53 @@ TRACE_EVENT(afs_get_tree,
11711193
__entry->cell, __entry->volume, __entry->vid)
11721194
);
11731195

1196+
TRACE_EVENT(afs_cb_break,
1197+
TP_PROTO(struct afs_fid *fid, unsigned int cb_break,
1198+
enum afs_cb_break_reason reason, bool skipped),
1199+
1200+
TP_ARGS(fid, cb_break, reason, skipped),
1201+
1202+
TP_STRUCT__entry(
1203+
__field_struct(struct afs_fid, fid )
1204+
__field(unsigned int, cb_break )
1205+
__field(enum afs_cb_break_reason, reason )
1206+
__field(bool, skipped )
1207+
),
1208+
1209+
TP_fast_assign(
1210+
__entry->fid = *fid;
1211+
__entry->cb_break = cb_break;
1212+
__entry->reason = reason;
1213+
__entry->skipped = skipped;
1214+
),
1215+
1216+
TP_printk("%llx:%llx:%x b=%x s=%u %s",
1217+
__entry->fid.vid, __entry->fid.vnode, __entry->fid.unique,
1218+
__entry->cb_break,
1219+
__entry->skipped,
1220+
__print_symbolic(__entry->reason, afs_cb_break_reasons))
1221+
);
1222+
1223+
TRACE_EVENT(afs_cb_miss,
1224+
TP_PROTO(struct afs_fid *fid, enum afs_cb_break_reason reason),
1225+
1226+
TP_ARGS(fid, reason),
1227+
1228+
TP_STRUCT__entry(
1229+
__field_struct(struct afs_fid, fid )
1230+
__field(enum afs_cb_break_reason, reason )
1231+
),
1232+
1233+
TP_fast_assign(
1234+
__entry->fid = *fid;
1235+
__entry->reason = reason;
1236+
),
1237+
1238+
TP_printk(" %llx:%llx:%x %s",
1239+
__entry->fid.vid, __entry->fid.vnode, __entry->fid.unique,
1240+
__print_symbolic(__entry->reason, afs_cb_break_reasons))
1241+
);
1242+
11741243
#endif /* _TRACE_AFS_H */
11751244

11761245
/* This part must be outside protection */

0 commit comments

Comments
 (0)