[SCSI] bfa: protect idr using bfad_mutex
authorJing Huang <huangj@brocade.com>
Fri, 19 Mar 2010 18:07:09 +0000 (11:07 -0700)
committerJames Bottomley <James.Bottomley@suse.de>
Sun, 11 Apr 2010 14:24:20 +0000 (09:24 -0500)
idr is a global resource, protect it with global bfad_mutex.

Signed-off-by: Jing Huang <huangj@brocade.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
drivers/scsi/bfa/bfad.c
drivers/scsi/bfa/bfad_drv.h
drivers/scsi/bfa/bfad_im.c

index 0baeabadb5b276e70c5715c924a4ec8fb40fa094..d4fc4287ebd372681fa98d3f6ef68304ec1688ba 100644 (file)
@@ -33,7 +33,7 @@
 #include <fcb/bfa_fcb.h>
 
 BFA_TRC_FILE(LDRV, BFAD);
-static DEFINE_MUTEX(bfad_mutex);
+DEFINE_MUTEX(bfad_mutex);
 LIST_HEAD(bfad_list);
 static int      bfad_inst;
 int bfad_supported_fc4s;
index 0639aedcb610cc690ff165d3c7dc3efa1c662aaf..6c920c1b53a4dcde5403faa3739bbe0b178492fc 100644 (file)
@@ -293,5 +293,6 @@ extern struct list_head bfad_list;
 extern int bfa_lun_queue_depth;
 extern int bfad_supported_fc4s;
 extern int bfa_linkup_delay;
+extern struct mutex bfad_mutex;
 
 #endif /* __BFAD_DRV_H__ */
index f263891b8cc61da896214efe4d83e4e13edeac2b..5b7cf539e50b18fca22be8c507650291f4970fab 100644 (file)
@@ -518,7 +518,9 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
 {
        int error = 1;
 
+       mutex_lock(&bfad_mutex);
        if (!idr_pre_get(&bfad_im_port_index, GFP_KERNEL)) {
+               mutex_unlock(&bfad_mutex);
                printk(KERN_WARNING "idr_pre_get failure\n");
                goto out;
        }
@@ -526,10 +528,13 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
        error = idr_get_new(&bfad_im_port_index, im_port,
                                         &im_port->idr_id);
        if (error) {
+               mutex_unlock(&bfad_mutex);
                printk(KERN_WARNING "idr_get_new failure\n");
                goto out;
        }
 
+       mutex_unlock(&bfad_mutex);
+
        im_port->shost = bfad_os_scsi_host_alloc(im_port, bfad);
        if (!im_port->shost) {
                error = 1;
@@ -563,7 +568,9 @@ bfad_im_scsi_host_alloc(struct bfad_s *bfad, struct bfad_im_port_s *im_port,
 out_fc_rel:
        scsi_host_put(im_port->shost);
 out_free_idr:
+       mutex_lock(&bfad_mutex);
        idr_remove(&bfad_im_port_index, im_port->idr_id);
+       mutex_unlock(&bfad_mutex);
 out:
        return error;
 }
@@ -571,8 +578,6 @@ out:
 void
 bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
 {
-       unsigned long flags;
-
        bfa_trc(bfad, bfad->inst_no);
        bfa_log(bfad->logmod, BFA_LOG_LINUX_SCSI_HOST_FREE,
                        im_port->shost->host_no);
@@ -582,9 +587,9 @@ bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port)
        scsi_remove_host(im_port->shost);
        scsi_host_put(im_port->shost);
 
-       spin_lock_irqsave(&bfad->bfad_lock, flags);
+       mutex_lock(&bfad_mutex);
        idr_remove(&bfad_im_port_index, im_port->idr_id);
-       spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+       mutex_unlock(&bfad_mutex);
 }
 
 static void