Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using select()/poll() in device driver

I have a driver, which handles several TCP connections.

Is there a way to perform something similar to user space application api's select/poll()/epoll() in kernel given a list of struct sock's?

Thanks

like image 394
dimba Avatar asked Dec 02 '14 12:12

dimba


People also ask

For what are poll and select used?

poll and select have essentially the same functionality: both allow a process to determine whether it can read from or write to one or more open files without blocking. They are thus often used in applications that must use multiple input or output streams without blocking on any one of them.

What is poll and select?

select() only uses (at maximum) three bits of data per file descriptor, while poll() typically uses 64 bits per file descriptor. In each syscall invoke poll() thus needs to copy a lot more over to kernel space.

How poll works in Linux?

When poll() is called for some file descriptor, the corresponding device poll_xyx() method registered with file operation structure is invoked in kernel space. This method then checks if the data is readily available, if this condition is true then the event mask is set and the poll returns to user space.

What is polling in kernel?

Instead polling device drivers use system timers to have the kernel call a routine within the device driver at some later time. This timer routine would check the status of the command and this is exactly how Linux's floppy driver works.


2 Answers

You may want to write your own custom sk_buff handler, which calls the kernel_select() that tries to lock the semaphore and does a blocking wait when the socket is open.

Not sure if you have already gone through this link Simulate effect of select() and poll() in kernel socket programming

like image 110
askb Avatar answered Oct 08 '22 13:10

askb


On the kernel side it's easy to avoid using sys_epoll() interface outright. After all, you've got a direct access to kernel objects, no need to jump through hoops.

Each file object, sockets included, "overrides" a poll method in its file_operations "vtable". You can simply loop around all your sockets, calling ->poll() on each of them and yielding periodically or when there's no data available.

If the sockets are fairly high traffic, you won't need anything more than this.

A note on the API:

poll() method requires a poll_table() argument, however if you do not intend to wait on it, it can safely be initialized to null:

poll_table pt;
init_poll_funcptr(&pt, NULL);
...
// struct socket *sk;
...
unsigned event_mask = sk->ops->poll(sk->file, sk, &pt);

If you do want to wait, just play around with the callback set into poll_table by init_poll_funcptr().

like image 38
oakad Avatar answered Oct 08 '22 12:10

oakad