RE: Linux-omap PM: Fix dead lock condition in resource_release(vdd1_opp)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 
Re-sent to linux-omap-owner@xxxxxxxxxxxxxxxx 

-----Original Message-----
From: Wang Limei-E12499 
Sent: Friday, August 07, 2009 12:05 PM
To: linux-omap@xxxxxxxxxxxxxxx; Kevin Hilman
Cc: Wang Limei-E12499
Subject: Linux-omap PM: Fix dead lock condition in
resource_release(vdd1_opp)

Kevin,
 
I am using linux-omap pm-2.6.29
<http://git.kernel.org/?p=linux/kernel/git/khilman/linux-omap-pm.git;a=s
hortlog;h=pm-2.6.29>  branch,found a dead lock condition in:
arch/arm/plat-omap/resource.c->resource_release().   
 
The dead lock happens when using resource_request("vdd1_opp",&dev,...)
and resource_release("vdd1_opp", &dev) to set and release vdd1 opp
constraint. The  scenario is:  
 
plat-omap/resource.c/resource_release("vdd1_opp",
&dev)==>resource.c/update_resource_level()=>mach-omap2/resource34xx.c/se
t_opp().  In set_opp(),  if the target_level of vdd1 is less than
OPP3,will release the constraint set on VDD2 by calling
resource_release(), but it will never return because can not get the
mutex which is holding  by the previous caller. 
 
int resource_release(const char *name, struct device *dev)
{           .......
	down(&res_mutex);
	........
	/* Recompute and set the current level for the resource */
	ret = update_resource_level(resp);
res_unlock:
	up(&res_mutex);
	return ret;
}

int set_opp(struct shared_resource *resp, u32 target_level) {
	.....
 if (resp == vdd1_resp) {
      if (target_level < 3)
           resource_release("vdd2_opp", &vdd2_dev); }
 
The patch to fix this issue is below, will you pls review it and let me
know your feedback?
 
From: Limei Wang <e12499@xxxxxxxxxxxx>
Date: Fri, 7 Aug 2009 11:40:35 -0500
Subject: [PATCH] OMAP PM: Fix dead lock bug in
resourc_release(vdd1_opp).
 

Signed-off-by: Limei Wang <e12499@xxxxxxxxxxxx>
---
 arch/arm/plat-omap/resource.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
 
diff --git a/arch/arm/plat-omap/resource.c
b/arch/arm/plat-omap/resource.c index ec31727..876fd12 100644
--- a/arch/arm/plat-omap/resource.c
+++ b/arch/arm/plat-omap/resource.c
@@ -418,10 +418,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:
    up(&res_mutex);
+
+   /* Recompute and set the current level for the resource */
+   if (!ret)
+       ret = update_resource_level(resp);
    return ret;
 }
 EXPORT_SYMBOL(resource_release);
--
1.5.6.3

 
Thanks,
Limei
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux