免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2095 | 回复: 6
打印 上一主题 下一主题

[CPU及多核] flush_pfn_alias(), cache alias问题。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-06-30 13:32 |只看该作者 |倒序浏览
cache alias:
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=1972593

cache一般有几种类型:
pipt
vivt
vipt noalias
vipt alias

实际上armv7 的dcache是vipt noalias的。icache是vipt alias的。
为什么会有cache alias问题呢,为什么amv7 dcache又没有呢,这是armv7 硬件能够自动处理dcache alias问题。

一个cache由 cache line size * num set * way 组成。
一般是 32 * 256 * 4 = 32KB.
如果line size * num set = 8KB大于page size的话那么就有可能有alias问题。
假设0xf000 0000和0xf000 1000两段地址都是映射同一个page的话,那么访问0xf000 0000和0xf000 1000时,他们在cache中的num是不同的,就是有各自的cache line,但是映射的物理地址是一样的。如果硬件不能自动处理的话,软件一定要处理好。
现在假设dcache是vipt alias的话,文件系统写一个page cache时,由于用户态可能映射了该page,所以会调用flush_dcache_page()来解决这个alias问题。
最终会调用到flush_pfn_alias(),不过这个代码看不懂,请高人帮忙分析下。


void flush_dcache_page(struct page *page)
{
        struct address_space *mapping;

        /*
         * The zero page is never written to, so never has any dirty
         * cache lines, and therefore never needs to be flushed.
         */
        if (page == ZERO_PAGE(0))
                return;

        mapping = page_mapping(page);

        if (!cache_ops_need_broadcast() &&
            mapping && !mapping_mapped(mapping))
                clear_bit(PG_dcache_clean, &page->flags);
        else {
                __flush_dcache_page(mapping, page);
                if (mapping && cache_is_vivt())
                        __flush_dcache_aliases(mapping, page);
                else if (mapping)
                        __flush_icache_all();
                set_bit(PG_dcache_clean, &page->flags);
        }
}


void __flush_dcache_page(struct address_space *mapping, struct page *page)
{
        /*
         * Writeback any data associated with the kernel mapping of this
         * page.  This ensures that data in the physical page is mutually
         * coherent with the kernels mapping.
         */
        if (!PageHighMem(page)) {
                __cpuc_flush_dcache_area(page_address(page), PAGE_SIZE);
        } else {
                void *addr = kmap_high_get(page);
                if (addr) {
                        __cpuc_flush_dcache_area(addr, PAGE_SIZE);
                        kunmap_high(page);
                } else if (cache_is_vipt()) {
                        /* unmapped pages might still be cached */
                        addr = kmap_atomic(page);
                        __cpuc_flush_dcache_area(addr, PAGE_SIZE);
                        kunmap_atomic(addr);
                }
        }

        /*
         * If this is a page cache page, and we have an aliasing VIPT cache,
         * we only need to do one flush - which would be at the relevant
         * userspace colour, which is congruent with page->index.
         */
        if (mapping && cache_is_vipt_aliasing())
                flush_pfn_alias(page_to_pfn(page),
                                page->index << PAGE_CACHE_SHIFT);
}



#define ALIAS_FLUSH_START        0xffff4000
//这个函数这个地址不知道什么意思?
static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr)
{
        unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT);
        const int zero = 0;

        set_pte_ext(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL), 0);
        flush_tlb_kernel_page(to);

        asm(        "mcrr        p15, 0, %1, %0, c14\n"
        "        mcr        p15, 0, %2, c7, c10, 4"
            :
            : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero)
            : "cc");
}

论坛徽章:
0
2 [报告]
发表于 2014-07-01 09:17 |只看该作者
ding
ding
ding

论坛徽章:
0
3 [报告]
发表于 2014-07-02 09:12 |只看该作者
在ding一下看看。。。

论坛徽章:
0
4 [报告]
发表于 2014-07-02 18:58 |只看该作者
看起来没人知道。还是论坛档次太低了

论坛徽章:
4
戌狗
日期:2013-08-15 18:22:43技术图书徽章
日期:2013-08-21 13:48:45巨蟹座
日期:2013-09-26 17:06:39处女座
日期:2013-12-25 11:26:10
5 [报告]
发表于 2014-07-03 13:22 |只看该作者
blake326 发表于 2014-07-02 18:58
看起来没人知道。还是论坛档次太低了


这个只能怪你不是女的

你要是个美女的话,早有人告诉你了。而且最好是去你家言传身教啊

论坛徽章:
22
丑牛
日期:2014-08-15 14:32:0015-16赛季CBA联赛之同曦
日期:2017-12-14 15:28:14黑曼巴
日期:2017-08-10 08:14:342017金鸡报晓
日期:2017-02-08 10:39:42黑曼巴
日期:2016-11-15 15:48:38CU十四周年纪念徽章
日期:2016-11-09 13:19:1015-16赛季CBA联赛之同曦
日期:2016-04-08 18:00:03平安夜徽章
日期:2015-12-26 00:06:30程序设计版块每日发帖之星
日期:2015-12-03 06:20:002015七夕节徽章
日期:2015-08-21 11:06:17IT运维版块每日发帖之星
日期:2015-08-09 06:20:002015亚冠之吉达阿赫利
日期:2015-07-03 08:39:42
6 [报告]
发表于 2014-07-03 14:11 |只看该作者
本帖最后由 amarant 于 2014-07-03 14:33 编辑

不是没人知道,很多人知道。
一来,人不愿看你的帖子,这么长,都是代码
二来,大家都很忙,整天解bug,看看论坛也希望看看轻松愉快的


ALIAS_FLUSH_START 这个地址随便填,因为以他作为开始地址往上刷cache size大小后,就可以全刷。而填一个偏移,就能刷指定行的cache

论坛徽章:
0
7 [报告]
发表于 2014-07-03 16:36 |只看该作者
回复 6# amarant

講的不錯

其實flush_pfn_alias()就是一個關鍵

樓主你可以試者去兜起來

1. to 就是解決alias的新VA
2. 13,14bit 就是靠這兩個去把那同一個color放在一起  <-- CACHE_COLOUR(vaddr)
3. mcrr   p15,,,,c14 目的就是flush to這個VA
4. mcr p15, 0,c7, c10, 4 就是做 DSB


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP