how did the kernel find the right process to send hardware interrupt - linux

At first, this two things might exist:
A system has a table to response hardware interrupt
A process has a table to response interrupt send/set by the kernel
If I hit a key on the keyboard, the keyboard will send a interrupt to the CPU/kernel, and the kernel will process this interrupt. But, maybe the current running process is not the foreground one in front of our eyes, it could be a daemon process or something else. So, how the kernel knows which process should read/response our key stroke?
Thanks!

Hardware interrupts are only handled by the kernel. The device-specific event is processed and if there is event/data to share with user space then the driver makes that available. In your example of a keyboard, the device driver services the interrupt, extracting any data and clearing the condition. The input event representing the data which is pulled from the hardware is then sent to the input subsystem. A user space process must have the exposed input device handle open and blocked on a read. The input subsystem within the kernel is managing this. It's very common to see the same in other drivers: expose a device handle (e.g. /dev/misc/mydevice) which responds to open/close/read/write/ioctl. When a process performs a "read" and there is no data, the kernel code blocks the calling process causing it to wait until there is data to satisfy the read condition. I recommend reading up on kernel device drivers. "Linux Device Drivers" is a great start.

Related

Using libiio trigger to propagate IRQ to userspace

I browsed most of that litterature already and the kernel side of it is very much covered, understood and assimilated.
However my question is basically: How can I be alerted, for example through a callback function, when an interruption occurs in the kernel space and my daemon
lives in userspace.
IRQ Occuring -------> Upper half of the interrupt(put the timestamp in the buffer) ---------> Lower half of the interrupt handler (read data and adds the
timestamp in the buffer) -----------> ???? userspace daemon (async callback of some description) that will write a log on the HD.
I have everything up to the daemon part written and working, I seem to understand that through libiio you can assign a trigger to a particular channel or
attribute but that is where I get stuck.
Litterature on the libiio (most notably its wiki) has a chapter on triggers that is 4 lines long ... not very helpful to say the least.
iioinfo lists the devices present in the LSM6DSLTR (18 devices including two triggers) and I have been unable to assign the triggers to any device that they are
not assigned to already (No such file or directory) which I gather refer to the absence of the trigger directory in the sysfs for that particular device.
I also gather that the sysfs directory is, of course, slave to the kernel device tree and that the creation of that part of the device tree is made as the
driver is loaded.
So there must be a way to alter that part of the sysfs filesystem by asking the kernel driver to provision a device in the context to implement the trigger
directory so we can assign a trigger to it
second part will be to slave that trigger to an actual IRQ (42 in my case - as listed in /proc/interrupts) and be alerted in the userspace daemon when a
thresold has been reached in terms of either acceleration or vibration ...
Well, this is the nuts and bolts of what I am trying to achieve. the last part will be to write a few registers on the chip to configure how and when IRQ will
occur for any given integrated devices.

IRQ Handling from User Space Linux

I'm writting a driver for a synthesized device in an FPGA. The device has several IRQs and have requested them on my driver:
irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
rc = request_irq(irq, &Custom_driver_handler,IRQF_TRIGGER_RISING , DRIVER_NAME, base_addr);
My problem is that i want that the irq_handler calls a function of an user space application. Is there any way to call my user space application from the irq_handler of the driver on kernel space??
I know i could save a flag from the driver and mmap its direction from the user application to polling it, but what i want to know is if there is any faster/more correct way.
Thank you in advance
There are several ways of invoking user-space functions from kernel, usually named upcalls: http://lkml.iu.edu/hypermail/linux/kernel/9809.3/0922.html; check also https://lwn.net/Articles/127698/ "Handling interrupts in user space" and the http://wiki.tldp.org/kernel_user_space_howto overview from 2008, part "Sending Signals from the Kernel to the User Space".
To make writing drivers easier, there is UIO framework in the kernel now: https://unix.stackexchange.com/questions/136274/can-i-achieve-functionality-similar-to-interrupts-in-linux-userspace https://lwn.net/Articles/232575/ https://yurovsky.github.io/2014/10/10/linux-uio-gpio-interrupt/ https://www.osadl.org/fileadmin/dam/rtlws/12/Koch.pdf http://www.hep.by/gnu/kernel/uio-howto/
With UIO you can block or poll special file descriptor to wait for interrupt (block by using read() syscall; poll with poll syscall): https://lwn.net/Articles/232575/
On the user space side, the first UIO-handled device will show up as /dev/uio0 (assuming a normal udev setup). The user-space driver will open the device. Reading the device returns an int value which is the event count (number of interrupts) seen by the device; if no interrupts have come in since the last read, the operation will block until an interrupt happens (though non-blocking operation is supported in the usual way as well). The file descriptor can be passed to poll().
include/linux/uio_driver.h is available in linux kernel for many years, it is here for 3. and 4. versions of kernel.

Making a serial port notify on change of handshaking lines

Is it possible to open a serial device (such as /dev/ttyS0) and be informed via select/poll/etc... or a signal when the handshaking lines (such as CTS/RTS or DSR/DTR) change? I know at the hardware level there's an interrupt from the UART to tell the kernel it has changed, but can I be informed of that up in userland?
Edit: I am aware of TIOCMIWAIT, but that ioctl call blocks until the status lines change. I would like instead to keep processing generally and have a poll or similar be informed on change, as well as other events.
There's no way to wait for the DTR/RTS lines to change in userland. The only way to do this on Linux is to constantly poll the device, checking to see if the status of the RTS/DTR lines have changed. I generally steal my serial port code from gtkerm, and it polls.
You can try using TIOCMIWAIT, but if I remember correctly that's going to be very tied to the driver for the serial port that Linux is using, and so may not work from driver to driver.

Does windows have a interrupt-context?

I have recently started reading Linux Kernel Development By Robert Love and I am Love -ing it!
Please read the below excerpt from the book to better understand my questions:
A number identifies interrupts and the kernel uses
this number to execute a specific interrupt handler to process and respond to the interrupt.
For example, as you type, the keyboard controller issues an interrupt to let the system
know that there is new data in the keyboard buffer. The kernel notes the interrupt number of the incoming interrupt and executes the correct interrupt handler.The interrupt
handler processes the keyboard data and lets the keyboard controller know it is ready for
more data...
Now I have dual boot on my machine and sometimes (in fact,many) when I type something on windows, I find myself doing it in, what I call Night crawler mode. This is when I am typing and I don't see anything on the screen and later after a while the entire text comes in one flash, probably the buffer just spits everything out.
Now I don't see this happening on Linux. Is it because of the interrupt-context present in Linux and the absence of it in windows?
BTW, I am still not sure if there is an interrupt-context in windows, google didn't give me any relevant results for that.
All OSes have an interrupt context, it's a feature/constraint of the CPU architecture -- basically, this is "just the way things work" with computer hardware. Different OSes (and drivers within that OS) make different choices about what work and how much work to do in the interrupt before returning, though. That may be related to your windows experience, or it may not. There is a lot of code involved in getting a key press translated into screen output, and interrupt handling is only a tiny part.
A number identifies interrupts and the kernel uses this number to execute a specific interrupt handler to process and respond to the interrupt. For example, as you type, the keyboard controller issues an interrupt to let the system know that there is new data in the keyboard buffer.The kernel notes the interrupt num- ber of the incoming interrupt and executes the correct interrupt handler.The interrupt handler processes the keyboard data and lets the keyboard controller know it is ready for more data
This is a pretty poor description. Things might be different now with USB keyboards, but this seems to discuss what would happen with an old PS/2 connection, where an "8042"-compatible chipset on your motherboard signals on an IRQ line to the CPU, which then executes whatever code is at the address stored in location 9 in the interrupt table (traditionally an array of pointers starting at address 0 in physical memory, though from memory you could change the address, and last time I played with this stuff PCs still had <1MB RAM and used different memory layout modes).
That dispatch process has nothing to do with the kernel... it's the way the hardware works. (The keyboard controller could be asked not to generate interrupts, allowing OS/driver software to "poll" it regularly to see if there happened to be new event data available, but it'd be pretty crazy to use that really).
Still, the code address from the interrupt table will point into the kernel or keyboard driver, and the kernel/driver code will read the keyboard event data from the keyboad controller's I/O port. For these hardware interrupt handlers, a primary goal is to get the data from the device and store it into a buffer as quickly as possible - both to ensure a return from the interrupt to whatever processing was happening, and because the keyboard controller can only handle one event at a time - it needs to be read off into the buffer before the next event.
It's then up to the OS/driver to either provide some kind of input availability signal to application software, or wait for the application software to attempt to read more keyboard input, but it can do it a "whenever you're ready" fashion. Whichever way, once an application has time to read and start responding to the input, things can happen that mean it takes an unexpectedly long amount of time: it could be that the extra keystroke triggers some complex repagination algorithm that takes a long time to run, or that the keystroke results in the program executing code that has been swapped out to disk (check wikipedia for "virtual memory"), in which case it could be only after the hard disk has read part of the program into memory that the program can continue to run. There are thousands of such edge cases involving window movement, graphics clipping algorithms, etc. that could account for the keyboard-handling code taking a long time to complete, and if other keystrokes have happened meanwhile they'll be read by the keyboard driver into that buffer, then only "perceived" by the application after the slow/blocking processing completes. It may well be that the processing consequent to all the keystrokes then in the buffer completes much more quickly: for example, if part of the program was swapped in from disk, that part may be ready to process the remaining keystrokes.
Why would Linux do better at this than Windows? Mainly because the Operating System, drivers and applications tend to be "leaner and meaner"... less bloated software (like C++ vs C# .NET), less wasted memory, so less swapping and delays.

How to record the system information before system hang? [duplicate]

I have an embedded board with a kernel module of thousands of lines which freeze on random and complexe use case with random time. What are the solution for me to try to debug it ?
I have already try magic System Request but it does not work. I guess that the explanation is that I am in a loop or a deadlock in a code where hardware interrupt is disable ?
Thanks,
Eva.
Typically, embedded boards have a watch dog. You should enable this timer and use the watchdog user process to kick the watch dog hard ware. Use nice on the watchdog process so that higher priority tasks must relinquish the CPU. This gives clues as to the issue. If the device does not reset with a watch dog active, then it maybe that only the network or serial port has stopped communicating. Ie, the kernel has not locked up. The issue is that there is no user visible activity. The watch dog is also useful if/when this type of issue occurs in the field.
For a kernel lockup case, the lockup watchdogs kernel features maybe useful. This will work if you have an infinite loop/deadlock as speculated. However, if this is custom hardware, it is also possible that SDRAM or a peripheral device latches up and causes abnormal bus activity. This will stop the CPU from fetching proper code; obviously, it is tough for Linux to recover from this.
You can combine the watchdog with some fallow memory that is used as a trace buffer. memmap= and mem= can limit the memory used by the kernel. A driver/device using this memory can be written that saves trace points that survive a reboot. The fallow memory's ring buffer is dumped when a watchdog reset is detected on kernel boot.
It is also useful to register thread notifiers that can do a printk on context switches, if the issue is repeatable or to discover how to make the event repeatable. Once you determine a sequence of events that leads to the lockup, you can use the scope or logic analyzer to do some final diagnosis. Or, it maybe evident which peripheral is the issue at this point.
You may also set panic=-1 and reboot=... on the kernel command line. The kdump facilities are useful, if you only have a code problem.
Related: kernel trap (at web archive). This link may no longer be available, but aren't important to this answer.

Resources