From: Miklos S. <mi...@sz...> - 2006-04-04 08:50:29
|
> > flush_dcache_page(): > > - The kernel address is flushed regardless whether the page is > > anonymous or not > > Not quite ... if the page is file backed but has no user mappings, on > the page dirty bit will be set (the kernel view won't be flushed). Yes, but in this case (page obtained from get_user_pages()) it obviously does have a user mapping. > > - If the page is file backed, then all user addresses refering to > > the page are flushed > > Yes, that's what it does. > > > Why this discrepancy between anonymous and file backed pages? > > Wounldn't it be enough for file backed pages too to flush only one > > user address? > > Not necessarily ... you're getting deep into how VIPT and VIVT caches > work. VIVT and non-CAM based VIPT caches need every alias flushed > (well, that's not congruent, anyway ... we try to keep congruence in > parisc, but it's not always possible). Usually a page is either file > backed or anonymous, so for an anonymous page, we wouldn't know the user > address to flush even if it were congruent. I still don't see _why_ you need all aliases flushed from get_user_pages() when you are only accessing the page through a single address. Think of it this way: get_user_pages(... write=0 ...) + memcpy() is equivalent to copy_from_user() get_user_pages(... write=1 ...) + memcpy() + flush_kernel_dcache_page() is equivalent to copy_to_user() copy_from_user() and copy_to_user() don't care about aliases, do they? > > Added to the mix are copy_to/from_user_page() which already seem to do > > the above, and are used in combination with get_user_pages() which > > results in multiple redundant cache flushes. Not too clean, is it? > > I don't see that they do. If flush_dcache_page() also does anon pages, > then the arch implementation of flush_anon_page() will be empty. If it > doesn't, then the flush_anon_page() and flush_dcache_page() are mutually > exclusive, anyway (because they both check the anon flag). No, I was thinking of get_user_pages() copy_to_user_page()/copy_from_user_page() copy_to/from_user_page are defined as: flush_cache_page(vma, vaddr, page_to_pfn(page)); \ memcpy(dst, src, len); \ ... So they do flush the caches _once more_ after get_user_pages() should have already done so. OK, I see it flushes the icache as well, but then only an icache flush should be needed, no? Miklos |