Skip to contentSkip to conversation

omap-pm: resource: Lock resource list in update_resource_level

PATCH New Mike Chan 1 participant 2 messages May 4, 2010

Subsystems (2)
lore
Share & tools
lore

Mike Chan

author
#0 lore raw

PATCH 1/2 omap-pm: resource: Lock resource list in update_resource_level

Take the resource mutex when iterating over the resource user_list. A race can occur if resource_request() adds a first time user to the user_list while update_resource_level() is called.

---
 arch/arm/plat-omap/resource.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
arch/arm/plat-omap/resource.c +7 -2
index f769f7c..6d3bba6 100644
@@ -106,6 +106,7 @@ static int update_resource_level(struct shared_resource *resp)
 	unsigned long target_level;
 	int ret;
 
+	mutex_lock(&resp->resource_mutex);
 	/* Regenerate the target_value for the resource */
 	if (resp->flags & RES_TYPE_PERFORMANCE) {
 		target_level = RES_PERFORMANCE_DEFAULTLEVEL;
@@ -118,9 +119,11 @@ static int update_resource_level(struct shared_resource *resp)
 			if (user->level < target_level)
 				target_level = user->level;
 	} else {
+		mutex_unlock(&resp->resource_mutex);
 		pr_debug("SRF: Unknown resource type\n");
 		return -EINVAL;
 	}
+	mutex_unlock(&resp->resource_mutex);
 
 	pr_debug("SRF: Changing Level for resource %s to %ld\n",
 				resp->name, target_level);
@@ -439,10 +442,12 @@ int resource_release(const char *name, struct device *dev)
 	list_del(&user->node);
 	free_user(user);
 
-	/* Recompute and set the current level for the resource */
-	ret = update_resource_level(resp);
 res_unlock:
 	mutex_unlock(&resp->resource_mutex);
+	/* Recompute and set the current level for the resource */
+	if (!ret)
+		ret = update_resource_level(resp);
+
 	return ret;
 }
 EXPORT_SYMBOL(resource_release);
Signature · 1 line
1.7.0.1
author
#1 lore raw

PATCH 2/2 omap-pm: resource: Only update resource level if there is a change

Previosuly update_resource_level() would always call the change_level() function, even if there was no change necessary.

---
 arch/arm/plat-omap/resource.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)
arch/arm/plat-omap/resource.c +4 -1
index 6d3bba6..ff5a938 100644
@@ -104,7 +104,7 @@ static int update_resource_level(struct shared_resource *resp)
 {
 	struct users_list *user;
 	unsigned long target_level;
-	int ret;
+	int ret = 0;
 
 	mutex_lock(&resp->resource_mutex);
 	/* Regenerate the target_value for the resource */
@@ -125,6 +125,9 @@ static int update_resource_level(struct shared_resource *resp)
 	}
 	mutex_unlock(&resp->resource_mutex);
 
+	if (resp->curr_level == target_level)
+		return ret;
+
 	pr_debug("SRF: Changing Level for resource %s to %ld\n",
 				resp->name, target_level);
 	ret = resp->ops->change_level(resp, target_level);
Signature · 1 line
1.7.0.1