Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 184950
b: refs/heads/master
c: 6aa2a86
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Chiang authored and Roland Dreier committed Feb 24, 2010
1 parent c8873f7 commit 9b2c5dc
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2b937afcab34e4f739e2f7cd6062870fbe6b2ccf
refs/heads/master: 6aa2a86ec430fb1ae739bd065d7ea6596997a2cf
45 changes: 9 additions & 36 deletions trunk/drivers/infiniband/core/user_mad.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,17 @@ enum {
};

/*
* Our lifetime rules for these structs are the following: each time a
* device special file is opened, we look up the corresponding struct
* ib_umad_port by minor in the umad_port[] table while holding the
* port_lock. If this lookup succeeds, we take a reference on the
* ib_umad_port's struct ib_umad_device while still holding the
* port_lock; if the lookup fails, we fail the open(). We drop these
* Our lifetime rules for these structs are the following:
* device special file is opened, we take a reference on the
* ib_umad_port's struct ib_umad_device. We drop these
* references in the corresponding close().
*
* In addition to references coming from open character devices, there
* is one more reference to each ib_umad_device representing the
* module's reference taken when allocating the ib_umad_device in
* ib_umad_add_one().
*
* When destroying an ib_umad_device, we clear all of its
* ib_umad_ports from umad_port[] while holding port_lock before
* dropping the module's reference to the ib_umad_device. This is
* always safe because any open() calls will either succeed and obtain
* a reference before we clear the umad_port[] entries, or fail after
* we clear the umad_port[] entries.
* When destroying an ib_umad_device, we drop the module's reference.
*/

struct ib_umad_port {
Expand Down Expand Up @@ -136,7 +128,6 @@ static struct class *umad_class;
static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE);

static DEFINE_SPINLOCK(port_lock);
static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS];
static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS);

static void ib_umad_add_one(struct ib_device *device);
Expand Down Expand Up @@ -779,29 +770,22 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd,
/*
* ib_umad_open() does not need the BKL:
*
* - umad_port[] accesses are protected by port_lock, the
* ib_umad_port structures are properly reference counted, and
* - the ib_umad_port structures are properly reference counted, and
* everything else is purely local to the file being created, so
* races against other open calls are not a problem;
* - the ioctl method does not affect any global state outside of the
* file structure being operated on;
* - the port is added to umad_port[] as the last part of module
* initialization so the open method will either immediately run
* -ENXIO, or all required initialization will be done.
*/
static int ib_umad_open(struct inode *inode, struct file *filp)
{
struct ib_umad_port *port;
struct ib_umad_file *file;
int ret = 0;

spin_lock(&port_lock);
port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE];
port = container_of(inode->i_cdev, struct ib_umad_port, cdev);
if (port)
kref_get(&port->umad_dev->ref);
spin_unlock(&port_lock);

if (!port)
else
return -ENXIO;

mutex_lock(&port->file_mutex);
Expand Down Expand Up @@ -892,13 +876,10 @@ static int ib_umad_sm_open(struct inode *inode, struct file *filp)
};
int ret;

spin_lock(&port_lock);
port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS];
port = container_of(inode->i_cdev, struct ib_umad_port, sm_cdev);
if (port)
kref_get(&port->umad_dev->ref);
spin_unlock(&port_lock);

if (!port)
else
return -ENXIO;

if (filp->f_flags & O_NONBLOCK) {
Expand Down Expand Up @@ -1042,10 +1023,6 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
if (device_create_file(port->sm_dev, &dev_attr_port))
goto err_sm_dev;

spin_lock(&port_lock);
umad_port[port->dev_num] = port;
spin_unlock(&port_lock);

return 0;

err_sm_dev:
Expand Down Expand Up @@ -1079,10 +1056,6 @@ static void ib_umad_kill_port(struct ib_umad_port *port)
cdev_del(&port->cdev);
cdev_del(&port->sm_cdev);

spin_lock(&port_lock);
umad_port[port->dev_num] = NULL;
spin_unlock(&port_lock);

mutex_lock(&port->file_mutex);

port->ib_dev = NULL;
Expand Down

0 comments on commit 9b2c5dc

Please sign in to comment.