Selaa lähdekoodia

[S390] cio: add lock to struct channel_path

Serialize access to members of struct channel_path with a mutex.

Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Sebastian Ott 14 vuotta sitten
vanhempi
commit
b730f3a933
2 muutettua tiedostoa jossa 27 lisäystä ja 14 poistoa
  1. 23 12
      drivers/s390/cio/chp.c
  2. 4 2
      drivers/s390/cio/chp.h

+ 23 - 12
drivers/s390/cio/chp.c

@@ -1,7 +1,7 @@
 /*
 /*
  *  drivers/s390/cio/chp.c
  *  drivers/s390/cio/chp.c
  *
  *
- *    Copyright IBM Corp. 1999,2007
+ *    Copyright IBM Corp. 1999,2010
  *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
  *    Author(s): Cornelia Huck (cornelia.huck@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
  *		 Arnd Bergmann (arndb@de.ibm.com)
  *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  *		 Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
@@ -241,11 +241,13 @@ static ssize_t chp_status_show(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 			       struct device_attribute *attr, char *buf)
 {
 {
 	struct channel_path *chp = to_channelpath(dev);
 	struct channel_path *chp = to_channelpath(dev);
+	int status;
 
 
-	if (!chp)
-		return 0;
-	return (chp_get_status(chp->chpid) ? sprintf(buf, "online\n") :
-		sprintf(buf, "offline\n"));
+	mutex_lock(&chp->lock);
+	status = chp->state;
+	mutex_unlock(&chp->lock);
+
+	return status ? sprintf(buf, "online\n") : sprintf(buf, "offline\n");
 }
 }
 
 
 static ssize_t chp_status_write(struct device *dev,
 static ssize_t chp_status_write(struct device *dev,
@@ -261,15 +263,18 @@ static ssize_t chp_status_write(struct device *dev,
 	if (!num_args)
 	if (!num_args)
 		return count;
 		return count;
 
 
-	if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1"))
+	if (!strnicmp(cmd, "on", 2) || !strcmp(cmd, "1")) {
+		mutex_lock(&cp->lock);
 		error = s390_vary_chpid(cp->chpid, 1);
 		error = s390_vary_chpid(cp->chpid, 1);
-	else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0"))
+		mutex_unlock(&cp->lock);
+	} else if (!strnicmp(cmd, "off", 3) || !strcmp(cmd, "0")) {
+		mutex_lock(&cp->lock);
 		error = s390_vary_chpid(cp->chpid, 0);
 		error = s390_vary_chpid(cp->chpid, 0);
-	else
+		mutex_unlock(&cp->lock);
+	} else
 		error = -EINVAL;
 		error = -EINVAL;
 
 
 	return error < 0 ? error : count;
 	return error < 0 ? error : count;
-
 }
 }
 
 
 static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
 static DEVICE_ATTR(status, 0644, chp_status_show, chp_status_write);
@@ -315,10 +320,12 @@ static ssize_t chp_type_show(struct device *dev, struct device_attribute *attr,
 			     char *buf)
 			     char *buf)
 {
 {
 	struct channel_path *chp = to_channelpath(dev);
 	struct channel_path *chp = to_channelpath(dev);
+	u8 type;
 
 
-	if (!chp)
-		return 0;
-	return sprintf(buf, "%x\n", chp->desc.desc);
+	mutex_lock(&chp->lock);
+	type = chp->desc.desc;
+	mutex_unlock(&chp->lock);
+	return sprintf(buf, "%x\n", type);
 }
 }
 
 
 static DEVICE_ATTR(type, 0444, chp_type_show, NULL);
 static DEVICE_ATTR(type, 0444, chp_type_show, NULL);
@@ -395,6 +402,7 @@ int chp_new(struct chp_id chpid)
 	chp->state = 1;
 	chp->state = 1;
 	chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
 	chp->dev.parent = &channel_subsystems[chpid.cssid]->device;
 	chp->dev.release = chp_release;
 	chp->dev.release = chp_release;
+	mutex_init(&chp->lock);
 
 
 	/* Obtain channel path description and fill it in. */
 	/* Obtain channel path description and fill it in. */
 	ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
 	ret = chsc_determine_base_channel_path_desc(chpid, &chp->desc);
@@ -464,7 +472,10 @@ void *chp_get_chp_desc(struct chp_id chpid)
 	desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
 	desc = kmalloc(sizeof(struct channel_path_desc), GFP_KERNEL);
 	if (!desc)
 	if (!desc)
 		return NULL;
 		return NULL;
+
+	mutex_lock(&chp->lock);
 	memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
 	memcpy(desc, &chp->desc, sizeof(struct channel_path_desc));
+	mutex_unlock(&chp->lock);
 	return desc;
 	return desc;
 }
 }
 
 

+ 4 - 2
drivers/s390/cio/chp.h

@@ -1,7 +1,7 @@
 /*
 /*
  *  drivers/s390/cio/chp.h
  *  drivers/s390/cio/chp.h
  *
  *
- *    Copyright IBM Corp. 2007
+ *    Copyright IBM Corp. 2007,2010
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  *    Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com>
  */
  */
 
 
@@ -10,6 +10,7 @@
 
 
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/device.h>
 #include <linux/device.h>
+#include <linux/mutex.h>
 #include <asm/chpid.h>
 #include <asm/chpid.h>
 #include "chsc.h"
 #include "chsc.h"
 #include "css.h"
 #include "css.h"
@@ -40,14 +41,15 @@ static inline int chp_test_bit(u8 *bitmap, int num)
 
 
 
 
 struct channel_path {
 struct channel_path {
+	struct device dev;
 	struct chp_id chpid;
 	struct chp_id chpid;
+	struct mutex lock; /* Serialize access to below members. */
 	int state;
 	int state;
 	struct channel_path_desc desc;
 	struct channel_path_desc desc;
 	/* Channel-measurement related stuff: */
 	/* Channel-measurement related stuff: */
 	int cmg;
 	int cmg;
 	int shared;
 	int shared;
 	void *cmg_chars;
 	void *cmg_chars;
-	struct device dev;
 };
 };
 
 
 int chp_get_status(struct chp_id chpid);
 int chp_get_status(struct chp_id chpid);