在内核套接字编程中模拟select()和poll()的效果

我正在开发的一个Linux内核驱动程序是在内核中使用networking通信( sock_create()sock->ops->bind()等)。

问题是会有多个套接字接收数据。 所以我需要在内核空间中模拟select()poll() 。 由于这些函数使用文件描述符,除非我使用系统调用来创build套接字,否则我不能使用系统调用,但是由于我在内核中工作,这似乎没有必要。

所以我想在我自己的处理程序( custom_sk_data_ready() )中包装默认的sock->sk_data_ready处理程序,这将解锁信号量。 然后,我可以编写我自己的kernel_select()函数,试图locking信号量并进行阻塞,直到它打开。 这样内核函数进入hibernate状态,直到信号量被custom_sk_data_ready()解锁。 一旦kernel_select()获得locking,它将解锁并调用custom_sk_data_ready()来重新locking它。 所以唯一额外的初始化是在绑定套接字之前运行custom_sk_data_ready() ,所以第一次调用custom_select()不会错误地触发。

我看到一个可能的问题。 如果发生多个接收,则多次调用custom_sk_data_ready()将尝试解锁信号量。 所以为了不丢失多个调用并跟踪正在使用的sock ,必须有一个表或指向正在使用的套接字的指针列表。 而custom_sk_data_ready()将不得不在表/列表中标记它传递的套接字。

这种方法听起来吗? 或者,当我使用标准的系统调用时,我应该努力解决用户/内核空间问题?

初始发现:

在中断上下文中调用sock结构中的所有callback函数。 这意味着他们无法入睡。 为了允许主内核线程在就绪套接字列表上hibernate,使用了互斥锁,但是custom_sk_data_ready()必须像互斥锁一样在互斥mutex_trylock()重复(调用mutex_trylock() )。 这也意味着任何dynamic分配都必须使用GFP_ATOMIC标志。


附加可能性:

对于每个打开的套接字,将每个套接字的sk_data_ready()replace为一个自定义的( custom_sk_data_ready() ),并创build一个worker( struct work_struct )和工作队列( struct workqueue_struct )。 一个普通的process_msg()函数将被用于每个worker。 创build一个内核模块级别的全局列表,其中每个列表元素都有一个指向套接字的指针并包含worker结构。 当数据在套接字上准备就绪时, custom_sk_data_ready()将执行并find具有相同套接字的匹配列表元素,然后使用list元素的工作队列和worker调用queue_work() 。 然后process_msg()函数将被调用,并且可以通过struct work_struct *参数(一个地址)的内容find匹配的list元素,或者使用container_of()macros来获取包含该列表结构的地址工人结构。

哪种技术最有声音?

Solutions Collecting From Web of "在内核套接字编程中模拟select()和poll()的效果"