omap-pm: resource: Protect static pool from concurrent get_user() calls
Subsystems (2)
PATCH 1/1 omap-pm: resource: Protect static pool from concurrent get_user() calls
With per-resource mutexes, mulitple threads can call resource_request() which can cause get_user() to concurrently allocate from the static pool. Take the res_mutex when allocating from the static pool, which is used in resouce_request() and resource_release() to guard against this.
Signed-off-by Mike Chan <[email protected]>
--- arch/arm/plat-omap/resource.c | 55 +++++++++++++++++++++++----------------- 1 files changed, 32 insertions(+), 23 deletions(-)
arch/arm/plat-omap/resource.c +32 -23
@@ -148,34 +148,39 @@ static struct users_list *get_user(void)int ind =0 ;struct users_list *user; +/* +* When allocating from the static pool, we must lock resource mutex, +* to protect against concurrent get_user() calls. +*/ +down (&res_mutex);/* See if something available in the static pool */ while (ind <MAX_USERS ) { -if (usr_list[ind].usage ==UNUSED ) -break ; -else - ind++; +if (usr_list[ind].usage ==UNUSED ) { +/* Pick from the static pool */ + user = &usr_list[ind]; + user->usage =STATIC_ALLOC ; +up (&res_mutex); +return user; + } + ind++; } -if (ind <MAX_USERS ) { -/* Pick from the static pool */ - user = &usr_list[ind]; - user->usage =STATIC_ALLOC ; - }else { -/* By this time we hope slab is initialized */ -if (slab_is_available ()) { - user =kmalloc (sizeof (struct users_list ),GFP_KERNEL ); -if (!user) { -printk (KERN_ERR "SRF:FATAL ERROR: kmalloc" -"failed\n" ); -return ERR_PTR (-ENOMEM ); - } - user->usage =DYNAMIC_ALLOC ; - }else { -/* Dynamic alloc not available yet */ -printk (KERN_ERR "SRF: FATAL ERROR: users_list" -"initial POOL EMPTY before slab init\n" ); +up (&res_mutex); +/* By this time we hope slab is initialized */ +if (slab_is_available ()) { + user =kmalloc (sizeof (struct users_list ),GFP_KERNEL ); +if (!user) { +printk (KERN_ERR "SRF:FATAL ERROR: kmalloc" +"failed\n" );return ERR_PTR (-ENOMEM ); } + user->usage =DYNAMIC_ALLOC ; + }else { +/* Dynamic alloc not available yet */ +printk (KERN_ERR "SRF: FATAL ERROR: users_list" +"initial POOL EMPTY before slab init\n" ); +return ERR_PTR (-ENOMEM ); } +return user; }
@@ -192,8 +197,12 @@ void free_user(struct users_list *user)if (user->usage ==DYNAMIC_ALLOC ) {kfree (user); }else { - user->usage =UNUSED ; +/* +* It is not necesssary to lock when returning to the +* static pool. +*/ user->dev =NULL ; + user->usage =UNUSED ; } }
Signature · 1 line
1.7.0.1