Re: [PATCH] remove BKL from drivers' release functions

David C. Hansen
2001-11-29T00:26:53Z

Russell King wrote:

>On Wed, Nov 28, 2001 at 03:32:32PM -0800, David C. Hansen wrote:
>
>>Nothing, because the BKL is not held for all opens anymore. In most of
>>the cases that we addressed, the BKL was in release _only_, not in open
>>at all. There were quite a few drivers where we added a spinlock, or
>>used atomic operations to keep open from racing with release.
>>
>
>All char and block devs are opened with the BKL held - see chrdev_open in
>fs/devices.c and do_open in fs/block_dev.c
>
I wrote a quick and dirty char device driver to see if this happened.
If I run two tasks doing a bunch of opens and closes, the -EBUSY
condition in the open function does happen. Is my driver doing
something wrong?

Here is the meat of the driver:

static int Device_Open = 0;

int testdev_open(struct inode *inode, struct file *file)
{
if ( test_and_set_bit(0,&Device_Open) ) {
printk( "attempt to open testdev more than once\n" );
return -EBUSY;
}
MOD_INC_USE_COUNT;
return SUCCESS;
}

int testdev_release(struct inode *inode, struct file *file)
{
clear_bit(0,&Device_Open);
MOD_DEC_USE_COUNT;
return 0;
}

static int Major;
struct file_operations Fops = {
open: testdev_open,
release: testdev_release,
};

/* Initialize the module - Register the character device */
int init_module(void)
{
Major = register_chrdev(0,
DEVICE_NAME,
&Fops);

/* Negative values signify an error */
if (Major < 0) {
printk ("%s: %s device failed with %d\n",MODULE_NAME,
"Sorry, registering the character",
Major);
return Major;
}
printk( "%s: loaded successfully on Major:%d\n",MODULE_NAME,Major);
return 0;
}

void cleanup_module(void)
{
int ret;
ret = unregister_chrdev(Major, DEVICE_NAME);
if (ret < 0)
printk("%s: Error in unregister_MODULE_NAME: %d\n",
MODULE_NAME, ret);
}