void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt) { lockdep_assert_held(&ctx->wqh.lock); *cnt = ((ctx->flags & EFD_SEMAPHORE) && ctx->count) ? 1 : ctx->count; ctx->count -= *cnt;//清零 } EXPORT_SYMBOL_GPL(eventfd_ctx_do_read); eventfd_write static ssize_t...
void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt); DECLARE_PER_CPU(int, eventfd_wake_count); @@ -82,6 +83,11 @@ static inline bool eventfd_signal_count(void) return false; } static inline void eventfd_ctx_do_read(struct eventfd_ctx *ctx, __u64 *cnt) { } #endif...
eventfd_ctx_do_read(ctx, &ucnt); if (waitqueue_active(&ctx->wqh)) // 判断可写事件是否存在,有即将激活ctx->wqh中的可写事件 wake_up_locked_poll(&ctx->wqh, EPOLLOUT); spin_unlock_irq(&ctx->wqh.lock); // copy内核ucnt到用户空间to if (unlikely(copy_to_iter(&ucnt, sizeof(ucnt)...
}if(likely(res ==0)) {/*read fdcount again*/eventfd_ctx_do_read(ctx, cnt);/**/if(waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, POLLOUT); } spin_unlock_irq(&ctx->wqh.lock);returnres; } 该函数比较长,我们慢慢分析,首先操作eventfd_ctx要加锁保证安全。起初res初始化...
内核支持两个版本的eventfd函数,eventfd2是支持直接设置一些flags而不需要再额外调用其他函数。count是一个初始化值,一会我们会看到他的作用,接下来我们看do_eventfd。 代码语言:javascript 代码运行次数:0 运行 AI代码解释 staticintdo_eventfd(unsigned int count,int flags){struct eventfd_ctx*ctx;struct file*file...
eventfd_read(2), read(2), eventfd_write(2), write(2) staticssize_teventfd_read(structfile *file,char__user *buf,size_tcount,loff_t*ppos){structeventfd_ctx*ctx=file->private_data;// 将 eventfd 结构从文件的私有数据中取出来ssize_tres; ...
do_eventfd主要是创建了一个eventfd_ctx结构体并初始化。我看看这个结构体。 structeventfd_ctx{ structkrefkref;wait_queue_head_t wqh;__u64 count;unsignedintflags; intid; }; 创建完结构体后,主要的逻辑是适配文件系统,首先申请了fd和file并关联起来,然后把file和eventfd_ctx关联起来,这样后续操作fd的时候,...
用户态通知内核态稍微麻烦一点首先需要再创建一个eventfd然后下发给fileprivatedata这里的操作同上面额外需要在模块里做一个iotcl专门负责用户态来通知内核态函数里就做eventfdsignal内核态线程需要先放在eventfdctxwqh上可以利用vfsread或者自己在内核态做一次poll似乎又麻烦了...
当内核态想通知用户态时,直接使用eventfd_signal,此时用户态线程需要先把自己放在eventfd_ctx->wqh上,有两种方案,一个是调用read,一个是调用poll。 如果是read,之后会将eventfd_ctx->count清零,下次还能阻塞住。但是如果使用poll,之后count并未清零,导致再次poll时,即使内核态没有eventfd_signal,poll也会即时返回。
eventfd_ctx_do_read(ctx, cnt); if (waitqueue_active(&ctx->wqh)) wake_up_locked_poll(&ctx->wqh, POLLOUT); } spin_unlock_irq(&ctx->wqh.lock); if (res > 0 && put_user(ucnt, (__u64 __user *) buf)) return -EFAULT;return res; ...