Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > +static inline unsigned int afs_page_dirty_resolution(void) > > I've been using size_t for offsets within a struct page. I don't know > that we'll ever support pages larger than 2GB (they're completely > impractical with today's bus speeds), but I'd rather not be the one > who has to track down all the uses of 'int' in the kernel in fifteen > years time. Going beyond 2G page size won't be fun and a lot of our APIs will break - write_begin, write_end, invalidatepage to name a few. It would probably require an analysis program to trace all the usages of such information within the kernel. > > +{ > > + if (PAGE_SIZE - 1 <= __AFS_PAGE_PRIV_MASK) > > + return 1; > > + else > > + return PAGE_SIZE / (__AFS_PAGE_PRIV_MASK + 1); > > Could this be DIV_ROUND_UP(PAGE_SIZE, __AFS_PAGE_PRIV_MASK + 1); avoiding > a conditional? I appreciate it's calculated at compile time today, but > it'll be dynamic with THP. That seems to work. > > static inline unsigned int afs_page_dirty_to(unsigned long priv) > > { > > - return ((priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK) + 1; > > + unsigned int x = (priv >> __AFS_PAGE_PRIV_SHIFT) & __AFS_PAGE_PRIV_MASK; > > + > > + /* The upper bound is exclusive */ > > I think you mean 'inclusive'. The returned upper bound points immediately beyond the range. E.g. 0-0 is an empty range. Changing that is way too big an overhaul outside the merge window. > > + return (x + 1) * afs_page_dirty_resolution(); > > } > > > > static inline unsigned long afs_page_dirty(unsigned int from, unsigned int to) > > { > > + unsigned int res = afs_page_dirty_resolution(); > > + from /= res; /* Round down */ > > + to = (to + res - 1) / res; /* Round up */ > > return ((unsigned long)(to - 1) << __AFS_PAGE_PRIV_SHIFT) | from; > > Wouldn't it produce the same result to just round down? ie: > > to = (to - 1) / res; > return ((unsigned long)to << __AFS_PAGE_PRIV_SHIFT) | from; Actually, yes, because res/res==1, which I then subtract afterwards. David