免费注册 查看新帖 |

Chinaunix

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

[其他] 请教块设备驱动的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-24 12:20 |只看该作者 |倒序浏览
本帖最后由 fei1700 于 2013-07-09 21:21 编辑

大家好,我的sd卡驱动(未用linux自带的)是用的blk_init_queue,采用__make_request处理bio,然后发送request,建立线程处理request的做法。
以前设置的一次性最大传输长度是PAGE_SIZE,也就是4K,现在希望改成64k提高速度。
linux kernel是2.6.34

我在读写前加入xxx_queue_map_sg 将bio map到内部申请的bounce_buf中,卡底层读写用bounce_buf,然后读后调用xxx_queue_bounce_post,写前调用xxx_queue_bounce_pre,将连续内存bounce_buf的内容再copy回 bio中,这样似乎是绕过了req->buffer,因为本来__make_request传下来应该用req->buffer,但是这个buffer有时并不是连续的,但我认为在底层直接修改bio应该可行。但是实际应该是内容有错,所以运行数据有误,出现乱码打印,但并未提示别的错误。我猜应该是读写内容有错,类似打印提示符时打印出的乱码
在mount前用的是4k及4k以内的单位来读取,所以mount成功,此后用8k来读取数据在跨页时有问题。
[    4.010000]  xxx:RRR unknown partition table
[    4.030000] EXT2-fs (xxx): warning: mounting unchecked fs, running e2fsck is recommended
[    4.040000] VFS: Mounted root (ext2 filesystem) on device 254:0.
[    4.040000] Freeing init memory: 108K
[    4.040000] ;B#t}Odh!H0 8:b;ppd3
                                                                      :>1 $tuy8+c<9-;%$++)-3z1-3 88ab>fi|"0__g1-`TE80 0h004+g8+&fd)-0|:--|_8"-6+ !9++8"0-3

可能我的做法有问题,那么为什么不能在跨层直接修改bio?在__make_request中并未走到elv merge,一个request一次。io schedule是cfq,
所以init_request_from_bio应该只是把bio的page_address直接赋值给req->buffer

谢谢大家

论坛徽章:
0
2 [报告]
发表于 2010-08-26 09:38 |只看该作者
一定是我问问题的方法有问题,连打开这个帖子的人都很少
还是我自己说一下这个问题的情况

我如果把bouncesz从8K改成64k,就没这个现象了。搞得我问题都不好查了。

论坛徽章:
0
3 [报告]
发表于 2010-08-26 20:35 |只看该作者
本帖最后由 fei1700 于 2013-07-09 21:22 编辑

我在这个问题上好像困了3天了,好久了。
还是纠正一下我刚才说的现象,8k改成64k并不是没这个现象了,而是概率变小一些了。即使是8k也一直是概率出现。
打印乱码应该是执行init后出现了。原因我猜是由于部分数据不对造成。虽然应该只说现象,但是我还是想加上猜测

我现在这块板是ARM cortex A9在读写前必须清cache,以前我调的ARM板我一直没有这个印象。在dma_map_single里有调用outer_inv_range类的函数。除了card外,别的模块也是必须要加上才能正常读写数据,否则可能有错。后来我还看到网上有描述ARM V6,V7里的prefetch,不过我用的是2.6.34,代码已经跑的是这个了
ARM: dma-mapping: fix for speculative prefetching
http://kerneltrap.org/mailarchive/git-commits-head/2010/3/1/25335

我修改前是从bio到request的buffer传给card,最大request size是PAGE_SIZE,把这块buffer dma_map_single,能正常运行。这样用的buffer一直都是同一块

我加了sg_copy_from_buffer后中间存在一个buffer的copy,即使我把bounce size改成4k,也在一个PAGE_SIZE,同样会开机乱码,也就是读出来内容有错

我有用blk_rq_map_sg+dma_map_sg 来替代blk_rq_map_sg+dma_map_single+sg_copy_from_buffer,也都是mount成功后,文件系统提示错误,还没走到init

我有在xxx_queue_bounce_post中加入outer_inv_range,range是整个256M mem,虽然执行起来很花时间,但是还是mount成功,执行execute command这一步打印乱码,系统死掉。于是我的方向没了

谁能跟我分析一下?谢谢大家

论坛徽章:
0
4 [报告]
发表于 2010-08-26 21:08 |只看该作者
发完上面这个贴后,我就试了一下先把code退回到以前不用scatterlist

-  brq.crq.buf = req->buffer;
+ brq.crq.buf = cq->bounce_buf;

...
if(!brq.crq.cmd)
                        memcpy(req->buffer, cq->bounce_buf, brq.card_data.blk_nums*brq.card_data.blk_size);

完全不用scatterlist。只是把req->buffer经过bounce_buf中转一下,也出现问题了。
差别只有2句,(1)没问题,(2)有问题

论坛徽章:
0
5 [报告]
发表于 2010-08-26 21:10 |只看该作者
我好像只是按了tab还是caps lock和空格好像就发帖了 -_-

-  brq.crq.buf = req->buffer;
+ brq.crq.buf = cq->bounce_buf;

...
+ if(!brq.crq.cmd)
+                       memcpy(req->buffer, cq->bounce_buf, brq.card_data.blk_nums*brq.card_data.blk_size);

这样改就会出开机乱码的现象

论坛徽章:
0
6 [报告]
发表于 2010-08-27 22:57 |只看该作者
参考网上另一个人的相似现象作修改:
regarding dma_inv_range on cortex A9 SMP core....
http://www.spinics.net/linux/lists/arm-kernel/msg71314.html
及这个网页上链接的另一个现象:
http://lkml.org/lkml/2009/6/18/100

做下面的修改后,概率降为4%(试了50次,出现2次)

--- arch/arm/mm/dma-mapping.c   (revision 169)
+++ arch/arm/mm/dma-mapping.c   (working copy)
@@ -401,6 +401,7 @@
  * platforms with CONFIG_DMABOUNCE.
  * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
  */
+extern void v7_flush_kern_cache_all(void);
void ___dma_single_cpu_to_dev(const void *kaddr, size_t size,
        enum dma_data_direction dir)
{
@@ -408,6 +409,7 @@

        BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));

+       v7_flush_kern_cache_all();
        dmac_map_area(kaddr, size, dir);

        paddr = __pa(kaddr);


ARM cortex A9 2.6.34

我都自己做板凳到第5楼了,也没人给点建议

论坛徽章:
0
7 [报告]
发表于 2010-08-29 17:59 |只看该作者
大概参考了下面几个网页,为了只修改card模块,不对别的模块有影响,我最后在sg_copy_from_buffer后面加上了bio_flush_dcache_pages(cq->req->bio);

Re: MPCore SMP Linux : should all dcaches be invalidated after handling prefetch abort ?
http://article.gmane.org/gmane.linux.ports.arm.kernel/51556

regarding dma_inv_range on cortex A9 SMP core....
http://www.spinics.net/linux/lists/arm-kernel/msg71314.html

USB mass storage and ARM cache coherency
http://lkml.org/lkml/2010/1/29/151

Rootfs in eMMC: Kernel panic ...Attempted to kill init!
http://lkml.org/lkml/2009/6/18/100

论坛徽章:
0
8 [报告]
发表于 2011-03-23 07:42 |只看该作者
高处不甚寒啊。兄弟你走的路,太强大了。哈哈……

论坛徽章:
0
9 [报告]
发表于 2011-03-23 14:16 |只看该作者
回复 7# fei1700


    哥们你的帖子弄的太乱了,整理一下,大家读起来方便
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP