Is the driver using the Linux NAPI Interface? - linux

Is there a way to confirm if a Linux Ethernet driver is using the NAPI interface?

I know this sounds like an obvious answer, but check the source to see if the NAPI API is being used.
For example:
In your driver's interrupt handler, does it use any of the calls below?
Does your driver implement a poll() method for the NAPI? If so, see if it uses
netif_receive_skb() instead of netif_rx().
If both of those questions lead to 'YES', the your driver is using NAPI.
Note: The following was copied from here
NAPI API
netif_rx_schedule(dev)
Called by an IRQ handler to schedule a poll for device
netif_rx_schedule_prep(dev)
puts the device in a state ready to be added to the CPU polling list if it is up and running. You can look at this as the first half of netif_rx_schedule(dev).
__netif_rx_schedule(dev)
Add device to the poll list for this CPU; assuming that netif_schedule_prep(dev) has already been called and returned 1
__netif_rx_schedule_prep(dev)
similar to netif_rx_schedule_prep(dev) but no check if device is up, usually not used
netif_rx_reschedule(dev, undo)
Called to reschedule polling for device specifically for some deficient hardware.
netif_rx_complete(dev)
Remove interface from the CPU poll list: it must be in the poll list on current cpu. This primitive is called by dev->poll(), when it completes its work. The device cannot be out of poll list at this call, if it is then clearly it is a BUG().
__netif_rx_complete(dev)
same as netif_rx_complete but called when local interrupts are already disabled.
Check out this wikipedia article and the external links in it for more detailed information.
I hope that helps.

Related

Linux keyboard delay

So I want to build a kernel module (I suppose) which would insert little delay after a keyboard key is pressed (let's say 500ms). I managed to do this in Windows through hooks, but it seems to be different in Linux. Note that I do not wish to use x11 methods, as I want it to also work from the linux console (even if there is no X server running). From what I was able to understand, it would require to build a kernel module and insert it dynamically into the kernel with insmod. I managed to build a key logger which would dump each pressed key to the kernel log, but inserting a delay would require sending the thread that handles the keyboard interrupt handler to sleep, which is a very bad idea, and also to rewrite the entire USB_KBD driver, because the current script calls the request_irq function with the IRQF_SHARED flag set, so I guess the original driver still does its job before executing my function.
I am currently requesting an interrupt handler like this
request_irq (1, (irq_handler_t) irq_handler, IRQF_SHARED, "keyboard_stats_irq", (void *)(irq_handler));
Any suggestions on how to handle this (any other way) ?
You can write a user space daemon that reads the input events from /dev/input/input* (whatever the keyboard device is), while grabbing the device to block the events to go through the rest of the system (ioctl(fd, EVIOCGRAB, 1)).
Then, the daemon can create a virtual input device, using /dev/uinput and write the input events there after some delay. Since the delay will be implemented in user-space, that will be quite easy.
Starting your daemon will be equivalent to hot-plugging a virtual keyboard, and modern X servers (less than 10 years?) are able to cope with hot-plugged input devices. And the vconsole driver works fine too with those.

Is there any way for ioctl() in linux to specify submission queue ID for a nvme IO request

I am working on a testing tool for nvme-cli(written in c and can run on linux).
For SSD validation purpose, we are actually looking for sending I/O commands to a particular Submission queue(IO Queue pair). We needed this because we wanted threading, but for threading to happen we need to send I/O requests to different queues else the I/O requests would be processed serially.
So is there any way in ioctl() where we can specify the Submission queue IDs?
Here is how a nvme IO is requested with ioctl()
ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);
This invokes nvme_ioctl() in the driver here!
nvme_ioctl() intern invokes the nvme_submit_io() Function here!
nvme_submit_io() has the a parameter struct nvme_ns *ns where the structure has a field name queueview here!
I wanted to know if we can invoke ioctl() with a additional new parameter queue_id which is to be assigned to queue field of struct nvme_ns *ns in the nvme_submit_io() function.
Can I know if we can do like this?
If yes, please give me some brief steps.
If NO, please suggest me any possible solution.
Since i am new to nvme or ioctl, please correct me if i am wrong.
Look a little bit into nvme_submit_io(), it calls nvme_submit_user_cmd()
Refer here. You will see nvme_alloc_request(q, cmd, 0, NVME_QID_ANY). The request allocates to NVME_QID_ANY means it not specify QID and let the hardware queue mapping to decide which queue is going to send.
Back to your question. AFAIK, there has NO native way to specify QID when sending ioctl cmd. If you really want to. You need to modify native nvme source code and build your own nvme driver.
HINT: Try to let nvme_alloc_request can receive specified QID, instead of NVME_QID_ANY.

Restoring Keyboard IRQ

I'm very new to the Linux Kernel Module development and trying to write a simple kernel module which can later be extended as the keyboard driver.
I tried following two approaches:
Interrupt Based Approach
I started writing the code after following the guide given here. But the only problem is that the machine freezes when I run rmmod because it is not able to restore the IRQ to the original keyboard driver.
Is there any way to save the device name & device id of the original keyboard driver before requesting the IRQ in init() and then restore everything back to normal once the exit() i.e. cleanup_module() is fired?
void cleanup_module() {
/* Something to restore everything back to normal */
free_irq(1, NULL);
}
Polling Approach
In this approach, I am continuously polling for the Key Pressed & Released by using a while loop and then copying the input back to the user.
while(!(inb(0x64) & 0x1) || (input = inb(0x60)) & 0x80);
The problem I'm facing here is that it never comes out of the while loop. I'm assuming that is because the original keyboard driver serves the request.
Is there any way to get the request forwarded from the original keyboard driver?
I appreciate any help/pointers on this.
Thanks!
I'm afraid that I do not see how this can work as long as the normal kernel keyboard driver is also controlling the keyboard, since both drivers will be attempting to control the device. The kernel i8042 driver (I assume that is the relevant one for you) registers its interrupt as shared, and if your driver managed to register for the same interrupt then it will also have registered its handler as shared, so that both got notified on interrupts and would race to access the device.
If you registered a shared handler, this might also explain the crash when you unload it: unregistering a shared interrupt handler only works when the second parameter contains a valid dev_id; so unregistering would fail when called with NULL as you did, but the handler code would still be unloaded from memory. This would leading to a crash on a future interrupt.
Regarding your polling approach, yes, since the normal driver is notified on interrupts it is rather likely to beat you to reading the keyboard.

how uevents get triggered in kernel

uevents has been sent from kernel space to user space through netlink socket.
In kernel, there must be something trigger uevent.
I guess there are two possibilities:
Hardware interrupt - this means, once hardware interruption happened, kernel sends event to user space to signal that there is some events happened.
software polling - this means, there is always a daemon to check these file system to see if there is anything changed. If so, then update these info to upper layer.
Could anyone provide your feedback?
Thanks
I can't agree with you about polling. uevent is event-based, so there is no polling.
Triggering uevent happened in many cases and I would rather start with figuring out what uevent types are exist?
Little searching and here you go - in include/linux/kobject.h
enum kobject_action {
KOBJ_ADD,
KOBJ_REMOVE,
KOBJ_CHANGE,
KOBJ_MOVE,
KOBJ_ONLINE,
KOBJ_OFFLINE,
KOBJ_MAX
};
So it's
Add event
Remove event
Change event
Move event
Online event
Offline event
KOBJ_MAX is special and marks and of enum.
There are 2 functions that actually sends uevent - kobject_uevent and kobject_uevent_env. These functions are called with on of the actions listed above.
Finally, to answer your questions. There are no predefined cases that will trigger uevent. If you search for calls of kobject_uevent and kobject_uevent_env you will see that it's happens in various callbacks in different unrelated kernel subsystems.
uevent is kernel facility to unify notifications from various unrelated drivers. So I think there are no well known list of things that will trigger uevent.

Simulating file descriptor in user space

I would like to implement a socket-like object in user space. There's an important requirement that it should be pollable (i.e. it's state should be queryable via select or poll call).
Is there a platform neutral way of implementing such an object?
I'm aware that on Linux there's eventfd which kind of suits the needs except that there's no way to force it to signalize neither POLLIN nor POLLOUT.
You can use socketpair() to create a pair of connected AF_UNIX sockets. This is better than pipe() as it allows for bidirectional communication. If this isn't good enough for your needs, another option (which requires root for a daemon) would be to use the as-yet-not-in-mainline-Linux CUSE patches to create a device driver in userspace to do whatever you like. Or you can just hook into whatever event loop your user will be using...
The new linux eventfd can also emulate POLLIN/POLLOUT, although not both at once - set its value to 0xfffffffffffffffe for POLLIN but not POLLOUT, 0 for POLLOUT but not POLLIN, or anything else for both.
Other than these options, there's no platform-neutral way to do this, no. The usual pattern is to use a FIFO just to wake up the event loop, and have it poll using some other API once it's awake.
You want to build an user space object, that will be accessible through system call ?
ie open, read, write etc ... are redirected to your userspace object ?
You need either kernel support or libc support, otherwise I don't see how you can redirect your system call.
eventfd is not what you are asking for, it is implemented in kernel space. Did you describe your real problem ? Could fifo or unix domain socket fit your need ?
What about pseudo tty ? I don't know if you can block writing from the master side by faking the hardware flow control.
It's really not clear what you're trying to do; if you want a socket-like device, why not use sockets? You don't say ... And what's the deal with POLLIN and POLLOUT?
I kinda suspect you might be interested in using pseudo-terminal devices, see man 7 pty.
Use pipe(). It gives you two fd's, one to write, one to read.
Use the fd[1] to do your select/poll on.
Use the fd[0] to signal your select/poll for activity.

Resources