Skip to content

Commit 13524ab

Browse files
committed
afs: Trace page dirty/clean
Add a trace event that logs the dirtying and cleaning of pages attached to AFS inodes. Signed-off-by: David Howells <[email protected]>
1 parent 1cf7a15 commit 13524ab

File tree

3 files changed

+70
-13
lines changed

3 files changed

+70
-13
lines changed

fs/afs/file.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,9 @@ static int afs_readpages(struct file *file, struct address_space *mapping,
583583
static void afs_invalidatepage(struct page *page, unsigned int offset,
584584
unsigned int length)
585585
{
586+
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
587+
unsigned long priv;
588+
586589
_enter("{%lu},%u,%u", page->index, offset, length);
587590

588591
BUG_ON(!PageLocked(page));
@@ -598,6 +601,9 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
598601
#endif
599602

600603
if (PagePrivate(page)) {
604+
priv = page_private(page);
605+
trace_afs_page_dirty(vnode, tracepoint_string("inval"),
606+
page->index, priv);
601607
set_page_private(page, 0);
602608
ClearPagePrivate(page);
603609
}
@@ -613,6 +619,7 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
613619
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
614620
{
615621
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
622+
unsigned long priv;
616623

617624
_enter("{{%x:%u}[%lu],%lx},%x",
618625
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
@@ -628,6 +635,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
628635
#endif
629636

630637
if (PagePrivate(page)) {
638+
priv = page_private(page);
639+
trace_afs_page_dirty(vnode, tracepoint_string("rel"),
640+
page->index, priv);
631641
set_page_private(page, 0);
632642
ClearPagePrivate(page);
633643
}

fs/afs/write.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,6 @@
1717
#include <linux/pagevec.h>
1818
#include "internal.h"
1919

20-
/*
21-
* We use page->private to hold the amount of the page that we've written to,
22-
* splitting the field into two parts. However, we need to represent a range
23-
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
24-
*/
25-
#if PAGE_SIZE > 32768
26-
#define AFS_PRIV_MAX 0xffffffff
27-
#define AFS_PRIV_SHIFT 32
28-
#else
29-
#define AFS_PRIV_MAX 0xffff
30-
#define AFS_PRIV_SHIFT 16
31-
#endif
32-
3320
/*
3421
* mark a page as having been made dirty and thus needing writeback
3522
*/
@@ -145,6 +132,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
145132

146133
priv = (unsigned long)t << AFS_PRIV_SHIFT;
147134
priv |= f;
135+
trace_afs_page_dirty(vnode, tracepoint_string("begin"),
136+
page->index, priv);
148137
SetPagePrivate(page);
149138
set_page_private(page, priv);
150139
_leave(" = 0");
@@ -386,6 +375,7 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
386375
struct page *primary_page,
387376
pgoff_t final_page)
388377
{
378+
struct afs_vnode *vnode = AFS_FS_I(mapping->host);
389379
struct page *pages[8], *page;
390380
unsigned long count, priv;
391381
unsigned n, offset, to, f, t;
@@ -407,8 +397,13 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
407397
priv = page_private(primary_page);
408398
offset = priv & AFS_PRIV_MAX;
409399
to = priv >> AFS_PRIV_SHIFT;
400+
trace_afs_page_dirty(vnode, tracepoint_string("store"),
401+
primary_page->index, priv);
410402

411403
WARN_ON(offset == to);
404+
if (offset == to)
405+
trace_afs_page_dirty(vnode, tracepoint_string("WARN"),
406+
primary_page->index, priv);
412407

413408
if (start >= final_page || to < PAGE_SIZE)
414409
goto no_more;
@@ -452,6 +447,9 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
452447
}
453448
to = t;
454449

450+
trace_afs_page_dirty(vnode, tracepoint_string("store+"),
451+
page->index, priv);
452+
455453
if (!clear_page_dirty_for_io(page))
456454
BUG();
457455
if (test_set_page_writeback(page))
@@ -657,6 +655,7 @@ int afs_writepages(struct address_space *mapping,
657655
void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
658656
{
659657
struct pagevec pv;
658+
unsigned long priv;
660659
unsigned count, loop;
661660
pgoff_t first = call->first, last = call->last;
662661

@@ -676,6 +675,9 @@ void afs_pages_written_back(struct afs_vnode *vnode, struct afs_call *call)
676675
ASSERTCMP(pv.nr, ==, count);
677676

678677
for (loop = 0; loop < count; loop++) {
678+
priv = page_private(pv.pages[loop]);
679+
trace_afs_page_dirty(vnode, tracepoint_string("clear"),
680+
pv.pages[loop]->index, priv);
679681
set_page_private(pv.pages[loop], 0);
680682
end_page_writeback(pv.pages[loop]);
681683
}
@@ -783,6 +785,8 @@ int afs_page_mkwrite(struct vm_fault *vmf)
783785

784786
priv = (unsigned long)PAGE_SIZE << AFS_PRIV_SHIFT; /* To */
785787
priv |= 0; /* From */
788+
trace_afs_page_dirty(vnode, tracepoint_string("mkwrite"),
789+
vmf->page->index, priv);
786790
SetPagePrivate(vmf->page);
787791
set_page_private(vmf->page, priv);
788792

@@ -840,9 +844,13 @@ int afs_launder_page(struct page *page)
840844
t = priv >> AFS_PRIV_SHIFT;
841845
}
842846

847+
trace_afs_page_dirty(vnode, tracepoint_string("launder"),
848+
page->index, priv);
843849
ret = afs_store_data(mapping, page->index, page->index, t, f);
844850
}
845851

852+
trace_afs_page_dirty(vnode, tracepoint_string("laundered"),
853+
page->index, priv);
846854
set_page_private(page, 0);
847855
ClearPagePrivate(page);
848856

include/trace/events/afs.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,45 @@ TRACE_EVENT(afs_dir_check_failed,
402402
__entry->vnode, __entry->off, __entry->i_size)
403403
);
404404

405+
/*
406+
* We use page->private to hold the amount of the page that we've written to,
407+
* splitting the field into two parts. However, we need to represent a range
408+
* 0...PAGE_SIZE inclusive, so we can't support 64K pages on a 32-bit system.
409+
*/
410+
#if PAGE_SIZE > 32768
411+
#define AFS_PRIV_MAX 0xffffffff
412+
#define AFS_PRIV_SHIFT 32
413+
#else
414+
#define AFS_PRIV_MAX 0xffff
415+
#define AFS_PRIV_SHIFT 16
416+
#endif
417+
418+
TRACE_EVENT(afs_page_dirty,
419+
TP_PROTO(struct afs_vnode *vnode, const char *where,
420+
pgoff_t page, unsigned long priv),
421+
422+
TP_ARGS(vnode, where, page, priv),
423+
424+
TP_STRUCT__entry(
425+
__field(struct afs_vnode *, vnode )
426+
__field(const char *, where )
427+
__field(pgoff_t, page )
428+
__field(unsigned long, priv )
429+
),
430+
431+
TP_fast_assign(
432+
__entry->vnode = vnode;
433+
__entry->where = where;
434+
__entry->page = page;
435+
__entry->priv = priv;
436+
),
437+
438+
TP_printk("vn=%p %lx %s %lu-%lu",
439+
__entry->vnode, __entry->page, __entry->where,
440+
__entry->priv & AFS_PRIV_MAX,
441+
__entry->priv >> AFS_PRIV_SHIFT)
442+
);
443+
405444
#endif /* _TRACE_AFS_H */
406445

407446
/* This part must be outside protection */

0 commit comments

Comments
 (0)