- 论坛徽章:
- 0
|
Hi all,
我在 trace v6_copy_user_highpage_aliasing in arch/arm/mm/copypage-v6.c 一些問題想不透。
這個就是 invalidate 一個 page。
static void discard_old_kernel_data(void *kto)
{
__asm__("mcrr p15, 0, %1, %0, c6 @ 0xec401f06"
:
: "r" (kto),
"r" ((unsigned long)kto + PAGE_SIZE - L1_CACHE_BYTES)
: "cc");
}
/*
* Copy the page, taking account of the cache colour.
*/
static void v6_copy_user_highpage_aliasing(struct page *to,
struct page *from, unsigned long vaddr)
{
unsigned int offset = CACHE_COLOUR(vaddr);
unsigned long kfrom, kto;
我想下面這個 if 條件式用來解決 from 這個 physical page,同時有兩個 kernel
& user virtual address map 到這裡時。當 kernel 端這邊是 dirty 時會把
kernel所對應到的 cache writeback,以便到時候用 aliasing 做出來的暫時
address 可以 copy 到dirty的 data。進而解決不一致的問題。這時候我有些
疑問:PG_dcache_dirty 在何時被設立,感覺在 do_wp_page() 也就是 copy-on-write
的 case 這個 if 條件不會成立。再來如果沒有這行在哪邊會出現問題 ?
if (test_and_clear_bit(PG_dcache_dirty, &from->flags))
__flush_dcache_page(page_mapping(from), from);
這個問題和上面的問題類似,kernel 這裡的 page_address(to) 所對應的 cache 必
需要 invalidate 掉。到時候 從 kfrom copy 過來到 kto 的資料是最新的,
而 page_address(to) 有可能他的 color 和 kfrom 不一致,導致他沒有最新的data。
同樣的,我在想,如果沒有這行會出現什麼問題嗎?
/* FIXME: not highmem safe */
discard_old_kernel_data(page_address(to));
/*
* Now copy the page using the same cache colour as the
* pages ultimate destination.
*/
spin_lock(&v6_lock);
set_pte_ext(TOP_PTE(from_address) + offset,
pfn_pte(page_to_pfn(from), PAGE_KERNEL), 0);
set_pte_ext(TOP_PTE(to_address) + offset,
pfn_pte(page_to_pfn(to), PAGE_KERNEL), 0);
kfrom = from_address + (offset << PAGE_SHIFT);
kto = to_address + (offset << PAGE_SHIFT);
flush_tlb_kernel_page(kfrom);
flush_tlb_kernel_page(kto);
copy_page((void *)kto, (void *)kfrom);
spin_unlock(&v6_lock);
}
謝謝各位的回覆,歡迎任何意見。
Gavin |
|