On Fri 01-06-18 09:05:50, Dave Chinner wrote:
On Thu, May 31, 2018 at 11:26:43AM -0700, Dan Williams wrote:
> On Thu, May 31, 2018 at 10:46 AM, Darrick J. Wong
> > The recent thread between Jan and Dan make me wonder if making mappings
> > share struct pages is going to be a nightmare to add to the mm code,
> > though...
> It's going to be a bit messy because a singular page->mapping
> association is fundamentally incompatible with DAX. Perhaps a linked
> list of mapping "siblings"?
I'd much prefer the filesystem allocate/control the struct page that
is inserted into mapping trees so we can have multiple struct pages
pointing at the one physical page. That way we can just insert
these dynamic struct pages into the relevant mappings and it works
the same way for both DAX and shared page cache pages.
Yes, that's one option but the overhead in terms of memory and CPU is
non-trivial and as Dan writes there are assumptions in MM code that
PFN<->struct page is 1:1 relationship (or possibly 1:0 as struct page can
be missing for certain types of pfns). But at this point I think the exact
data structure layout is not that important (whether there will be dynamic
struct pages or some other linkage). I think we first need to settle on
how responsibilities between MM and filesystems are going to be split.
i.e. the filesystem knows they are shared physical blocks, the
filesystem controls COW of physical blocks, the filesystem controls
truncate/invalidation of physical blocks, the filesystem controls
cache state of the physical blocks. So why are we designing
infrastructure around the virtual memory and caching infrastructure
that bypasses the layer that manages and arbitrates access to the
I agree with this but let's see whether we are on the same page. What MM
mostly cares about and in particular what Dan needs to solve is "given
struct page, give me all page tables that map this page". And it seems
completely fair to me to maintain such translation within MM code as the
filesystem generally does not care in too big detail about memory mappings
of files. When something with the page is going happen (like breaking cow,
truncate, whatever), the filesystem just tells MM to invalidate all page
tables for the page and subsequent page faults will fill in updated
information - nothing new here.
Then there's a second slightly different question - and I suspect you are
speaking about that one - "given struct page, give me all radix trees
pointing to this page". This is more a filesystem caching question (even in
case of DAX, you can think of this as caching of inode + logical offset =>
physical block translations). Currently this translation is maintained by
page cache and again the filesystem is mostly ignorant of details of what
and when gets cached and just tells the MM when it should throw away the
cached information (through truncate/invalidate_inode_pages()).
With reflink and DAX / shared page cache these questions get more complex
to answer but in principle I don't see why the mapping from the struct page
to radix trees should not be maintained (with a help of the filesystem) in
generic code. Sure the interface now needs to be more flexible and in that
sense filesystems will be more in control what the page cache is doing -
e.g. ->readpage callback would probably need to be passed just inode +
logical offset and *the filesystem* will now need to find / allocate
approprite page, fill it up, and tell page cache this page is now caching
given offset in the file. And page cache will add this inode + offset to a
list of things caching this page. Do you agree or you had something
different in mind?
Jan Kara <jack(a)suse.com>
SUSE Labs, CR