Simulate effect of select() and poll() in kernel socket programming
Your second idea sounds more like it will work.
The CEPH code looks like it does something similar, see net/ceph/messenger.c
.
Using select()/poll() in device driver
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
When you call select(2) how does the kernel figure out a socket is ready?
https://eklitzke.org/how-tcp-sockets-work answered my question
When a new data packet comes in on the network interface (NIC), the kernel is notified either by being interrupted by the NIC, or by polling the NIC for data. Typically whether the kernel is interrupt driven or in polling mode depends on how much network traffic is happening; when the NIC is very busy it’s more efficient for the kernel to poll, but if the NIC is not busy CPU cycles and power can be saved by using interrupts. Linux calls this technique NAPI, literally “New API”.
When the kernel gets a packet from the NIC it decodes the packet and figures out what TCP connection the packet is associated with based on the source IP, source port, destination IP, and destination port. This information is used to look up the struct sock in memory associated with that connection. Assuming the packet is in sequence, the data payload is then copied into the socket’s receive buffer. At this point the kernel will wake up any processes doing a blocking read(2), or that are using an I/O multiplexing system call like select(2) or epoll_wait(2) to wait on the socket.
select/poll and one write buffer
This is a type of race condition and is not unique to your device. The application must be prepared for this eventuality. That is, just because select returns a file descriptor as being writable (or readable or whatever) does not guarantee that a subsequent system call on the file will not block.
The usual way of handling this is to open the file descriptor in non-blocking mode (O_NONBLOCK or O_NDELAY). Then when the situation you described happens, UserA will get a write error (with errno EWOULDBLOCK/EAGAIN), and should then return to select to await the device becoming writable again.
How can you generate a POLLPRI event on a regular file?
It looks like you can achieve this by polling a sysctl exposed in procfs. If you look at the poll implementation in procfs for the sys
subdirectory, you'll see that any sysctl that implements notifications for poll will return a mask that includes POLLERR|POLLPRI
. So how do we figure out what sysctls implement this? We look for uses of proc_sys_poll_notify
!
One such place is in proc_do_uts_string
, which implements a number of sysctls under /proc/sys/kernel
. Most of these are read-only, but hostname
and domainname
can be written (see also their table entries).
Of course, this is going to require root privileges to be able to write to e.g. /proc/sys/kernel/hostname
.
This is probably the easiest way to do such a thing while staying within a synthetic filesystem implementation. Of course, the only real way to test your code is to poll(2)
one of your pins, press a button, and see if you get your rising / falling signal interrupts.
Note: sysfs also does this for edge nodes in the tree:
>>> import select
>>> f = open('/sys/bus/clockevents/devices/clockevent0/uevent', 'r')
>>> p = select.poll()
>>> p.register(f, select.POLLPRI | select.POLLERR)
>>> result = p.poll(10)
>>> result
[(3, 10)]
10
is of course POLLPRI (0x2) | POLLERR (0x8)
. I got the same results using /sys/power/state
as my input. Basically, if you poll any user-readable, non-directory file entry in sysfs, you'll get POLLPRI | POLLERR
back.
Related Topics
What Is The Correct Way to Define a Netfilter Hook Function
How to Launch Linux Subshell for Ssh_Askpass to Work in Linux
Stop a Running Dotnet Core Website Running on Kestrel
How to Setup Cron Job on Amazon Linux Ami
How to Remove Warning: Link.Res Contains Output Sections; Did You Forget -T
How to Execute an Arbitrary Script with a Working Directory of The Directory Its In
64-Bit Linux, Assembly Language, Issues
How to Set CPU Load on a Red Hat Linux Box
Using Dma Memory Transfer in User-Space
Find Based Filename Autocomplete in Bash Script
Qemu Hosting Mte Enabled Kernel Does Not Raise Fault
Cpu Utilization High for Sleeping Processes
How to Print $ in Shell Script
Cannot Run 32-Bit Apps on 64-Bit Linux
Powershell Connecting from a Linux Client to a Windows Remote
Can Perf-Stat Results Be Generated from a Perf.Data File
What's The Difference Between /Usr/Include/Linux and The Include Folder in Linux Kernel Source