Skip to content

Commit 67d78a6

Browse files
committed
afs: Pass page into dirty region helpers to provide THP size
Pass a pointer to the page being accessed into the dirty region helpers so that the size of the page can be determined in case it's a transparent huge page. This also required the page to be passed into the afs_page_dirty trace point - so there's no need to specifically pass in the index or private data as these can be retrieved directly from the page struct. Signed-off-by: David Howells <dhowells@redhat.com> Tested-By: Marc Dionne <marc.dionne@auristor.com> cc: linux-afs@lists.infradead.org cc: linux-cachefs@redhat.com cc: linux-fsdevel@vger.kernel.org Link: https://lore.kernel.org/r/160588527183.3465195.16107942526481976308.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161118144921.1232039.11377711180492625929.stgit@warthog.procyon.org.uk/ # rfc Link: https://lore.kernel.org/r/161161040747.2537118.11435394902674511430.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/161340404553.1303470.11414163641767769882.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/161539548385.286939.8864598314493255313.stgit@warthog.procyon.org.uk/ # v4 Link: https://lore.kernel.org/r/161653804285.2770958.3497360004849598038.stgit@warthog.procyon.org.uk/ # v5 Link: https://lore.kernel.org/r/161789087043.6155.16922142208140170528.stgit@warthog.procyon.org.uk/ # v6
1 parent 03ffae9 commit 67d78a6

4 files changed

Lines changed: 55 additions & 64 deletions

File tree

fs/afs/file.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,8 @@ static void afs_invalidate_dirty(struct page *page, unsigned int offset,
514514
return;
515515

516516
/* We may need to shorten the dirty region */
517-
f = afs_page_dirty_from(priv);
518-
t = afs_page_dirty_to(priv);
517+
f = afs_page_dirty_from(page, priv);
518+
t = afs_page_dirty_to(page, priv);
519519

520520
if (t <= offset || f >= end)
521521
return; /* Doesn't overlap */
@@ -533,17 +533,17 @@ static void afs_invalidate_dirty(struct page *page, unsigned int offset,
533533
if (f == t)
534534
goto undirty;
535535

536-
priv = afs_page_dirty(f, t);
536+
priv = afs_page_dirty(page, f, t);
537537
set_page_private(page, priv);
538-
trace_afs_page_dirty(vnode, tracepoint_string("trunc"), page->index, priv);
538+
trace_afs_page_dirty(vnode, tracepoint_string("trunc"), page);
539539
return;
540540

541541
undirty:
542-
trace_afs_page_dirty(vnode, tracepoint_string("undirty"), page->index, priv);
542+
trace_afs_page_dirty(vnode, tracepoint_string("undirty"), page);
543543
clear_page_dirty_for_io(page);
544544
full_invalidate:
545-
priv = (unsigned long)detach_page_private(page);
546-
trace_afs_page_dirty(vnode, tracepoint_string("inval"), page->index, priv);
545+
detach_page_private(page);
546+
trace_afs_page_dirty(vnode, tracepoint_string("inval"), page);
547547
}
548548

549549
/*
@@ -571,7 +571,6 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
571571
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
572572
{
573573
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
574-
unsigned long priv;
575574

576575
_enter("{{%llx:%llu}[%lu],%lx},%x",
577576
vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
@@ -580,9 +579,8 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags)
580579
/* deny if page is being written to the cache and the caller hasn't
581580
* elected to wait */
582581
if (PagePrivate(page)) {
583-
priv = (unsigned long)detach_page_private(page);
584-
trace_afs_page_dirty(vnode, tracepoint_string("rel"),
585-
page->index, priv);
582+
detach_page_private(page);
583+
trace_afs_page_dirty(vnode, tracepoint_string("rel"), page);
586584
}
587585

588586
/* indicate that the page can be released */

fs/afs/internal.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -875,31 +875,31 @@ struct afs_vnode_cache_aux {
875875
#define __AFS_PAGE_PRIV_MMAPPED 0x8000UL
876876
#endif
877877

878-
static inline unsigned int afs_page_dirty_resolution(void)
878+
static inline unsigned int afs_page_dirty_resolution(struct page *page)
879879
{
880-
int shift = PAGE_SHIFT - (__AFS_PAGE_PRIV_SHIFT - 1);
880+
int shift = thp_order(page) + PAGE_SHIFT - (__AFS_PAGE_PRIV_SHIFT - 1);
881881
return (shift > 0) ? shift : 0;
882882
}
883883

884-
static inline size_t afs_page_dirty_from(unsigned long priv)
884+
static inline size_t afs_page_dirty_from(struct page *page, unsigned long priv)
885885
{
886886
unsigned long x = priv & __AFS_PAGE_PRIV_MASK;
887887

888888
/* The lower bound is inclusive */
889-
return x << afs_page_dirty_resolution();
889+
return x << afs_page_dirty_resolution(page);
890890
}
891891

892-
static inline size_t afs_page_dirty_to(unsigned long priv)
892+
static inline size_t afs_page_dirty_to(struct page *page, unsigned long priv)
893893
{
894894
unsigned long x = (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK;
895895

896896
/* The upper bound is immediately beyond the region */
897-
return (x + 1) << afs_page_dirty_resolution();
897+
return (x + 1) << afs_page_dirty_resolution(page);
898898
}
899899

900-
static inline unsigned long afs_page_dirty(size_t from, size_t to)
900+
static inline unsigned long afs_page_dirty(struct page *page, size_t from, size_t to)
901901
{
902-
unsigned int res = afs_page_dirty_resolution();
902+
unsigned int res = afs_page_dirty_resolution(page);
903903
from >>= res;
904904
to = (to - 1) >> res;
905905
return (to << __AFS_PAGE_PRIV_SHIFT) | from;

fs/afs/write.c

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,14 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
112112
t = f = 0;
113113
if (PagePrivate(page)) {
114114
priv = page_private(page);
115-
f = afs_page_dirty_from(priv);
116-
t = afs_page_dirty_to(priv);
115+
f = afs_page_dirty_from(page, priv);
116+
t = afs_page_dirty_to(page, priv);
117117
ASSERTCMP(f, <=, t);
118118
}
119119

120120
if (f != t) {
121121
if (PageWriteback(page)) {
122-
trace_afs_page_dirty(vnode, tracepoint_string("alrdy"),
123-
page->index, priv);
122+
trace_afs_page_dirty(vnode, tracepoint_string("alrdy"), page);
124123
goto flush_conflicting_write;
125124
}
126125
/* If the file is being filled locally, allow inter-write
@@ -204,21 +203,19 @@ int afs_write_end(struct file *file, struct address_space *mapping,
204203

205204
if (PagePrivate(page)) {
206205
priv = page_private(page);
207-
f = afs_page_dirty_from(priv);
208-
t = afs_page_dirty_to(priv);
206+
f = afs_page_dirty_from(page, priv);
207+
t = afs_page_dirty_to(page, priv);
209208
if (from < f)
210209
f = from;
211210
if (to > t)
212211
t = to;
213-
priv = afs_page_dirty(f, t);
212+
priv = afs_page_dirty(page, f, t);
214213
set_page_private(page, priv);
215-
trace_afs_page_dirty(vnode, tracepoint_string("dirty+"),
216-
page->index, priv);
214+
trace_afs_page_dirty(vnode, tracepoint_string("dirty+"), page);
217215
} else {
218-
priv = afs_page_dirty(from, to);
216+
priv = afs_page_dirty(page, from, to);
219217
attach_page_private(page, (void *)priv);
220-
trace_afs_page_dirty(vnode, tracepoint_string("dirty"),
221-
page->index, priv);
218+
trace_afs_page_dirty(vnode, tracepoint_string("dirty"), page);
222219
}
223220

224221
set_page_dirty(page);
@@ -321,7 +318,6 @@ static void afs_pages_written_back(struct afs_vnode *vnode,
321318
pgoff_t first, pgoff_t last)
322319
{
323320
struct pagevec pv;
324-
unsigned long priv;
325321
unsigned count, loop;
326322

327323
_enter("{%llx:%llu},{%lx-%lx}",
@@ -340,9 +336,9 @@ static void afs_pages_written_back(struct afs_vnode *vnode,
340336
ASSERTCMP(pv.nr, ==, count);
341337

342338
for (loop = 0; loop < count; loop++) {
343-
priv = (unsigned long)detach_page_private(pv.pages[loop]);
339+
detach_page_private(pv.pages[loop]);
344340
trace_afs_page_dirty(vnode, tracepoint_string("clear"),
345-
pv.pages[loop]->index, priv);
341+
pv.pages[loop]);
346342
end_page_writeback(pv.pages[loop]);
347343
}
348344
first += count;
@@ -516,15 +512,13 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
516512
*/
517513
start = primary_page->index;
518514
priv = page_private(primary_page);
519-
offset = afs_page_dirty_from(priv);
520-
to = afs_page_dirty_to(priv);
521-
trace_afs_page_dirty(vnode, tracepoint_string("store"),
522-
primary_page->index, priv);
515+
offset = afs_page_dirty_from(primary_page, priv);
516+
to = afs_page_dirty_to(primary_page, priv);
517+
trace_afs_page_dirty(vnode, tracepoint_string("store"), primary_page);
523518

524519
WARN_ON(offset == to);
525520
if (offset == to)
526-
trace_afs_page_dirty(vnode, tracepoint_string("WARN"),
527-
primary_page->index, priv);
521+
trace_afs_page_dirty(vnode, tracepoint_string("WARN"), primary_page);
528522

529523
if (start >= final_page ||
530524
(to < PAGE_SIZE && !test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)))
@@ -562,17 +556,16 @@ static int afs_write_back_from_locked_page(struct address_space *mapping,
562556
}
563557

564558
priv = page_private(page);
565-
f = afs_page_dirty_from(priv);
566-
t = afs_page_dirty_to(priv);
559+
f = afs_page_dirty_from(page, priv);
560+
t = afs_page_dirty_to(page, priv);
567561
if (f != 0 &&
568562
!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags)) {
569563
unlock_page(page);
570564
break;
571565
}
572566
to = t;
573567

574-
trace_afs_page_dirty(vnode, tracepoint_string("store+"),
575-
page->index, priv);
568+
trace_afs_page_dirty(vnode, tracepoint_string("store+"), page);
576569

577570
if (!clear_page_dirty_for_io(page))
578571
BUG();
@@ -860,14 +853,13 @@ vm_fault_t afs_page_mkwrite(struct vm_fault *vmf)
860853
*/
861854
wait_on_page_writeback(vmf->page);
862855

863-
priv = afs_page_dirty(0, PAGE_SIZE);
856+
priv = afs_page_dirty(vmf->page, 0, PAGE_SIZE);
864857
priv = afs_page_dirty_mmapped(priv);
865-
trace_afs_page_dirty(vnode, tracepoint_string("mkwrite"),
866-
vmf->page->index, priv);
867858
if (PagePrivate(vmf->page))
868859
set_page_private(vmf->page, priv);
869860
else
870861
attach_page_private(vmf->page, (void *)priv);
862+
trace_afs_page_dirty(vnode, tracepoint_string("mkwrite"), vmf->page);
871863
file_update_time(file);
872864

873865
sb_end_pagefault(inode->i_sb);
@@ -920,17 +912,15 @@ int afs_launder_page(struct page *page)
920912
f = 0;
921913
t = PAGE_SIZE;
922914
if (PagePrivate(page)) {
923-
f = afs_page_dirty_from(priv);
924-
t = afs_page_dirty_to(priv);
915+
f = afs_page_dirty_from(page, priv);
916+
t = afs_page_dirty_to(page, priv);
925917
}
926918

927-
trace_afs_page_dirty(vnode, tracepoint_string("launder"),
928-
page->index, priv);
919+
trace_afs_page_dirty(vnode, tracepoint_string("launder"), page);
929920
ret = afs_store_data(mapping, page->index, page->index, t, f, true);
930921
}
931922

932-
priv = (unsigned long)detach_page_private(page);
933-
trace_afs_page_dirty(vnode, tracepoint_string("laundered"),
934-
page->index, priv);
923+
detach_page_private(page);
924+
trace_afs_page_dirty(vnode, tracepoint_string("laundered"), page);
935925
return ret;
936926
}

include/trace/events/afs.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -969,30 +969,33 @@ TRACE_EVENT(afs_dir_check_failed,
969969
);
970970

971971
TRACE_EVENT(afs_page_dirty,
972-
TP_PROTO(struct afs_vnode *vnode, const char *where,
973-
pgoff_t page, unsigned long priv),
972+
TP_PROTO(struct afs_vnode *vnode, const char *where, struct page *page),
974973

975-
TP_ARGS(vnode, where, page, priv),
974+
TP_ARGS(vnode, where, page),
976975

977976
TP_STRUCT__entry(
978977
__field(struct afs_vnode *, vnode )
979978
__field(const char *, where )
980979
__field(pgoff_t, page )
981-
__field(unsigned long, priv )
980+
__field(unsigned long, from )
981+
__field(unsigned long, to )
982982
),
983983

984984
TP_fast_assign(
985985
__entry->vnode = vnode;
986986
__entry->where = where;
987-
__entry->page = page;
988-
__entry->priv = priv;
987+
__entry->page = page->index;
988+
__entry->from = afs_page_dirty_from(page, page->private);
989+
__entry->to = afs_page_dirty_to(page, page->private);
990+
__entry->to |= (afs_is_page_dirty_mmapped(page->private) ?
991+
(1UL << (BITS_PER_LONG - 1)) : 0);
989992
),
990993

991-
TP_printk("vn=%p %lx %s %zx-%zx%s",
994+
TP_printk("vn=%p %lx %s %lx-%lx%s",
992995
__entry->vnode, __entry->page, __entry->where,
993-
afs_page_dirty_from(__entry->priv),
994-
afs_page_dirty_to(__entry->priv),
995-
afs_is_page_dirty_mmapped(__entry->priv) ? " M" : "")
996+
__entry->from,
997+
__entry->to & ~(1UL << (BITS_PER_LONG - 1)),
998+
__entry->to & (1UL << (BITS_PER_LONG - 1)) ? " M" : "")
996999
);
9971000

9981001
TRACE_EVENT(afs_call_state,

0 commit comments

Comments
 (0)