Linux内核开发之异步通知与异步I/O(五)
2010-10-24 10:44
302 查看
“小王呢,今天开始讲AIO与设备驱动,这也是设备驱动通知与异步IO的最后一节了,下次咱们就要开始讲更高级的东西,比如中断啦,时钟等”
在Linux内核中,每个IO请求都对应一个kiocb结构体,其ki_filp成员指向对应的file指针,通过is_sync_kiocb可以判断某Kiocb时候为同步IO请求,如果非真,表示是异步IO请求。
块设备和网络设备本身就是异步的。只有字符设备驱动必须明确指出应支持AIO.需要说明的是AIO对于大多数字符设备而言都不是必须的。只有少数才需要。
在字符设备驱动程序中,file_operations包含了3个和AIO相关的函数。如下:
在Linux内核中,每个IO请求都对应一个kiocb结构体,其ki_filp成员指向对应的file指针,通过is_sync_kiocb可以判断某Kiocb时候为同步IO请求,如果非真,表示是异步IO请求。
块设备和网络设备本身就是异步的。只有字符设备驱动必须明确指出应支持AIO.需要说明的是AIO对于大多数字符设备而言都不是必须的。只有少数才需要。
在字符设备驱动程序中,file_operations包含了3个和AIO相关的函数。如下:
ssize_t(*aio_read)(structkiocb*iocb,char*buffer,size_tcount,loff_toffset); ssize_t(*aio_write)(structkiocb*iocb,constchar*buffer,size_tcount,loff_toffset); int(*aio_fsync)(structkiocb*iocb,intdatasync);
aio_read()和aio_write()与file_operation中的read()和write()中的offset参数不同,它直接传递值,而后者传递的是指针。这两个函数本身也不一定完成读写操作,它只是发起,初始化读写操作。
下面来看看实际的代码部分:
//异步读 staticssize_txxx_aio_read(structkiocb*iocb,char*buffer,size_tcount,loff_toffset) { returnxxx_defer_op(0,iocb,buf,count,pos); } //异步写 staticssize_txxx_aio_write(structkiocb*iocb,constchar*buffer,size_tcount,loff_toffset) { returnxxx_defer_op(1,iocb,(char*)buf,count,pos); } //初始化异步IO staticintxxx_defer_op(intwrite,structkiocb*iocb,char*buf,size_tcount,loff_tpos) { structasync_work*async_wk; intresult; //当可以访问buffer时进行复制 if(write) { result=xxx_write(iocb->ki_filp,buf,count,&pos); } else { result=xxx_read(iocb->ki_filp,buf,count,&pos); } //如果是同步IOCB,立即返回状态 if(is_sync_kiocb(iocb)) returnresutl; //否则,推后几us执行 async_wk=kmalloc(sizeof(*async_wk),GFP_KERNEL)); if(async_wk==NULL) returnresult; async_wk->aiocb=iocb; async_wk->result=result; INIT_WORK(&async_wk->work,xxx_do_deferred_op,async_wk); schedule_delayed_work(&async_wk->work,HZ/100); return-EIOCBOUEUED;//控制权限返回给用户空间 } //延迟后执行 staticvoidxxx_do_deferred_op(void*p) { structasync_work*async_wk=(structasync_work*)p; aio_complete(async_wk_iocb,async_wk->result,0); kfree(async_wk); }在上述代码中有一个async_work的结构体定义如下:
structasync_work { structkiocb*iocb;//kiocb结构体指针 intresult;//执行结果 structwork_structwork;//工作结构体 };
在上边代码中最核心的是使用aync_work结构体将操作延迟,通过schedule_delayed_work可以调度其运行,而aio_complete的调用用于通知内核驱动程序已经完成了操作。
最后,这一大章的内容都讲完了,一连5节,小王,你好好整理整理,下次就要开始新的内容了。
相关文章推荐
- Linux内核开发之异步通知与异步I/O(一)
- Linux内核开发之异步通知与异步I/O(三)
- Linux内核开发之异步通知与异步I/O《来自linux设备开发详解》
- Linux内核开发之异步通知与异步I/O(一)
- Linux内核开发之异步通知与异步I/O(一)
- Linux内核开发之异步通知与异步I/O(二)
- Linux内核开发之异步通知与异步I/O(一)
- Linux内核开发之异步通知与异步I/O(一)
- Hasen的linux设备驱动开发学习之旅--异步通知
- Linux内核开发之异步通知与异步I/O(三)
- Linux内核的异步通知
- Linux内核异步通知
- Linux内核开发之异步通知与异步I/O(四)
- Linux内核中断引入用户空间(异步通知机制)
- Linux内核开发之异步通知与异步I/O_fcntl
- Linux内核开发之异步通知与异步I/O(三)
- Linux内核开发之异步通知与异步I/O(五)
- Linux设备驱动开发详解--笔记9--异步通知与异步I/O
- Linux内核开发之异步通知与异步I/O(二)
- linux内核开发总结----内核同步与异步