免费注册 查看新帖 |

Chinaunix

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

请教 在读写回调(end_io)中如何使用memcpy [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-27 16:23 |只看该作者 |倒序浏览
我需要在读写回调函数(read_end_io/write_end_io)中进行页数据拷贝,而且目标页(topage)是刚刚alloc_page()的。

我们经常看到驱动层对memcpy是这样使用的:
memcpy(kmap(formpage, kmap(topage), len);
kunmap(frompage);
kunmap(topage);
这让我感觉memcpy必须使用映射过的虚地址进行拷贝。但是kunmap不能使用在中断程序中,所以我很困惑在读写回调(read_end_io/write_end_io)中如何使用memcpy进行页数据拷贝。

我的问题是下面两个:
1.在读写回调(read_end_io/write_end_io)中怎样进行页数据拷贝,使用memcpy或者替代方法都可以。(也许可以使用kmap_atomic和kunmap_atomic??)
2.memcpy必须使用映射过的内存虚地址吗,能否解释一下。

对回答者先表示感谢!

论坛徽章:
0
2 [报告]
发表于 2008-10-04 15:51 |只看该作者

回复 #1 jjjjffff 的帖子

1:在读写回调(read_end_io/write_end_io)中怎样进行页数据拷贝?
在读写回调中进行数据拷贝与其他的地方拷贝没什么不同,只不过读写回调是处在中断中而已。


2:memcpy使用虚拟地址,这是肯定的,也是必须的。

alloc_page返回的是struct page*, 由页指针要转换到虚拟地址,这里面涉及到:低端内存和高端内存这一知识点。
如果该页指针对应的是低端内存页框,则使用page_address(page)即可将page->虚拟地址。
如果。。。。。。。。高端内存页框, 由于高端内存页框并不映射在内核线性地址空间的第4个GB上,因此内核不能直接访问他们,所以这时就需要建立映射了。
有两种方式:永久映射(使用函数:kmap,kunmap); 临时映射(kmap_atomic,kunmap_atomic)
kmap的实现:
void *kmap(struct page *page)
{
        might_sleep();
        if (!PageHighMem(page))
                return page_address(page);
        return kmap_high(page);
}

其中:永久映射是可能被阻塞的,所以不能用在中断中,而临时映射可以用在中断中。

论坛徽章:
0
3 [报告]
发表于 2008-10-06 09:50 |只看该作者

回复 #2 todaygood 的帖子

感谢你的详细解释。
其实就是因为在中断中不能使用kunmap,
因为换成kunmap_atomic还有问题,所以还在调查中。

论坛徽章:
0
4 [报告]
发表于 2008-10-06 22:37 |只看该作者

回复 #3 jjjjffff 的帖子

什么问题?什么问题?什么问题?

论坛徽章:
0
5 [报告]
发表于 2008-10-07 09:25 |只看该作者

回复 #4 todaygood 的帖子

谢谢。
就是驱动层panic。
其实我最先想到的也是kunmap_atomic。
由于panic位置还没有确认,所以......

[ 本帖最后由 jjjjffff 于 2008-10-7 11:13 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP