aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDongxiao Xu <dongxiao.xu@intel.com>2009-05-31 02:43:42 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-06-19 14:00:55 -0400
commit72abd2288318a35fbf225b93a31d4623e3b8c872 (patch)
tree9ce193ab0c02b57cb2ef59009d4aafd98c3176df
parent171df6381962b463e5aa8ff936eb3f995a56ce9e (diff)
Staging: heci: fix spinlock order mess of device_lock and read_io_lock
In orginal code, the device_lock and read_io_lock is mess order when nested, which may bring dead lock. This patch unify the spinlock order of device_lock and read_io_lock. First acquire device_lock, then read_io_lock. Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/staging/heci/heci_main.c2
-rw-r--r--drivers/staging/heci/io_heci.c17
2 files changed, 16 insertions, 3 deletions
diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c
index daf1107cb8e0..fb97428b457c 100644
--- a/drivers/staging/heci/heci_main.c
+++ b/drivers/staging/heci/heci_main.c
@@ -954,8 +954,8 @@ static ssize_t heci_read(struct file *file, char __user *ubuf,
954 goto out; 954 goto out;
955 } 955 }
956 956
957 spin_lock(&file_ext->read_io_lock);
958 err = heci_start_read(dev, if_num, file_ext); 957 err = heci_start_read(dev, if_num, file_ext);
958 spin_lock(&file_ext->read_io_lock);
959 if (err != 0 && err != -EBUSY) { 959 if (err != 0 && err != -EBUSY) {
960 DBG("heci start read failure with status = %d\n", err); 960 DBG("heci start read failure with status = %d\n", err);
961 spin_unlock(&file_ext->read_io_lock); 961 spin_unlock(&file_ext->read_io_lock);
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c
index 53dc770727d8..16c723566f6e 100644
--- a/drivers/staging/heci/io_heci.c
+++ b/drivers/staging/heci/io_heci.c
@@ -637,8 +637,9 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
637 DBG("received wrong function input param.\n"); 637 DBG("received wrong function input param.\n");
638 return -ENODEV; 638 return -ENODEV;
639 } 639 }
640 if (file_ext->state != HECI_FILE_CONNECTED) 640 if (file_ext->state != HECI_FILE_CONNECTED) {
641 return -ENODEV; 641 return -ENODEV;
642 }
642 643
643 spin_lock_bh(&dev->device_lock); 644 spin_lock_bh(&dev->device_lock);
644 if (dev->heci_state != HECI_ENABLED) { 645 if (dev->heci_state != HECI_ENABLED) {
@@ -647,18 +648,26 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
647 } 648 }
648 spin_unlock_bh(&dev->device_lock); 649 spin_unlock_bh(&dev->device_lock);
649 DBG("check if read is pending.\n"); 650 DBG("check if read is pending.\n");
651 spin_lock(&file_ext->read_io_lock);
650 if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) { 652 if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
651 DBG("read is pending.\n"); 653 DBG("read is pending.\n");
654 spin_unlock(&file_ext->read_io_lock);
652 return -EBUSY; 655 return -EBUSY;
653 } 656 }
657 spin_unlock(&file_ext->read_io_lock);
658
654 priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); 659 priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
655 if (!priv_cb) 660 if (!priv_cb)
656 return -ENOMEM; 661 return -ENOMEM;
657 662
663 spin_lock(&file_ext->read_io_lock);
658 DBG("allocation call back success\n" 664 DBG("allocation call back success\n"
659 "host client = %d, ME client = %d\n", 665 "host client = %d, ME client = %d\n",
660 file_ext->host_client_id, file_ext->me_client_id); 666 file_ext->host_client_id, file_ext->me_client_id);
667 spin_unlock(&file_ext->read_io_lock);
668
661 spin_lock_bh(&dev->device_lock); 669 spin_lock_bh(&dev->device_lock);
670 spin_lock(&file_ext->read_io_lock);
662 for (i = 0; i < dev->num_heci_me_clients; i++) { 671 for (i = 0; i < dev->num_heci_me_clients; i++) {
663 if (dev->me_clients[i].client_id == file_ext->me_client_id) 672 if (dev->me_clients[i].client_id == file_ext->me_client_id)
664 break; 673 break;
@@ -666,6 +675,7 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
666 } 675 }
667 676
668 BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); 677 BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
678 spin_unlock(&file_ext->read_io_lock);
669 if (i == dev->num_heci_me_clients) { 679 if (i == dev->num_heci_me_clients) {
670 rets = -ENODEV; 680 rets = -ENODEV;
671 goto unlock; 681 goto unlock;
@@ -684,12 +694,14 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
684 /* make sure information is zero before we start */ 694 /* make sure information is zero before we start */
685 priv_cb->information = 0; 695 priv_cb->information = 0;
686 priv_cb->file_private = (void *) file_ext; 696 priv_cb->file_private = (void *) file_ext;
687 file_ext->read_cb = priv_cb;
688 spin_lock_bh(&dev->device_lock); 697 spin_lock_bh(&dev->device_lock);
698 spin_lock(&file_ext->read_io_lock);
699 file_ext->read_cb = priv_cb;
689 if (dev->host_buffer_is_empty) { 700 if (dev->host_buffer_is_empty) {
690 dev->host_buffer_is_empty = 0; 701 dev->host_buffer_is_empty = 0;
691 if (!heci_send_flow_control(dev, file_ext)) { 702 if (!heci_send_flow_control(dev, file_ext)) {
692 rets = -ENODEV; 703 rets = -ENODEV;
704 spin_unlock(&file_ext->read_io_lock);
693 goto unlock; 705 goto unlock;
694 } else { 706 } else {
695 list_add_tail(&priv_cb->cb_list, 707 list_add_tail(&priv_cb->cb_list,
@@ -699,6 +711,7 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num,
699 list_add_tail(&priv_cb->cb_list, 711 list_add_tail(&priv_cb->cb_list,
700 &dev->ctrl_wr_list.heci_cb.cb_list); 712 &dev->ctrl_wr_list.heci_cb.cb_list);
701 } 713 }
714 spin_unlock(&file_ext->read_io_lock);
702 spin_unlock_bh(&dev->device_lock); 715 spin_unlock_bh(&dev->device_lock);
703 return rets; 716 return rets;
704unlock: 717unlock: