代码版本linux-3.16.37-git, qemu-v2.8-git

因为eventfd要与epoll配合使用,不清楚epoll的请参考epoll的linux内核工作机制

一. Eventfd在QEMU下的使用

Eventfd在QEMU下的使用以这三个函数为基础:event_notifier_init和event_notifier_get_fd,以及event_notifier_set_handler。
在event_notifier_init中,初始化EventNotifier:

ret即是此次的fd的值,man手册中有对应的介绍:
eventfd() creates an "eventfd object" that can be used as an event wait/notify mechanism by user-space applications, and by the
kernel to notify user-space applications of events. The object contains an unsigned 64-bit integer (uint64_t) counter that is
maintained by the kernel. This counter is initialized with the value specified in the argument initval.

而event_notifier_get_fd就是返回EventNotifier fd值而已。

event_notifier_set_handler则是将handler挂到AIO线程上,

在aio_set_fd_handler下,每个AIO的调度单元是以node形式存在,

在aio_epoll_update中,AioContext下的epoll_enabled被置1,获取ctl的值,然后将node->pfd.fd即eventfd加入epoll队列:

然后使用aio_notify通知AIO进行调度,而AioContext的通知功能本质上又是一个eventfd直接在userspace的应用,下面再提:

看一下eventfd调用的过程:

iothread初始化过程中调用了iothread_complete,创建了iothread_run线程

只要AIO thread没有被停掉,线程就会一直被epoll

在aio_poll下,

在aio_epoll下,完成对event事件的调度

此处只是将node进行了设置,但是仍然没有进行真正的调度执行,真正的执行是在aio_dispatch下的

回头看一下aio_notify的eventfd的使用,在aio_context_new下,

ret = event_notifier_init(&ctx->notifier, false);

即给eventfd写入了新值。

aio_notify_accept则负责接收它,表示自己已经收到对应的通知并完成处理。

len = read(e->rfd, buffer, sizeof(buffer));

 

二. Eventfd在kernel下的机制

SYSCALL_DEFINE2(eventfd2, unsigned int, count, int, flags)创建eventfd.

在eventfd_file_create中,其中

注释对count的意义说清楚了.

anon_inode_getfile获取匿名fd,重点在file->private_data = priv;另外还有eventfd_fops

用户态对eventfd的控制是通过上面两个控制的,而kernel对userspace则是eventfd_signal


QEMU下的eventfd机制及源代码分析来自于OenHan

链接为:http://oenhan.com/qemu-eventfd-kvm

2 对 “QEMU下的eventfd机制及源代码分析”的想法;

  1. 博主你好,非常感谢你的分享,对我有很大启发,发现两个问题想跟你交流下:
    1. qemu用了glib的的一些api,在函数aio_set_fd_handler中调用了g_source_add_poll,查看API后发现这个函数是添加GPollFD到GSource中。
    Adds a file descriptor to the set of file descriptors polled for this source
    2. aio_epoll_update—>epoll_ctl(ctx->epollfd, ctl, node->pfd.fd, &event);只是将事件event和node->pfd.fd关联起来。
    以上两点是想跟你确认,我的理解是否正确?

    另外:qemu的这种做法,是将glib与epoll结合起来用么?如果单用其中一种是否也可以完成eventfd的机制。

    1. @HEAVY 这两点是这么理解的。eventfd机制上比较容易实现,只要有线程轮询它即可,其中任何一种都可以实现。epoll和eventfd是非常契合的配置,GMainLoop应该是比较容易控制流程。

发表评论