[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>
This commit is contained in:
parent
fe6173d9b3
commit
8284fb19ef
|
@ -766,7 +766,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
|
||||||
if (!secm_area)
|
if (!secm_area)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
mutex_lock(&css->mutex);
|
|
||||||
if (enable && !css->cm_enabled) {
|
if (enable && !css->cm_enabled) {
|
||||||
css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
css->cub_addr1 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
css->cub_addr2 = (void *)get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||||
|
@ -774,7 +773,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
|
||||||
free_page((unsigned long)css->cub_addr1);
|
free_page((unsigned long)css->cub_addr1);
|
||||||
free_page((unsigned long)css->cub_addr2);
|
free_page((unsigned long)css->cub_addr2);
|
||||||
free_page((unsigned long)secm_area);
|
free_page((unsigned long)secm_area);
|
||||||
mutex_unlock(&css->mutex);
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -795,7 +793,6 @@ chsc_secm(struct channel_subsystem *css, int enable)
|
||||||
free_page((unsigned long)css->cub_addr1);
|
free_page((unsigned long)css->cub_addr1);
|
||||||
free_page((unsigned long)css->cub_addr2);
|
free_page((unsigned long)css->cub_addr2);
|
||||||
}
|
}
|
||||||
mutex_unlock(&css->mutex);
|
|
||||||
free_page((unsigned long)secm_area);
|
free_page((unsigned long)secm_area);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -689,10 +689,14 @@ css_cm_enable_show(struct device *dev, struct device_attribute *attr,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct channel_subsystem *css = to_css(dev);
|
struct channel_subsystem *css = to_css(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (!css)
|
if (!css)
|
||||||
return 0;
|
return 0;
|
||||||
return sprintf(buf, "%x\n", css->cm_enabled);
|
mutex_lock(&css->mutex);
|
||||||
|
ret = sprintf(buf, "%x\n", css->cm_enabled);
|
||||||
|
mutex_unlock(&css->mutex);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
|
@ -702,6 +706,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
|
||||||
struct channel_subsystem *css = to_css(dev);
|
struct channel_subsystem *css = to_css(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&css->mutex);
|
||||||
switch (buf[0]) {
|
switch (buf[0]) {
|
||||||
case '0':
|
case '0':
|
||||||
ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
|
ret = css->cm_enabled ? chsc_secm(css, 0) : 0;
|
||||||
|
@ -712,6 +717,7 @@ css_cm_enable_store(struct device *dev, struct device_attribute *attr,
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
mutex_unlock(&css->mutex);
|
||||||
return ret < 0 ? ret : count;
|
return ret < 0 ? ret : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,9 +764,11 @@ static int css_reboot_event(struct notifier_block *this,
|
||||||
struct channel_subsystem *css;
|
struct channel_subsystem *css;
|
||||||
|
|
||||||
css = channel_subsystems[i];
|
css = channel_subsystems[i];
|
||||||
|
mutex_lock(&css->mutex);
|
||||||
if (css->cm_enabled)
|
if (css->cm_enabled)
|
||||||
if (chsc_secm(css, 0))
|
if (chsc_secm(css, 0))
|
||||||
ret = NOTIFY_BAD;
|
ret = NOTIFY_BAD;
|
||||||
|
mutex_unlock(&css->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue