LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   how to safely use unregister_chrdev? (https://www.linuxquestions.org/questions/linux-kernel-70/how-to-safely-use-unregister_chrdev-750629/)

jans 08-27-2009 08:35 AM

how to safely use unregister_chrdev?
 
Hi everyone,

I want to write a simple character device driver (based on the one in LDD3). How can I use unregister_chrdev safely? For example, consider the following code:

Code:

static int init(void) {
  kbuff = kmalloc(1, GPF_KERNEL);
  if(kbuff == 0) {
    return -1;
  }
  int success = register_chrdev(major, name, &fops);
  if(0 <= success) {
    // users can open/read/write the device
    unregister_chrdev(major, name);
    // somebody might still be writing here
    free(kbuff); // freeing is problematic since write might be writing to kbuff
    return -1;
  }
  else {
    free(kbuff);
    return success;
  }
}
module_init(init);

How can I determine nobody is reading or writing any more and that I can safely deallocate kbuff?

In other words, is it possible to stop accepting "open" calls and to wait for all existing file handles to be released?

Thanks in advance,
Jan

cladisch 08-28-2009 07:16 AM

Usually, anything allocated in the module_init function is free in the module_exit function.
By making your module the owner of opened objects, or by incrementing the reference count of the module yourself when something is opened, you ensure that the module cannot be unloaded while it's still used.

jans 09-01-2009 07:58 AM

Thx for your reply.

I was wondering about the situation where you have to call unregister_chrdev in module_init (for example, because module_init detects a problem after register_chrdev and needs to deregister/free all resources it already acquired).

Note that the specification of register_chrdev states that the device may start being used immediately after register_chrdev.

cladisch 09-01-2009 09:01 AM

Good question. ;-)

It is recommended that any calls that allow userspace to access your device should come last, i.e., make all resource allocations and other checks before that. (And if you don't do this, your device file's open callback could get into problems if it needs such resources.)

If that is not possible, you have to write your driver in such a way that it waits until there are no acesses from userspace. The file object is reference-counted, so you just have to wait for the last close callback of your device file.


With regard to your first post: If register_chrdev returns an error, it is impossible for this device to have been opened.

jans 09-02-2009 05:15 AM

Quote:

With regard to your first post: If register_chrdev returns an error, it is impossible for this device to have been opened.
Yes, you're right. This is just a toy example where a device is registered and immediately unregistered (if registering succeeds). In a real driver you might want to register several character devices and roll back registrations if you encounter a problem while registering say the 5th device.

Again, thanks for your help! :-)

Quote:

If that is not possible, you have to write your driver in such a way that it waits until there are no acesses from userspace. The file object is reference-counted, so you just have to wait for the last close callback of your device file.
Is there a way to stop new connections (i.e. open calls) to character devices? Is there a preferred way to wait for the reference count to become 0?

A solution to the last question might be to let release notify init_module if it releases a connection.

cladisch 09-02-2009 05:44 AM

Quote:

Is there a way to stop new connections (i.e. open calls) to character devices?
There is a handy function called unregister_chrdev(). :-)

Quote:

Is there a preferred way to wait for the reference count to become 0?
The kernel prevents unloading your module as long as the reference count is above 0, i.e., as long as some file is open. Furthermore, the kernel will prevent any attempts to get a new reference while the module is being unloaded, so it is not possible for your device file to be opened at that point.

In other words, as long as all connections from userspace are properly module-reference counted, you can safely free everything in the module_exit function, without having to wait.

The module reference count helps only with module loading/unloading; if you want to unregister some device before module unloading (for example, because your USB device was unplugged), you actually have to wait for all userspace connections to be closed before you can free the resources they might access.


All times are GMT -5. The time now is 01:23 AM.