Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6
Linus Torvalds [Mon, 20 Oct 2008 20:42:14 +0000 (13:42 -0700)]
* 'bkl-removal' of git://git.lwn.net/linux-2.6:
  UIO: BKL removal

1  2 
drivers/uio/uio.c

diff --combined drivers/uio/uio.c
@@@ -47,6 -47,9 +47,9 @@@ static struct uio_class 
        struct class *class;
  } *uio_class;
  
+ /* Protect idr accesses */
+ static DEFINE_MUTEX(minor_lock);
  /*
   * attributes
   */
@@@ -67,11 -70,6 +70,11 @@@ static ssize_t map_size_show(struct uio
        return sprintf(buf, "0x%lx\n", mem->size);
  }
  
 +static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
 +{
 +      return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK);
 +}
 +
  struct uio_sysfs_entry {
        struct attribute attr;
        ssize_t (*show)(struct uio_mem *, char *);
@@@ -82,13 -80,10 +85,13 @@@ static struct uio_sysfs_entry addr_attr
        __ATTR(addr, S_IRUGO, map_addr_show, NULL);
  static struct uio_sysfs_entry size_attribute =
        __ATTR(size, S_IRUGO, map_size_show, NULL);
 +static struct uio_sysfs_entry offset_attribute =
 +      __ATTR(offset, S_IRUGO, map_offset_show, NULL);
  
  static struct attribute *attrs[] = {
        &addr_attribute.attr,
        &size_attribute.attr,
 +      &offset_attribute.attr,
        NULL,   /* need to NULL terminate the list of attributes */
  };
  
@@@ -239,7 -234,6 +242,6 @@@ static void uio_dev_del_attributes(stru
  
  static int uio_get_minor(struct uio_device *idev)
  {
-       static DEFINE_MUTEX(minor_lock);
        int retval = -ENOMEM;
        int id;
  
@@@ -261,7 -255,9 +263,9 @@@ exit
  
  static void uio_free_minor(struct uio_device *idev)
  {
+       mutex_lock(&minor_lock);
        idr_remove(&uio_idr, idev->minor);
+       mutex_unlock(&minor_lock);
  }
  
  /**
@@@ -305,8 -301,9 +309,9 @@@ static int uio_open(struct inode *inode
        struct uio_listener *listener;
        int ret = 0;
  
-       lock_kernel();
+       mutex_lock(&minor_lock);
        idev = idr_find(&uio_idr, iminor(inode));
+       mutex_unlock(&minor_lock);
        if (!idev) {
                ret = -ENODEV;
                goto out;
                if (ret)
                        goto err_infoopen;
        }
        return 0;
  
  err_infoopen:
        kfree(listener);
- err_alloc_listener:
  
+ err_alloc_listener:
        module_put(idev->owner);
  
  out:
-       unlock_kernel();
        return ret;
  }
  
@@@ -490,23 -484,15 +492,23 @@@ static int uio_vma_fault(struct vm_area
  {
        struct uio_device *idev = vma->vm_private_data;
        struct page *page;
 +      unsigned long offset;
  
        int mi = uio_find_mem_index(vma);
        if (mi < 0)
                return VM_FAULT_SIGBUS;
  
 +      /*
 +       * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
 +       * to use mem[N].
 +       */
 +      offset = (vmf->pgoff - mi) << PAGE_SHIFT;
 +
        if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
 -              page = virt_to_page(idev->info->mem[mi].addr);
 +              page = virt_to_page(idev->info->mem[mi].addr + offset);
        else
 -              page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
 +              page = vmalloc_to_page((void *)idev->info->mem[mi].addr
 +                                                      + offset);
        get_page(page);
        vmf->page = page;
        return 0;
@@@ -698,9 -684,9 +700,9 @@@ int __uio_register_device(struct modul
        if (ret)
                goto err_get_minor;
  
 -      idev->dev = device_create_drvdata(uio_class->class, parent,
 -                                        MKDEV(uio_major, idev->minor), idev,
 -                                        "uio%d", idev->minor);
 +      idev->dev = device_create(uio_class->class, parent,
 +                                MKDEV(uio_major, idev->minor), idev,
 +                                "uio%d", idev->minor);
        if (IS_ERR(idev->dev)) {
                printk(KERN_ERR "UIO: device register failed\n");
                ret = PTR_ERR(idev->dev);