diff options
author | Asias He <asias@redhat.com> | 2013-04-25 03:35:20 -0400 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-04-25 04:05:52 -0400 |
commit | f2b7daf5b13f69ac09e706fb5b906478212a4100 (patch) | |
tree | 149b7d34518312ef46c6d75fce96bdcfa6628a21 | |
parent | d3682b1aeba088957a210e3abc2c71dba63d6def (diff) |
tcm_vhost: Refactor the lock nesting rule
We want to use tcm_vhost_mutex to make sure hotplug/hotunplug will not
happen when set_endpoint/clear_endpoint is in process.
Signed-off-by: Asias He <asias@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r-- | drivers/vhost/tcm_vhost.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 957a0b98a5d9..822cd1fbff5e 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -808,6 +808,9 @@ static void vhost_scsi_flush(struct vhost_scsi *vs) | |||
808 | /* | 808 | /* |
809 | * Called from vhost_scsi_ioctl() context to walk the list of available | 809 | * Called from vhost_scsi_ioctl() context to walk the list of available |
810 | * tcm_vhost_tpg with an active struct tcm_vhost_nexus | 810 | * tcm_vhost_tpg with an active struct tcm_vhost_nexus |
811 | * | ||
812 | * The lock nesting rule is: | ||
813 | * tcm_vhost_mutex -> vs->dev.mutex -> tpg->tv_tpg_mutex -> vq->mutex | ||
811 | */ | 814 | */ |
812 | static int vhost_scsi_set_endpoint( | 815 | static int vhost_scsi_set_endpoint( |
813 | struct vhost_scsi *vs, | 816 | struct vhost_scsi *vs, |
@@ -820,26 +823,27 @@ static int vhost_scsi_set_endpoint( | |||
820 | int index, ret, i, len; | 823 | int index, ret, i, len; |
821 | bool match = false; | 824 | bool match = false; |
822 | 825 | ||
826 | mutex_lock(&tcm_vhost_mutex); | ||
823 | mutex_lock(&vs->dev.mutex); | 827 | mutex_lock(&vs->dev.mutex); |
828 | |||
824 | /* Verify that ring has been setup correctly. */ | 829 | /* Verify that ring has been setup correctly. */ |
825 | for (index = 0; index < vs->dev.nvqs; ++index) { | 830 | for (index = 0; index < vs->dev.nvqs; ++index) { |
826 | /* Verify that ring has been setup correctly. */ | 831 | /* Verify that ring has been setup correctly. */ |
827 | if (!vhost_vq_access_ok(&vs->vqs[index])) { | 832 | if (!vhost_vq_access_ok(&vs->vqs[index])) { |
828 | mutex_unlock(&vs->dev.mutex); | 833 | ret = -EFAULT; |
829 | return -EFAULT; | 834 | goto out; |
830 | } | 835 | } |
831 | } | 836 | } |
832 | 837 | ||
833 | len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET; | 838 | len = sizeof(vs_tpg[0]) * VHOST_SCSI_MAX_TARGET; |
834 | vs_tpg = kzalloc(len, GFP_KERNEL); | 839 | vs_tpg = kzalloc(len, GFP_KERNEL); |
835 | if (!vs_tpg) { | 840 | if (!vs_tpg) { |
836 | mutex_unlock(&vs->dev.mutex); | 841 | ret = -ENOMEM; |
837 | return -ENOMEM; | 842 | goto out; |
838 | } | 843 | } |
839 | if (vs->vs_tpg) | 844 | if (vs->vs_tpg) |
840 | memcpy(vs_tpg, vs->vs_tpg, len); | 845 | memcpy(vs_tpg, vs->vs_tpg, len); |
841 | 846 | ||
842 | mutex_lock(&tcm_vhost_mutex); | ||
843 | list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { | 847 | list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { |
844 | mutex_lock(&tv_tpg->tv_tpg_mutex); | 848 | mutex_lock(&tv_tpg->tv_tpg_mutex); |
845 | if (!tv_tpg->tpg_nexus) { | 849 | if (!tv_tpg->tpg_nexus) { |
@@ -854,11 +858,10 @@ static int vhost_scsi_set_endpoint( | |||
854 | 858 | ||
855 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { | 859 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn)) { |
856 | if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) { | 860 | if (vs->vs_tpg && vs->vs_tpg[tv_tpg->tport_tpgt]) { |
857 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
858 | mutex_unlock(&tcm_vhost_mutex); | ||
859 | mutex_unlock(&vs->dev.mutex); | ||
860 | kfree(vs_tpg); | 861 | kfree(vs_tpg); |
861 | return -EEXIST; | 862 | mutex_unlock(&tv_tpg->tv_tpg_mutex); |
863 | ret = -EEXIST; | ||
864 | goto out; | ||
862 | } | 865 | } |
863 | tv_tpg->tv_tpg_vhost_count++; | 866 | tv_tpg->tv_tpg_vhost_count++; |
864 | vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; | 867 | vs_tpg[tv_tpg->tport_tpgt] = tv_tpg; |
@@ -867,7 +870,6 @@ static int vhost_scsi_set_endpoint( | |||
867 | } | 870 | } |
868 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 871 | mutex_unlock(&tv_tpg->tv_tpg_mutex); |
869 | } | 872 | } |
870 | mutex_unlock(&tcm_vhost_mutex); | ||
871 | 873 | ||
872 | if (match) { | 874 | if (match) { |
873 | memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn, | 875 | memcpy(vs->vs_vhost_wwpn, t->vhost_wwpn, |
@@ -893,7 +895,9 @@ static int vhost_scsi_set_endpoint( | |||
893 | kfree(vs->vs_tpg); | 895 | kfree(vs->vs_tpg); |
894 | vs->vs_tpg = vs_tpg; | 896 | vs->vs_tpg = vs_tpg; |
895 | 897 | ||
898 | out: | ||
896 | mutex_unlock(&vs->dev.mutex); | 899 | mutex_unlock(&vs->dev.mutex); |
900 | mutex_unlock(&tcm_vhost_mutex); | ||
897 | return ret; | 901 | return ret; |
898 | } | 902 | } |
899 | 903 | ||
@@ -908,6 +912,7 @@ static int vhost_scsi_clear_endpoint( | |||
908 | int index, ret, i; | 912 | int index, ret, i; |
909 | u8 target; | 913 | u8 target; |
910 | 914 | ||
915 | mutex_lock(&tcm_vhost_mutex); | ||
911 | mutex_lock(&vs->dev.mutex); | 916 | mutex_lock(&vs->dev.mutex); |
912 | /* Verify that ring has been setup correctly. */ | 917 | /* Verify that ring has been setup correctly. */ |
913 | for (index = 0; index < vs->dev.nvqs; ++index) { | 918 | for (index = 0; index < vs->dev.nvqs; ++index) { |
@@ -918,8 +923,8 @@ static int vhost_scsi_clear_endpoint( | |||
918 | } | 923 | } |
919 | 924 | ||
920 | if (!vs->vs_tpg) { | 925 | if (!vs->vs_tpg) { |
921 | mutex_unlock(&vs->dev.mutex); | 926 | ret = 0; |
922 | return 0; | 927 | goto err_dev; |
923 | } | 928 | } |
924 | 929 | ||
925 | for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { | 930 | for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { |
@@ -965,13 +970,14 @@ static int vhost_scsi_clear_endpoint( | |||
965 | kfree(vs->vs_tpg); | 970 | kfree(vs->vs_tpg); |
966 | vs->vs_tpg = NULL; | 971 | vs->vs_tpg = NULL; |
967 | mutex_unlock(&vs->dev.mutex); | 972 | mutex_unlock(&vs->dev.mutex); |
968 | 973 | mutex_unlock(&tcm_vhost_mutex); | |
969 | return 0; | 974 | return 0; |
970 | 975 | ||
971 | err_tpg: | 976 | err_tpg: |
972 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | 977 | mutex_unlock(&tv_tpg->tv_tpg_mutex); |
973 | err_dev: | 978 | err_dev: |
974 | mutex_unlock(&vs->dev.mutex); | 979 | mutex_unlock(&vs->dev.mutex); |
980 | mutex_unlock(&tcm_vhost_mutex); | ||
975 | return ret; | 981 | return ret; |
976 | } | 982 | } |
977 | 983 | ||