diff options
author | Dongxiao Xu <dongxiao.xu@intel.com> | 2009-05-31 02:43:42 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-06-19 14:00:55 -0400 |
commit | 72abd2288318a35fbf225b93a31d4623e3b8c872 (patch) | |
tree | 9ce193ab0c02b57cb2ef59009d4aafd98c3176df | |
parent | 171df6381962b463e5aa8ff936eb3f995a56ce9e (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.c | 2 | ||||
-rw-r--r-- | drivers/staging/heci/io_heci.c | 17 |
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; |
704 | unlock: | 717 | unlock: |