Franck Bui-Huu wrote:
> 
> In devices.c, it's used by usb_device_poll() and usb_device_lseek()
> functions.
> 
>   usb_device_poll():
> 
>     It seems to use it only to protect usb_device_status
>     structure. Can't we use a simple mutex here ?

actually I don't think we need a lock at all here, if the
usb_device_status structure is allocated per process.

Moreover this function seems to be broken because it almost always
raises the POLLIN bit. I tested it and poll(2) always returns with
POLLIN bit set although no event happens on the bus...is this
behaviour expected ?

> 
>   usb_device_lseek():
> 
>     can we use the inode's mutex instead ?
> 
> In devio.c, it's used by usbdev_open() and usbdev_lseek()
> functions. In both function can't we also use the inode's mutex
> instead ?

this patch below does the following:

usb_device_poll() -> no more lock needed because usb_device_status
structure is allocated when opening the file. It also fixes the
potential bug described previously

usb_device_lseek() -> drop the BKL and use the inode's mutex

usbdev_lseek() -> drop the BKL and use the inode's mutex

usbdev_open() -> drop the BKL. I don't know why it was used...

-- >8 --

diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index c0f3734..d07f3ac 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -590,50 +590,34 @@ static ssize_t usb_device_read(struct fi
        return total_written;
 }
 
-/* Kernel lock for "lastev" protection */
 static unsigned int usb_device_poll(struct file *file, struct 
poll_table_struct *wait)
 {
-       struct usb_device_status *st = (struct usb_device_status 
*)file->private_data;
+       struct usb_device_status *st;
        unsigned int mask = 0;
 
-       lock_kernel();
-       if (!st) {
-               st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
-               if (!st) {
-                       unlock_kernel();
-                       return POLLIN;
-               }
-               
-               /* we may have dropped BKL - need to check for having lost the 
race */
-               if (file->private_data) {
-                       kfree(st);
-                       st = file->private_data;
-                       goto lost_race;
-               }
-
-               /*
-                * need to prevent the module from being unloaded, since
-                * proc_unregister does not call the release method and
-                * we would have a memory leak
-                */
-               st->lastev = conndiscevcnt;
-               file->private_data = st;
-               mask = POLLIN;
-       }
-lost_race:
        if (file->f_mode & FMODE_READ)
                 poll_wait(file, &deviceconndiscwq, wait);
+
+       st = (struct usb_device_status *)file->private_data;
        if (st->lastev != conndiscevcnt)
                mask |= POLLIN;
        st->lastev = conndiscevcnt;
-       unlock_kernel();
+
        return mask;
 }
 
 static int usb_device_open(struct inode *inode, struct file *file)
 {
-        file->private_data = NULL;
-        return 0;
+       struct usb_device_status *st;
+       int rv = -ENOMEM;
+
+       st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
+       if (st) {
+               st->lastev = conndiscevcnt;
+               file->private_data = st;
+               rv = 0;
+       }
+       return rv;
 }
 
 static int usb_device_release(struct inode *inode, struct file *file)
@@ -647,8 +631,7 @@ static loff_t usb_device_lseek(struct fi
 {
        loff_t ret;
 
-       lock_kernel();
-
+       mutex_lock(&file->f_dentry->d_inode->i_mutex);
        switch (orig) {
        case 0:
                file->f_pos = offset;
@@ -662,8 +645,7 @@ static loff_t usb_device_lseek(struct fi
        default:
                ret = -EINVAL;
        }
-
-       unlock_kernel();
+       mutex_unlock(&file->f_dentry->d_inode->i_mutex);
        return ret;
 }
 
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 545da37..dfe54d5 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -94,8 +94,7 @@ static loff_t usbdev_lseek(struct file *
 {
        loff_t ret;
 
-       lock_kernel();
-
+       mutex_lock(&file->f_dentry->d_inode->i_mutex);
        switch (orig) {
        case 0:
                file->f_pos = offset;
@@ -109,8 +108,7 @@ static loff_t usbdev_lseek(struct file *
        default:
                ret = -EINVAL;
        }
-
-       unlock_kernel();
+       mutex_unlock(&file->f_dentry->d_inode->i_mutex);
        return ret;
 }
 
@@ -539,15 +537,10 @@ static int usbdev_open(struct inode *ino
        struct dev_state *ps;
        int ret;
 
-       /* 
-        * no locking necessary here, as chrdev_open has the kernel lock
-        * (still acquire the kernel lock for safety)
-        */
        ret = -ENOMEM;
        if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
-               goto out_nolock;
+               goto out;
 
-       lock_kernel();
        ret = -ENOENT;
        /* check if we are called from a real node or usbfs */
        if (imajor(inode) == USB_DEVICE_MAJOR)
@@ -576,8 +569,6 @@ static int usbdev_open(struct inode *ino
        list_add_tail(&ps->list, &dev->filelist);
        file->private_data = ps;
  out:
-       unlock_kernel();
- out_nolock:
         return ret;
 }
 

Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to