亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標(biāo)題: 一個(gè)cache相關(guān)的問(wèn)題 [打印本頁(yè)]

作者: duanius    時(shí)間: 2010-11-04 21:47
標(biāo)題: 一個(gè)cache相關(guān)的問(wèn)題
這周碰到的一個(gè)問(wèn)題,在解決的過(guò)程中得到不少高手的熱心幫助,把一些總結(jié)貼出來(lái),歡迎大家指點(diǎn)。

寫(xiě)一個(gè)屏驅(qū)動(dòng)的時(shí)候,需要把一塊內(nèi)核中用kmalloc分配的內(nèi)存映射到應(yīng)用層中使用。這是一個(gè)很simple的需求,很輕松的就可以通過(guò)mmap搞定:

驅(qū)動(dòng)部分代碼:
1698         if((mmap_addr = kmalloc(PAGE_SIZE, GFP_KERNEL)) == NULL){
1699                 ret = -ENOMEM;
1700                 goto out;
1701         }
1702         SetPageReserved(virt_to_page((mmap_addr)));

....

899         long length = vma->vm_end - vma->vm_start;
900
901         if (length > PAGE_SIZE)
902                 return -EIO;
903
904         if ((ret = remap_pfn_range(vma,vma->vm_start,virt_to_phys((void *)mmap_addr) >> PAGE_SHIFT,length,vma->vm_page_prot)) < 0) {
905                 return ret;

....


應(yīng)用層通過(guò)
401         if( ( addr = mmap(NULL, 4096, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0 )) == (void *)-1)
402         {
403                 perror("mmap error\n");
404                 return -1;
405         }
獲得地址, 然后往內(nèi)寫(xiě)入

這是一種通過(guò)普通內(nèi)存設(shè)為保留,當(dāng)成io內(nèi)存映射并map出去的一種方式。經(jīng)過(guò)測(cè)試,發(fā)現(xiàn)大部分時(shí)候數(shù)據(jù)是對(duì)的,但偶爾數(shù)據(jù)會(huì)出錯(cuò)。隨后嘗試不采用remap_pfn_range建立頁(yè)表,而是通過(guò)缺頁(yè)時(shí)返回分配頁(yè)的動(dòng)態(tài)方式來(lái)處理,結(jié)果仍然一樣。

我們猜測(cè)是由于cache的原因?qū)е碌,于是在mmap的時(shí)候使其nocache,仍然無(wú)法解決。在實(shí)在沒(méi)有辦法的情況下,我們嘗試采用在內(nèi)核讀取共享內(nèi)存時(shí)執(zhí)行flush_all_cache,果然,解決了問(wèn)題,證明了確實(shí)是cache導(dǎo)致的。

那么為什么一開(kāi)始我們種種嘗試未能成功呢?因?yàn)槲覀兣戳朔较。我們以為是?yīng)用層在讀cache,內(nèi)核讀內(nèi)存,實(shí)際上,由于采用remap_pfn_range,或者我們?cè)趍map的時(shí)候指定了nocache的方式,應(yīng)用層讀取這片vma的時(shí)候是根據(jù)其指定的nocache屬性去讀內(nèi)存,而內(nèi)核訪問(wèn)kmalloc的時(shí)候卻是讀內(nèi)存。如何讓內(nèi)核也讀內(nèi)存呢,很簡(jiǎn)單,通過(guò)ioremap_nocache把kmalloc得到的地址再做一次映射,然后給內(nèi)核用就可以了。

這就是傳說(shuō)中的Cache Coherence ---緩存一致性。由于cache和內(nèi)存在某些時(shí)候的不一致而導(dǎo)致的不同地址空間分別讀寫(xiě)導(dǎo)致的問(wèn)題。并不是所有體系結(jié)構(gòu)都存在這種問(wèn)題,比如x86.我曾經(jīng)在x86上用過(guò)mmap并且使用良好,因?yàn)閤86的體系結(jié)構(gòu)確保了緩存一致性:其總線監(jiān)聽(tīng)技術(shù)使當(dāng)某片被cache的內(nèi)存被其他請(qǐng)求操作時(shí),會(huì)被立刻回寫(xiě),確保cache與內(nèi)存的一致性。但這種監(jiān)聽(tīng)技術(shù)會(huì)帶來(lái)性能上的損耗,所以arm是由軟件來(lái)確保這個(gè)一致性的:一些時(shí)候,比如進(jìn)程切換,必須通過(guò)flush整個(gè)cache獲得正確的內(nèi)存訪問(wèn)。

在這里例子里,我們是通過(guò)內(nèi)核和應(yīng)用都nocache的方式來(lái)進(jìn)行內(nèi)存共享的。那么雙方能不能通過(guò)cache的方式來(lái)訪問(wèn)呢?我們必須知道,有兩種cache:物理cache和邏輯cache,對(duì)于armv6以下的arm芯片,采用的是邏輯cache的方式,即cache在mmu之前,而armv6及以上的cpu,cache在mmu之后,cpu送出的要訪問(wèn)的地址先通過(guò)mmu進(jìn)行虛擬/物理的轉(zhuǎn)換,再送到cache。這意味著什么呢?意味著對(duì)于我們的cpu(v5),當(dāng)應(yīng)用層用其地址空間的地址把共享區(qū)從內(nèi)存加到cache后,內(nèi)核同樣訪問(wèn)這片區(qū)域的時(shí)候,也可以按照其kmalloc分配的地址將同一片內(nèi)存中的數(shù)據(jù)加載到cache的另一行中,這就意味著一個(gè)內(nèi)存塊會(huì)有2個(gè)cache拷貝,也就是傳說(shuō)中的別名。簡(jiǎn)單地說(shuō),如果你用arm11,由于使用物理cache,所以不會(huì)有問(wèn)題,而arm9的話,就很麻煩了。

那為什么有時(shí)候訪問(wèn)正確,有時(shí)候訪問(wèn)錯(cuò)誤呢?這就和cache的替換策略有關(guān)了。不像x86由于總線監(jiān)視的原因,可以在相關(guān)內(nèi)存被touch的時(shí)候回寫(xiě),arm的cache只有當(dāng)是dirty,并且被cache輪轉(zhuǎn)策略選中需要換出的時(shí)候,才會(huì)被回寫(xiě)。所以有時(shí)候,某些加載共享內(nèi)存的cache塊沒(méi)有被替換,而相應(yīng)的內(nèi)存塊又被內(nèi)核加載到cache形成別名,錯(cuò)誤就自然產(chǎn)生了。

這就是cache導(dǎo)致的問(wèn)題。如果雙方采用一樣的cache策略,自然cache就是透明的,但是如果是不一樣的方式,那么可能就會(huì)有問(wèn)題。具體會(huì)有哪些問(wèn)題,如前所述,就和cpu,體系結(jié)構(gòu)有著密切的關(guān)系了。
作者: sep    時(shí)間: 2010-11-04 22:23
本帖最后由 sep 于 2010-11-04 22:24 編輯

受教了!拔覀円詾槭菓(yīng)用層在讀cache,內(nèi)核讀內(nèi)存”,開(kāi)始我也這樣以為的,本來(lái)還對(duì)snail同學(xué)存在一些疑問(wèn)。嵌入式版塊里一個(gè)tx的問(wèn)題估計(jì)跟你的問(wèn)題類(lèi)似。
作者: smalloc    時(shí)間: 2010-11-04 22:26
謝謝分享
王齊在 linux  powerpc詳解 提到了物理cache 和虛擬cache一說(shuō).
是不是就是lz說(shuō)的物理cache和邏輯cache?
也就是你說(shuō)的不一致實(shí)際原因是.虛擬cache根本不從物理cache裝載數(shù)據(jù)?而是直接從物理內(nèi)存裝載數(shù)據(jù)?
作者: duanius    時(shí)間: 2010-11-04 22:37
受教了。“我們以為是應(yīng)用層在讀cache,內(nèi)核讀內(nèi)存”,開(kāi)始我也這樣以為的,本來(lái)還對(duì)snail同學(xué)存在一些疑問(wèn) ...
sep 發(fā)表于 2010-11-04 22:23


是的 這個(gè)想法誤導(dǎo)了我很長(zhǎng)時(shí)間 。也是我sx了, 設(shè)nocache就是給vma設(shè)的 居然認(rèn)為會(huì)影響到內(nèi)核
作者: duanius    時(shí)間: 2010-11-04 22:52
謝謝分享
王齊在 linux  powerpc詳解 提到了物理cache 和虛擬cache一說(shuō).
是不是就是lz說(shuō)的物理cache和邏輯 ...
smalloc 發(fā)表于 2010-11-04 22:26



應(yīng)該就是那個(gè)邏輯和物理cache吧
虛擬,也就是邏輯cache不是虛擬的cache的意思 而是指在cache中用邏輯地址尋址  物理cache同樣   也就是離cpu之間隔一個(gè)mmu  而邏輯cache隔開(kāi)cpu和mmu
作者: smalloc    時(shí)間: 2010-11-04 22:58
回復(fù) 5# duanius


    恩.你看看這句是不是筆誤
應(yīng)用層讀取這片vma的時(shí)候是根據(jù)其指定的nocache屬性去讀內(nèi)存,而內(nèi)核訪問(wèn)kmalloc的時(shí)候卻是讀內(nèi)存
看了半天不理解
作者: smalloc    時(shí)間: 2010-11-04 23:02
還有你現(xiàn)在出問(wèn)題的板子上2種cache同時(shí)實(shí)現(xiàn)了嗎?同時(shí)作用?
我看你前面的描述感覺(jué)并不是同時(shí)實(shí)現(xiàn),好象說(shuō)有的只實(shí)現(xiàn)物理 有的只實(shí)現(xiàn)邏輯
如果2個(gè)都是物理的或者邏輯的,那么一開(kāi)始就不會(huì)出問(wèn)題了,是這意思?
作者: duanius    時(shí)間: 2010-11-04 23:25
回復(fù)  duanius


    恩.你看看這句是不是筆誤
應(yīng)用層讀取這片vma的時(shí)候是根據(jù)其指定的nocache屬性去讀 ...
smalloc 發(fā)表于 2010-11-04 22:58



    我們的需求是內(nèi)核讀  應(yīng)用層讀寫(xiě)  ,我可能描述的不準(zhǔn)確吧,總之,應(yīng)用層訪問(wèn)那塊vma是根據(jù)prog flag指定的來(lái)做的 比如不cache,不用寫(xiě)緩沖之類(lèi)
不過(guò)說(shuō)讀也可以  因?yàn)閍rm只有讀分配cache,寫(xiě)一般不分配,除非命中
作者: duanius    時(shí)間: 2010-11-04 23:27
還有你現(xiàn)在出問(wèn)題的板子上2種cache同時(shí)實(shí)現(xiàn)了嗎?同時(shí)作用?
我看你前面的描述感覺(jué)并不是同時(shí)實(shí)現(xiàn),好象說(shuō)有的 ...
smalloc 發(fā)表于 2010-11-04 23:02



不不  邏輯cache和物理cache只是一種cache的組織形式 沒(méi)法同時(shí)存在
比如x86,arm11 用的是物理cache,而arm9用的是邏輯cache  只會(huì)有一種cache存在
對(duì)于arm11 只要同時(shí)cache或者同時(shí)nocache就可以了
而arm9,則必須只能同時(shí)nocache 原因就是我倒數(shù)第三段所說(shuō)的別名的原因
作者: smalloc    時(shí)間: 2010-11-05 13:07
回復(fù) 9# duanius


    我還有點(diǎn)疑問(wèn).可否告知下,前面說(shuō)內(nèi)核中讀會(huì)出錯(cuò),大概錯(cuò)了多少字節(jié)?
另一個(gè)就是這個(gè)內(nèi)核讀是什么發(fā)動(dòng)的?在硬件中斷中?軟中斷中?內(nèi)核線程?還是本進(jìn)程的某個(gè)系統(tǒng)調(diào)用?
作者: duanius    時(shí)間: 2010-11-05 14:04
具體錯(cuò)多少字節(jié)沒(méi)算過(guò) 一個(gè)個(gè)數(shù)看著眼花。
這個(gè)一個(gè)屏驅(qū)動(dòng)的內(nèi)存 160行,如果錯(cuò)的話會(huì)錯(cuò)1到50行不等   一般十幾行。不是每次都錯(cuò),和讀時(shí)間間隔都有關(guān)。具體一行里面錯(cuò)多少字節(jié)就沒(méi)看了。
通過(guò)ioctl
作者: smalloc    時(shí)間: 2010-11-05 15:11
回復(fù) 11# duanius


    關(guān)于這個(gè)問(wèn)題我認(rèn)真想了下.有些疑問(wèn),實(shí)際隱隱感覺(jué)解釋不協(xié)調(diào).

下面慢慢寫(xiě)出來(lái).可能一次寫(xiě)不完整.

其總線監(jiān)聽(tīng)技術(shù)使當(dāng)某片被cache的內(nèi)存被其他請(qǐng)求操作時(shí)
------------
這個(gè)"其他"值得商討,比如是一個(gè)DMA設(shè)備。而不是cache自己.如果是從處理器端訪問(wèn),顯然必然先過(guò)問(wèn)或者不過(guò)問(wèn)cache但是都是一個(gè)內(nèi)部接口
我更相信他內(nèi)部能自己協(xié)調(diào)好

一些時(shí)候,比如進(jìn)程切換,必須通過(guò)flush整個(gè)cache獲得正確的內(nèi)存訪問(wèn)。
--------------
好象這個(gè)是TLB失效,不過(guò)也順便把數(shù)據(jù)的cache刷了。失效TLB的原因是每個(gè)進(jìn)程的頁(yè)表不一樣,而TLB卻分不出是哪個(gè)進(jìn)程,所以有多對(duì)1的情況。比如把一個(gè)進(jìn)程的一個(gè)表項(xiàng)當(dāng)作另一個(gè)進(jìn)程的---PPC可以區(qū)分,但linux沒(méi)利用.
作者: snail_314    時(shí)間: 2010-11-05 15:18
本帖最后由 snail_314 于 2010-11-05 15:20 編輯

flush tlb和flush cache是兩碼子事,flush cache有專(zhuān)門(mén)的指令,flsuh tlb時(shí)應(yīng)該不會(huì)順便去做flush cache的事。
x86上確實(shí)有snoop功能,不過(guò)就像ls所說(shuō),確實(shí)是掛在bus上的bus master之間做snoop,但是都在cpu內(nèi)部怕真沒(méi)有
作者: duanius    時(shí)間: 2010-11-05 15:25
回復(fù)  duanius


    關(guān)于這個(gè)問(wèn)題我認(rèn)真想了下.有些疑問(wèn),實(shí)際隱隱感覺(jué)解釋不協(xié)調(diào).

下面慢慢寫(xiě)出來(lái). ...
smalloc 發(fā)表于 2010-11-05 15:11


你說(shuō)的對(duì)  我這個(gè)說(shuō)法是錯(cuò)誤的。 我寫(xiě)這塊的時(shí)候沒(méi)仔細(xì)想,把它和dma時(shí)的一致性弄混淆了。x86應(yīng)該有些可以確保的機(jī)制但應(yīng)該就和總線沒(méi)啥關(guān)系了 我具體再去查查

至于tlb和cache,是兩碼事。雖然tlb本質(zhì)上也是cache,但是給mmu用的。這里沒(méi)有直接關(guān)系,有cache的系統(tǒng),也不一定有mmu阿
作者: Solaris12    時(shí)間: 2010-11-05 17:01
你說(shuō)的對(duì)  我這個(gè)說(shuō)法是錯(cuò)誤的。 我寫(xiě)這塊的時(shí)候沒(méi)仔細(xì)想,把它和dma時(shí)的一致性弄混淆了。x86應(yīng)該有些可以確保的機(jī)制但應(yīng)該就和總線沒(méi)啥關(guān)系了 我具體再去查查

至于tlb和cache,是兩碼事。雖然tlb本質(zhì)上也是cache,但是給mmu用的。這里沒(méi)有直接關(guān)系,有cache的系統(tǒng),也不一定有mmu阿



    1. 應(yīng)該是關(guān)聯(lián)的,你上面的例子里,如果用pci dma接口分配一個(gè)DMA  consistent 的內(nèi)存,然后再follow一個(gè)dma sync的調(diào)用,一樣可以解決問(wèn)題。

    2. VIVT的CPU切換上下文時(shí)可能需要flash cache和tlb,這個(gè)還是取決于cache的實(shí)現(xiàn)。
作者: duanius    時(shí)間: 2010-11-05 17:32
1. 應(yīng)該是關(guān)聯(lián)的,你上面的例子里,如果用pci dma接口分配一個(gè)DMA  consistent 的內(nèi)存,然后再fo ...
Solaris12 發(fā)表于 2010-11-05 17:01



   有關(guān)你所說(shuō)的1,你的意思是內(nèi)核和app共享的內(nèi)存是一個(gè)DMA  consistent內(nèi)存,誰(shuí)訪問(wèn)完后sync一下,以確保同步?
作者: smalloc    時(shí)間: 2010-11-05 18:16
回復(fù) 14# duanius


    可寫(xiě)的cache一般就2種write-through-WT和write-back-WB
但是不管哪種都保持對(duì)本處理器角度看和物理內(nèi)存是一致的。即當(dāng)你讀寫(xiě)數(shù)據(jù)時(shí)處理器指令感受不到cache存在。這也是一般cache實(shí)現(xiàn)的原則

。
然后在就上面說(shuō)的邏輯cache 物理cache和我可以誤解出來(lái)的"虛擬cache"-書(shū)已經(jīng)歸還無(wú)法查證--以及mmu 物理尋址來(lái)次大分類(lèi)。

先看ARMV5手冊(cè)B4.6最后一句:
Caches can be implemented with virtual or physical addressing, including indexing, provided these behaviors are met.

我對(duì)這句話的理解是:處理器可以先直接用虛擬地址尋址cache-估計(jì)這個(gè)就是你
說(shuō)的邏輯cache.
也可以通過(guò)mmu得到物理地址再在cache上尋址。這個(gè)就是統(tǒng)一的物理cache的說(shuō)法。
但是對(duì)于第一個(gè),cache關(guān)聯(lián)的虛擬內(nèi)存還是物理內(nèi)存?我想arm是物理內(nèi)存。
即當(dāng)WB-cache想把數(shù)據(jù)寫(xiě)入物理內(nèi)存的時(shí)候,他知道自己對(duì)的哪塊物理內(nèi)存,而不是再通過(guò)mmu去找一次物理內(nèi)存--而這個(gè)正是我之前所理解的

"虛擬cache",我想應(yīng)該沒(méi)有這樣實(shí)現(xiàn)的,因?yàn)樾屎艿,各個(gè)cache塊之間如果對(duì)的同一物理內(nèi)存要同步很麻煩,沒(méi)有自動(dòng)同步人工同步也很麻

煩。而且過(guò)分依賴(lài)MMU和頁(yè)表。一般不實(shí)現(xiàn)。

對(duì)于刷tlb和cache。假設(shè)是物理cache,我們切換進(jìn)程有必要去刷新cache嗎?我覺(jué)得有沒(méi)有MMU都不必要。而對(duì)于邏輯cache,因?yàn)橹苯油ㄟ^(guò)虛擬

地址去查找cache.換了tlb,這個(gè)cache大致也失效了,你可能在cache中由本進(jìn)程的虛擬地址找的是上一個(gè)進(jìn)程的物理地址的值。所以先寫(xiě)回

cache很正常。

再回到正題上,對(duì)于如上的邏輯cache,2個(gè)虛擬地址是不是能同時(shí)對(duì)應(yīng)2個(gè)cache數(shù)據(jù)塊-而這2個(gè)數(shù)據(jù)塊對(duì)應(yīng)同一個(gè)物理內(nèi)存塊?或者根本只有

一個(gè)cache內(nèi)存塊?
手冊(cè)B1.3開(kāi)頭。v6之前一個(gè)物理地址只能對(duì)應(yīng)一個(gè)虛擬地址。也就是說(shuō)如果是2個(gè)虛擬地址,應(yīng)該就是直接卸掉第一個(gè)。用第2個(gè).
v6之后應(yīng)該也是一個(gè)數(shù)據(jù)塊。---這個(gè)真沒(méi)看出來(lái)。待驗(yàn)證。
作者: smalloc    時(shí)間: 2010-11-05 19:38
回復(fù) 17# smalloc


    恩.上面最后一段錯(cuò)了 v6之前是
virtual indexing and virtual address tags
同時(shí)2個(gè)map是不可預(yù)料行為.
作者: duanius    時(shí)間: 2010-11-05 20:32
回復(fù) 18# smalloc


      有關(guān)你所說(shuō)的邏輯cache回寫(xiě)時(shí)是否通過(guò)mmu,因?yàn)檫@塊只牽涉到效率,不會(huì)像一致性問(wèn)題一樣干擾我的程序,所以我也沒(méi)去考慮過(guò),翻了翻也沒(méi)找到答案,不過(guò)簡(jiǎn)單的思考下,回寫(xiě)的時(shí)候找mmu也不是沒(méi)有可能。因?yàn)楫?dāng)讀未命中的時(shí)候,毫無(wú)疑問(wèn)會(huì)去找mmu,那么回寫(xiě)的時(shí)候卻去找物理內(nèi)存,可以這樣設(shè)計(jì)么?我不懂芯片,但我覺(jué)得如果你不要mmu都能找到物理內(nèi)存,你讀未命中的時(shí)候還找mmu干嘛?這不是多此一舉么。當(dāng)然這是我的猜測(cè),其實(shí)這塊當(dāng)時(shí)我不是很關(guān)心,是因?yàn)椴还芩趺丛O(shè)計(jì),我都無(wú)法做什么,我不需要要像知道cache的原理一樣把這里搞透。但cache的實(shí)現(xiàn)確實(shí)是會(huì)影響到不管是os還是app的。


    至于有關(guān)cache和tlb,就像我14樓說(shuō)的,沒(méi)有必要因?yàn)閮蓸佣伎梢阅脕?lái)“刷”,就放在一起綁定的說(shuō)。這兩個(gè)東西完全是分離的,各搞個(gè)的,沒(méi)啥關(guān)系。任務(wù)切換mmu內(nèi)容變了,tlb當(dāng)然要變,沒(méi)啥好說(shuō)的。cache刷不刷呢?邏輯要刷,物理隨便你,可刷可不刷。這完全看你os的實(shí)現(xiàn)。對(duì)于大cache,刷不劃算,還占任務(wù)切換的時(shí)間,但對(duì)于小cache,刷不刷我覺(jué)得是一樣的,因?yàn)榭隙ㄒ蛔x全是不命中,索性全invalid算了。這種情況下如果不是高實(shí)時(shí)性要求的系統(tǒng)這塊基本上都無(wú)所謂的,能差多少呢。所以沒(méi)必要兩個(gè)扯一起說(shuō),比如看這里http://en.wikipedia.org/wiki/ARM_architecture ,很多都是有cache沒(méi)mmu,所以討論cache的時(shí)候沒(méi)必要扯上tlb,如13樓所說(shuō)“flush tlb和flush cache是兩碼子事”,各自有各自的用途和指令,不搭嘎的。


    有關(guān)vivt的別名現(xiàn)象,應(yīng)該是這樣的了,你17樓提到“也就是說(shuō)如果是2個(gè)虛擬地址,應(yīng)該就是直接卸掉第一個(gè)。用第2個(gè).,真是讓我嚇了一跳,如果這樣我做的both cache訪問(wèn)的實(shí)驗(yàn)就沒(méi)法解釋了。應(yīng)該是18樓的。
作者: smalloc    時(shí)間: 2010-11-05 20:56
回復(fù) 19# duanius


    問(wèn)題是你一剛開(kāi)始就出錯(cuò),并不是2個(gè)都是cache的.和別名無(wú)關(guān)
作者: duanius    時(shí)間: 2010-11-05 21:02
回復(fù) 20# smalloc

一開(kāi)始?我確實(shí)最先嘗試的方式是一個(gè)cache一個(gè)非cache 因?yàn)槲矣玫氖莚emap_pfn_range來(lái)分配,但后面我也嘗試了采用應(yīng)用層cache的方式來(lái)試,還是不行,然后思考了下邏輯cache與物理cache的區(qū)別,才有了這篇文章。最后得出了在x86上,不關(guān)心cache,arm11上,要么同cache,要么同nocache,arm9上 只能同nocache的結(jié)論。我認(rèn)為理論上也應(yīng)該是正確的。
作者: smalloc    時(shí)間: 2010-11-05 21:06
回復(fù) 21# duanius


    我承認(rèn)還有一點(diǎn)不能確認(rèn).就是一個(gè)cache一個(gè)nocache為什么會(huì)不一致
我在找確著的證據(jù).
不能簡(jiǎn)單通過(guò)用加了flush來(lái)證明這一點(diǎn)
比如我相信是因?yàn)橹噶顏y序列造成的.而加flush不過(guò)是強(qiáng)制執(zhí)行序列而已---雖然這個(gè)可能性很小
作者: duanius    時(shí)間: 2010-11-05 21:14
回復(fù)  duanius


    我承認(rèn)還有一點(diǎn)不能確認(rèn).就是一個(gè)cache一個(gè)nocache為什么會(huì)不一致
我在找確著的證 ...
smalloc 發(fā)表于 2010-11-05 21:06



    這個(gè)是和體系結(jié)構(gòu)相關(guān)的啊  x86隨便你整 不管有沒(méi)有cache都不用care(如果沒(méi)記錯(cuò)的話) 人家拍胸脯擔(dān)保了
但arm手冊(cè)里面寫(xiě)明了一致性是需要你自己去care的,arm自己去刷cache只有一種情況,就是那一行要滾蛋,被換出了。所以比方說(shuō)兩邊同時(shí)寫(xiě),各寫(xiě)各的,cache行不被換出的話就是各自完各自的,誰(shuí)也不知道對(duì)方在干嗎。而且我認(rèn)為,比如內(nèi)核行cache一直有效,然后app拿了同樣一片內(nèi)存到cache或者直接訪問(wèn)內(nèi)存,內(nèi)核是不知道的,因?yàn)槲夷壳皼](méi)找到arm有任何機(jī)制確保它能知道。
作者: smalloc    時(shí)間: 2010-11-05 21:19
回復(fù) 23# duanius


    順便問(wèn)下.ARM只能看手冊(cè)嗎 有沒(méi) see mips run 那樣的中文書(shū)?
作者: duanius    時(shí)間: 2010-11-05 22:46
回復(fù) 24# smalloc


嵌入式系統(tǒng)開(kāi)發(fā)-軟件設(shè)計(jì)與優(yōu)化 這本書(shū) 應(yīng)該是經(jīng)典中的經(jīng)典吧
其實(shí)我覺(jué)得arm的體系結(jié)構(gòu)相對(duì)x86要簡(jiǎn)單很多 比起i32開(kāi)發(fā)者手冊(cè)n卷動(dòng)不動(dòng)就是上k頁(yè),arm的東西隨便翻翻一本書(shū)再看其他的都是雷同的了,而且內(nèi)部的機(jī)制也確實(shí)比x86簡(jiǎn)單
作者: smalloc    時(shí)間: 2010-11-05 23:41
本帖最后由 smalloc 于 2010-11-05 23:43 編輯

回復(fù) 25# duanius


    這本書(shū)真不錯(cuò),以前發(fā)了幾個(gè)帖子問(wèn).就是沒(méi)有人推薦過(guò)...

找到了一個(gè)困惑的地方.可以做下實(shí)驗(yàn):
思考原先的步驟:
剛開(kāi)始是
在mmap的時(shí)候指定了nocache的方式寫(xiě), 內(nèi)核讀帶cache的, 這個(gè)時(shí)候有問(wèn)題發(fā)生
然后
內(nèi)核讀取共享內(nèi)存時(shí)執(zhí)行flush_all_cache, 這樣就成功了.

如果按上面幾貼討論.假定應(yīng)用層肯定寫(xiě)到物理內(nèi)存了, 但是不影響cache

在內(nèi)核讀的時(shí)候.如果4K沒(méi)任何cache,那么讀都是未命中的.那么一定正確,不管刷不刷緩存

如果是循環(huán)執(zhí)行.
則這4K內(nèi)可能有一部分或全部已經(jīng)是cache
那么在第2次讀之前即使刷了緩存,也不能保證所有的物理內(nèi)存4K不被掩蓋.因?yàn)樗⒕彺媸菍⒕彺娴膬?nèi)容寫(xiě)入內(nèi)存 當(dāng)然前提是他們被修改了.
也就是說(shuō)還有可能會(huì)出錯(cuò).
也就是刷緩存后不能保證在緩存中再load的數(shù)據(jù)和 采用nocache寫(xiě)的數(shù)據(jù)保持一致.
作者: duanius    時(shí)間: 2010-11-06 11:40
其實(shí)我倒想起了一個(gè)實(shí)驗(yàn)  還是我原來(lái)的需求,用戶nocache寫(xiě),內(nèi)核cache讀。
一旦發(fā)現(xiàn)內(nèi)核讀的數(shù)據(jù)和用戶寫(xiě)的數(shù)據(jù)不一致,用戶就立刻停止寫(xiě)。
然后改為用戶讀。 過(guò)會(huì)用戶就會(huì)發(fā)現(xiàn)雖然內(nèi)核沒(méi)去寫(xiě),用戶也沒(méi)寫(xiě),但數(shù)據(jù)就變了,原因就是內(nèi)核cache的回寫(xiě)。我想應(yīng)該是這樣,不過(guò)懶得去試了。
作者: duanius    時(shí)間: 2010-11-06 11:48
本帖最后由 duanius 于 2010-11-06 12:02 編輯

回復(fù) 26# smalloc
你說(shuō)的一cahce 一nocache 然后flush一次也會(huì)出問(wèn)題  我想了想可能有這種可能性
不過(guò)對(duì)于內(nèi)核讀 app寫(xiě)  其實(shí)解決起來(lái)也簡(jiǎn)單  就是app寫(xiě)前flush  而不是寫(xiě)后flush  應(yīng)該就o了把
總之邏輯cache屁事多 只要?jiǎng)e名問(wèn)題解決不了  怎么都可能出問(wèn)題  如果用邏輯cache 還是老老實(shí)實(shí)的both nocache把
作者: smalloc    時(shí)間: 2010-11-06 11:51
回復(fù) 27# duanius


    這個(gè)挺麻煩.
你只要在內(nèi)核讀完再在內(nèi)核全部寫(xiě)不正確數(shù)據(jù),然后用戶再寫(xiě).循環(huán)執(zhí)行
就可以知道了.如果cache和寫(xiě)內(nèi)存不能同步,則刷緩存后必定會(huì)不是每次正確
作者: duanius    時(shí)間: 2010-11-06 12:17
回復(fù)  duanius


    這個(gè)挺麻煩.
你只要在內(nèi)核讀完再在內(nèi)核全部寫(xiě)不正確數(shù)據(jù),然后用戶再寫(xiě).循環(huán)執(zhí)行
...
smalloc 發(fā)表于 2010-11-06 11:51



28樓回復(fù)錯(cuò)了 重新編輯下
你這個(gè)也許行 但兩邊都寫(xiě) 還帶刷緩存 太復(fù)雜太亂了 我看的暈暈乎乎的  
其實(shí)我這個(gè)代碼實(shí)現(xiàn)很簡(jiǎn)單  而且邏輯也很清晰   內(nèi)核只是讀,不寫(xiě) 只有app寫(xiě)  居然都能把內(nèi)存改掉  這還不夠說(shuō)明問(wèn)題么?  別兩邊都寫(xiě) ,還帶flush,邏輯太復(fù)雜了。

這個(gè)問(wèn)題到這應(yīng)該就可以結(jié)束了,都通通透透的了
作者: smalloc    時(shí)間: 2010-11-06 13:20
本帖最后由 smalloc 于 2010-11-06 13:25 編輯

回復(fù) 28# duanius


    app寫(xiě)前flush而不是寫(xiě)后flush
這個(gè)有問(wèn)題,這要看flush到底做了什么.
如果是寫(xiě)回, 而cache內(nèi)容依然有效. 這樣可以驗(yàn)證不同步性
如果是寫(xiě)回, 且cache內(nèi)容失效. 則無(wú)法驗(yàn)證不同步性.因?yàn)橥交蛘卟煌? 讀總是對(duì)的.


我上面的不復(fù)雜.你僅僅需要在讀后直接用一個(gè)memset之類(lèi)函數(shù)的就可以了


我認(rèn)為沒(méi)結(jié)束,如果是同步的.則剛開(kāi)始解釋的flush_all后成功是緩存影響的解釋就不成立.而應(yīng)該有別的解釋
作者: smalloc    時(shí)間: 2010-11-06 13:47
回復(fù) 31# smalloc


    為什么我這么在意這個(gè).因?yàn)槲艺J(rèn)為這個(gè)不一致性違背了cache對(duì)處理器端隱藏的初衷.
而你前面的: x86隨便你整 不管有沒(méi)有cache都不用care(如果沒(méi)記錯(cuò)的話) 人家拍胸脯擔(dān)保了

這個(gè)care指的什么?如果不是我們上面待驗(yàn)證的不一致性,就應(yīng)該是指
"其總線監(jiān)聽(tīng)技術(shù)使當(dāng)某片被cache的內(nèi)存被其他請(qǐng)求操作時(shí)"

也許這2句是同一個(gè)意思.

如果ARM被驗(yàn)證是一致的.那么大多數(shù)時(shí)候我們就不必在不必要的地方care了

并且可能對(duì)于一個(gè)新的解釋中提到的地方要care.
作者: snail_314    時(shí)間: 2010-11-06 14:57
回復(fù) 32# smalloc


    說(shuō)x86不存在cache一致性有點(diǎn)過(guò)了.只限于通過(guò)pci bus訪問(wèn)memory時(shí)才會(huì)監(jiān)聽(tīng)哈.典型的反例就是顯卡訪問(wèn)顯存和cpu訪問(wèn)顯存,因?yàn)轱@卡訪問(wèn)顯存不通過(guò)pci的.
作者: smalloc    時(shí)間: 2010-11-06 19:51
回復(fù) 32# smalloc


    x86只是要求軟件不能這樣做,并沒(méi)有說(shuō)到實(shí)現(xiàn)效果.看來(lái)只能暫時(shí)相信不同步了.
3A 10.11.6
作者: Godbach    時(shí)間: 2011-02-11 16:28
多謝 smalloc 兄的提醒和建議,本帖加精。
smalloc 兄的評(píng)價(jià)如下:
我覺(jué)得這個(gè)帖子很重要 不僅說(shuō)明了虛實(shí)映射類(lèi)型 還說(shuō)明了多映射帶來(lái)的CACHE問(wèn)題 有很多隱含問(wèn)題可能都來(lái)源于此

作者: zhanglong71    時(shí)間: 2011-04-23 00:36
本帖最后由 zhanglong71 于 2011-04-23 00:45 編輯
“意味著對(duì)于我們的cpu(v5),當(dāng)應(yīng)用層用其地址空間的地址把共享區(qū)從內(nèi)存加到cache后,內(nèi)核同樣訪問(wèn)這片區(qū)域的時(shí)候,也可以按照其kmalloc分配的地址將同一片內(nèi)存中的數(shù)據(jù)加載到cache的另一行中,這就意味著一個(gè)內(nèi)存塊會(huì)有2個(gè)cache拷貝”


一個(gè)考慮問(wèn)題的方向,留個(gè)腳印。
作者: chishanmingshen    時(shí)間: 2013-03-26 07:16
本帖最后由 chishanmingshen 于 2013-03-26 09:59 編輯

回復(fù) 6# smalloc

這個(gè)地方寫(xiě)錯(cuò)了吧,“卻是讀cache”吧?

這里怎么理解啊,請(qǐng)指點(diǎn),謝謝。

另外,怎么最后又繞到了多映射的cache了?是說(shuō)app和內(nèi)核both cache的情況?

1樓提到的錯(cuò)誤產(chǎn)生的原因:

”所以有時(shí)候,某些加載共享內(nèi)存的cache塊沒(méi)有被替換,而相應(yīng)的內(nèi)存塊又被內(nèi)核加載到cache形成別名,錯(cuò)誤就自然產(chǎn)生了!

這里為何為何有多個(gè)映射的cache?一個(gè)是內(nèi)核的,一個(gè)是app的?

有點(diǎn)暈。。。
作者: blake326    時(shí)間: 2013-03-27 16:30
回復(fù) 1# duanius

這個(gè)是典型的dcache aliasing問(wèn)題。

考慮一個(gè)vipt的dcache, NumSets=256, Associativity=4, LineSize=32B,這樣每個(gè)way的大小是8KB,總大小是32KB。
假設(shè)現(xiàn)在kmalloc關(guān)聯(lián)到的一個(gè)page,并且mmap映射到了用戶空間,就是說(shuō)兩段地址x和y都映射到了這個(gè)page。那么x和y關(guān)聯(lián)到的numset號(hào)可能相同也可能不同,
相同的話沒(méi)有關(guān)系,如果不同的話就麻煩了,假設(shè)x關(guān)聯(lián)到numset 0,但是y關(guān)聯(lián)到numset 0 + 128(偏移4KB)。這樣,訪問(wèn)x和y的時(shí)候都會(huì)創(chuàng)建一個(gè)cache line,
但是互相不知道這種關(guān)系,這個(gè)問(wèn)題是一般是留給軟件來(lái)處理的。
很明顯的如果way<=4KB則不會(huì)出現(xiàn)alias問(wèn)題。

參考:http://72891.cn/forum.php?mod=viewthread&tid=1972593

不過(guò)在armv7中,dcache默認(rèn)是vipt noaliasing的,雖然它默認(rèn)way=8KB,硬件應(yīng)該自己處理好了。
參考:http://72891.cn/thread-4065587-1-1.html

不過(guò)你當(dāng)時(shí)用的arm應(yīng)該存在dcache alasing的問(wèn)題。

內(nèi)核中通過(guò)flush_dcache_page處理alias問(wèn)題的。
典型的場(chǎng)景,寫(xiě)文件,寫(xiě)page,調(diào)用flush_dcache_page,發(fā)現(xiàn)page被mmap用戶映射過(guò)了,然后處理alias。
參考:http://72891.cn/thread-4063721-1-1.html

   
   
   
作者: chishanmingshen    時(shí)間: 2013-03-27 20:39
本帖最后由 chishanmingshen 于 2013-03-27 21:04 編輯

回復(fù) 39# blake326


有道理,向你學(xué)習(xí)!
作者: blake326    時(shí)間: 2013-03-28 08:58
這個(gè)問(wèn)題不應(yīng)該叫cache一致性問(wèn)題吧。cache一致性一般指的是smp的cache一致性。
目前的問(wèn)題完全單cpu上出現(xiàn)的cache問(wèn)題。
參考:http://72891.cn/thread-4070329-1-1.html
作者: chishanmingshen    時(shí)間: 2013-03-28 09:32
回復(fù) 41# blake326

alias問(wèn)題我了解了。問(wèn)下,為何此帖說(shuō)使用nocache屬性還出問(wèn)題?

如果是一個(gè)用nocache,一個(gè)用cache,那么就沒(méi)有alias的問(wèn)題啊?


   
作者: blake326    時(shí)間: 2013-03-28 10:21
本帖最后由 blake326 于 2013-03-28 10:22 編輯

回復(fù) 42# chishanmingshen


    一個(gè)cache,一個(gè)nocache訪問(wèn)。nocache訪問(wèn)的都是真實(shí)的ddr。cache的訪問(wèn)的是cache。
  如果你寫(xiě)了cache,當(dāng)cache中的值沒(méi)有clean到ddr的時(shí)候,問(wèn)題不就來(lái)了嘛。
  如果nocache寫(xiě)了ddr。但是cache中的值沒(méi)有inv的話,問(wèn)題也來(lái)了。

  這個(gè)問(wèn)題跟磁盤(pán)驅(qū)動(dòng)要處理的,在交給dma讀寫(xiě)之前,必須要先clean或者inv一下相關(guān)的cache。
  
作者: chishanmingshen    時(shí)間: 2013-03-28 11:46
明白了,謝謝,看來(lái)還是x86舒服些。。。

回復(fù) 43# blake326


   
作者: image_z    時(shí)間: 2013-04-03 20:41
本帖最后由 image_z 于 2013-04-07 09:48 編輯
duanius 發(fā)表于 2010-11-04 21:47
這周碰到的一個(gè)問(wèn)題,在解決的過(guò)程中得到不少高手的熱心幫助,把一些總結(jié)貼出來(lái),歡迎大家指點(diǎn)。

寫(xiě)一個(gè) ...
好吧,我挖個(gè)墳,看看樓主還常來(lái)cu不?
應(yīng)用層讀取這片vma的時(shí)候是根據(jù)其指定的nocache屬性去讀內(nèi)存,而內(nèi)核訪問(wèn)kmalloc的時(shí)候卻是讀內(nèi)存(這里應(yīng)該是筆誤,原意是cache)。如何讓內(nèi)核也讀內(nèi)存呢,

樓主認(rèn)為kernel層,讀取內(nèi)存時(shí),讀到的是cache中的數(shù)據(jù)(多次讀取后,系統(tǒng)已cache了相關(guān)的數(shù)據(jù)),而內(nèi)存中真正的數(shù)據(jù)被應(yīng)用層更新掉了。
我的問(wèn)題是:為什么通過(guò)copy_to_user這類(lèi)函數(shù)進(jìn)行內(nèi)存數(shù)據(jù)的拷貝,內(nèi)核層面讀取kmalloc的內(nèi)存數(shù)據(jù)時(shí)(應(yīng)該也出現(xiàn)多次讀取,cache住相關(guān)內(nèi)存數(shù)據(jù)的情況),沒(méi)有出現(xiàn)這種情況,copy_to_user中有相關(guān)刷cache的操作嗎?
==============================================================
看了ls的帖子,是不是copy_to_user這類(lèi)函數(shù),會(huì)同時(shí)更新掉cache里的內(nèi)容。內(nèi)核讀kmalloc的內(nèi)存,直接讀的更新后的內(nèi)容。

作者: greatcode    時(shí)間: 2013-04-06 13:48
不需要吧,又不是mmap的內(nèi)存
作者: junnyg    時(shí)間: 2013-04-13 16:28
在這里例子里,我們是通過(guò)內(nèi)核和應(yīng)用都nocache的方式來(lái)進(jìn)行內(nèi)存共享的。那么雙方能不能通過(guò)cache的方式來(lái)訪問(wèn)呢?我們必須知道,有兩種cache:物理cache和邏輯cache,對(duì)于armv6以下的arm芯片,采用的是邏輯cache的方式,即cache在mmu之前,而armv6及以上的cpu,cache在mmu之后,cpu送出的要訪問(wèn)的地址先通過(guò)mmu進(jìn)行虛擬/物理的轉(zhuǎn)換,再送到cache。這意味著什么呢?意味著對(duì)于我們的cpu(v5),當(dāng)應(yīng)用層用其地址空間的地址把共享區(qū)從內(nèi)存加到cache后,內(nèi)核同樣訪問(wèn)這片區(qū)域的時(shí)候,也可以按照其kmalloc分配的地址將同一片內(nèi)存中的數(shù)據(jù)加載到cache的另一行中,這就意味著一個(gè)內(nèi)存塊會(huì)有2個(gè)cache拷貝,也就是傳說(shuō)中的別名。簡(jiǎn)單地說(shuō),如果你用arm11,由于使用物理cache,所以不會(huì)有問(wèn)題,而arm9的話,就很麻煩了。
----------------------
   從這段中學(xué)到了,以前只模糊知道arm的cache尋址是使用線性地址和物理地址一起匹配的,當(dāng)時(shí)使用的armV7架構(gòu),沒(méi)想到里面arm不同架構(gòu)區(qū)分這么精細(xì),多謝樓主指點(diǎn)!




歡迎光臨 Chinaunix (http://72891.cn/) Powered by Discuz! X3.2