diff options
author | Michael Ernst <mernst@de.ibm.com> | 2008-04-17 01:46:01 -0400 |
---|---|---|
committer | Heiko Carstens <heiko.carstens@de.ibm.com> | 2008-04-17 01:46:57 -0400 |
commit | 8284fb19efa1f11ea8dd213e9e227fc1fcb20586 (patch) | |
tree | f91933a4ee9e253bd25c3a98df0d67ee946bb41e /drivers/s390/cio | |
parent | fe6173d9b33dba18ec462051750fb1b9abcd796d (diff) |
[S390] cio: fix parallel cm_enable processing.
It is now possible to trigger cm_enable processing several times in
parallel without causing a kernel panic.
Signed-off-by: Michael Ernst <mernst@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/chsc.c | 3 | ||||
-rw-r--r-- | drivers/s390/cio/css.c | 10 |
2 files changed, 9 insertions, 4 deletions
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index b6a40c20780d..5de86908b0d0 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c | |||
@@ -766,7 +766,6 @@ chsc_secm(struct channel_subsystem *css, int enable) | |||
766 | if (!secm_area) | 766 | if (!secm_area) |
767 | return -ENOMEM; | 767 | return -ENOMEM; |
768 | 768 | ||
769 | mutex_lock(&css->mutex); | ||
770 | if (enable && !css->cm_enabled) { | 769 | if (enable && !css->cm_enabled) { |
771 | css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 770 | css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
772 | css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); | 771 | css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA); |
@@ -774,7 +773,6 @@ chsc_secm(struct channel_subsystem *css, int enable) | |||
774 | free_page((unsigned long)css->cub_addr1); | 773 | free_page((unsigned long)css->cub_addr1); |
775 | free_page((unsigned long)css->cub_addr2); | 774 | free_page((unsigned long)css->cub_addr2); |
776 | free_page((unsigned long)secm_area); | 775 | free_page((unsigned long)secm_area); |
777 | mutex_unlock(&css->mutex); | ||
778 | return -ENOMEM; | 776 | return -ENOMEM; |
779 | } | 777 | } |
780 | } | 778 | } |
@@ -795,7 +793,6 @@ chsc_secm(struct channel_subsystem *css, int enable) | |||
795 | free_page((unsigned long)css->cub_addr1); | 793 | free_page((unsigned long)css->cub_addr1); |
796 | free_page((unsigned long)css->cub_addr2); | 794 | free_page((unsigned long)css->cub_addr2); |
797 | } | 795 | } |
798 | mutex_unlock(&css->mutex); | ||
799 | free_page((unsigned long)secm_area); | 796 | free_page((unsigned long)secm_area); |
800 | return ret; | 797 | return ret; |
801 | } | 798 | } |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index 3e829c827493..c1afab5f72d6 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -689,10 +689,14 @@ css_cm_enable_show(struct device *dev, struct device_attribute *attr, | |||
689 | char *buf) | 689 | char *buf) |
690 | { | 690 | { |
691 | struct channel_subsystem *css = to_css(dev); | 691 | struct channel_subsystem *css = to_css(dev); |
692 | int ret; | ||
692 | 693 | ||
693 | if (!css) | 694 | if (!css) |
694 | return 0; | 695 | return 0; |
695 | return sprintf(buf, "%x\n", css->cm_enabled); | 696 | mutex_lock(&css->mutex); |
697 | ret = sprintf(buf, "%x\n", css->cm_enabled); | ||
698 | mutex_unlock(&css->mutex); | ||
699 | return ret; | ||
696 | } | 700 | } |
697 | 701 | ||
698 | static ssize_t | 702 | static ssize_t |
@@ -702,6 +706,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr, | |||
702 | struct channel_subsystem *css = to_css(dev); | 706 | struct channel_subsystem *css = to_css(dev); |
703 | int ret; | 707 | int ret; |
704 | 708 | ||
709 | mutex_lock(&css->mutex); | ||
705 | switch (buf[0]) { | 710 | switch (buf[0]) { |
706 | case '0': | 711 | case '0': |
707 | ret = css->cm_enabled ? chsc_secm(css, 0) : 0; | 712 | ret = css->cm_enabled ? chsc_secm(css, 0) : 0; |
@@ -712,6 +717,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr, | |||
712 | default: | 717 | default: |
713 | ret = -EINVAL; | 718 | ret = -EINVAL; |
714 | } | 719 | } |
720 | mutex_unlock(&css->mutex); | ||
715 | return ret < 0 ? ret : count; | 721 | return ret < 0 ? ret : count; |
716 | } | 722 | } |
717 | 723 | ||
@@ -758,9 +764,11 @@ static int css_reboot_event(struct notifier_block *this, | |||
758 | struct channel_subsystem *css; | 764 | struct channel_subsystem *css; |
759 | 765 | ||
760 | css = channel_subsystems[i]; | 766 | css = channel_subsystems[i]; |
767 | mutex_lock(&css->mutex); | ||
761 | if (css->cm_enabled) | 768 | if (css->cm_enabled) |
762 | if (chsc_secm(css, 0)) | 769 | if (chsc_secm(css, 0)) |
763 | ret = NOTIFY_BAD; | 770 | ret = NOTIFY_BAD; |
771 | mutex_unlock(&css->mutex); | ||
764 | } | 772 | } |
765 | 773 | ||
766 | return ret; | 774 | return ret; |