Skip to content

Commit 7b75bbd

Browse files
committed
powercap/dtpm: Change locking scheme
The different functions are all called through the dtpm_create_hierarchy() which handle the mutex. The different functions are used in this context, consequently with the lock always held. Remove all locks taken in the function and add the lock in the hierarchy creation function. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> Reviewed-by: Ulf Hansson <ulf.hansson@linaro.org> Link: https://lore.kernel.org/r/20220130210210.549877-1-daniel.lezcano@linaro.org
1 parent b9d6c47 commit 7b75bbd

1 file changed

Lines changed: 27 additions & 68 deletions

File tree

drivers/powercap/dtpm.c

Lines changed: 27 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ static int get_max_power_range_uw(struct powercap_zone *pcz, u64 *max_power_uw)
5151
{
5252
struct dtpm *dtpm = to_dtpm(pcz);
5353

54-
mutex_lock(&dtpm_lock);
5554
*max_power_uw = dtpm->power_max - dtpm->power_min;
56-
mutex_unlock(&dtpm_lock);
5755

5856
return 0;
5957
}
@@ -83,14 +81,7 @@ static int __get_power_uw(struct dtpm *dtpm, u64 *power_uw)
8381

8482
static int get_power_uw(struct powercap_zone *pcz, u64 *power_uw)
8583
{
86-
struct dtpm *dtpm = to_dtpm(pcz);
87-
int ret;
88-
89-
mutex_lock(&dtpm_lock);
90-
ret = __get_power_uw(dtpm, power_uw);
91-
mutex_unlock(&dtpm_lock);
92-
93-
return ret;
84+
return __get_power_uw(to_dtpm(pcz), power_uw);
9485
}
9586

9687
static void __dtpm_rebalance_weight(struct dtpm *dtpm)
@@ -133,7 +124,16 @@ static void __dtpm_add_power(struct dtpm *dtpm)
133124
}
134125
}
135126

136-
static int __dtpm_update_power(struct dtpm *dtpm)
127+
/**
128+
* dtpm_update_power - Update the power on the dtpm
129+
* @dtpm: a pointer to a dtpm structure to update
130+
*
131+
* Function to update the power values of the dtpm node specified in
132+
* parameter. These new values will be propagated to the tree.
133+
*
134+
* Return: zero on success, -EINVAL if the values are inconsistent
135+
*/
136+
int dtpm_update_power(struct dtpm *dtpm)
137137
{
138138
int ret;
139139

@@ -155,26 +155,6 @@ static int __dtpm_update_power(struct dtpm *dtpm)
155155
return ret;
156156
}
157157

158-
/**
159-
* dtpm_update_power - Update the power on the dtpm
160-
* @dtpm: a pointer to a dtpm structure to update
161-
*
162-
* Function to update the power values of the dtpm node specified in
163-
* parameter. These new values will be propagated to the tree.
164-
*
165-
* Return: zero on success, -EINVAL if the values are inconsistent
166-
*/
167-
int dtpm_update_power(struct dtpm *dtpm)
168-
{
169-
int ret;
170-
171-
mutex_lock(&dtpm_lock);
172-
ret = __dtpm_update_power(dtpm);
173-
mutex_unlock(&dtpm_lock);
174-
175-
return ret;
176-
}
177-
178158
/**
179159
* dtpm_release_zone - Cleanup when the node is released
180160
* @pcz: a pointer to a powercap_zone structure
@@ -191,20 +171,14 @@ int dtpm_release_zone(struct powercap_zone *pcz)
191171
struct dtpm *dtpm = to_dtpm(pcz);
192172
struct dtpm *parent = dtpm->parent;
193173

194-
mutex_lock(&dtpm_lock);
195-
196-
if (!list_empty(&dtpm->children)) {
197-
mutex_unlock(&dtpm_lock);
174+
if (!list_empty(&dtpm->children))
198175
return -EBUSY;
199-
}
200176

201177
if (parent)
202178
list_del(&dtpm->sibling);
203179

204180
__dtpm_sub_power(dtpm);
205181

206-
mutex_unlock(&dtpm_lock);
207-
208182
if (dtpm->ops)
209183
dtpm->ops->release(dtpm);
210184

@@ -216,23 +190,12 @@ int dtpm_release_zone(struct powercap_zone *pcz)
216190
return 0;
217191
}
218192

219-
static int __get_power_limit_uw(struct dtpm *dtpm, int cid, u64 *power_limit)
220-
{
221-
*power_limit = dtpm->power_limit;
222-
return 0;
223-
}
224-
225193
static int get_power_limit_uw(struct powercap_zone *pcz,
226194
int cid, u64 *power_limit)
227195
{
228-
struct dtpm *dtpm = to_dtpm(pcz);
229-
int ret;
230-
231-
mutex_lock(&dtpm_lock);
232-
ret = __get_power_limit_uw(dtpm, cid, power_limit);
233-
mutex_unlock(&dtpm_lock);
234-
235-
return ret;
196+
*power_limit = to_dtpm(pcz)->power_limit;
197+
198+
return 0;
236199
}
237200

238201
/*
@@ -292,7 +255,7 @@ static int __set_power_limit_uw(struct dtpm *dtpm, int cid, u64 power_limit)
292255

293256
ret = __set_power_limit_uw(child, cid, power);
294257
if (!ret)
295-
ret = __get_power_limit_uw(child, cid, &power);
258+
ret = get_power_limit_uw(&child->zone, cid, &power);
296259

297260
if (ret)
298261
break;
@@ -310,8 +273,6 @@ static int set_power_limit_uw(struct powercap_zone *pcz,
310273
struct dtpm *dtpm = to_dtpm(pcz);
311274
int ret;
312275

313-
mutex_lock(&dtpm_lock);
314-
315276
/*
316277
* Don't allow values outside of the power range previously
317278
* set when initializing the power numbers.
@@ -323,8 +284,6 @@ static int set_power_limit_uw(struct powercap_zone *pcz,
323284
pr_debug("%s: power limit: %llu uW, power max: %llu uW\n",
324285
dtpm->zone.name, dtpm->power_limit, dtpm->power_max);
325286

326-
mutex_unlock(&dtpm_lock);
327-
328287
return ret;
329288
}
330289

@@ -335,11 +294,7 @@ static const char *get_constraint_name(struct powercap_zone *pcz, int cid)
335294

336295
static int get_max_power_uw(struct powercap_zone *pcz, int id, u64 *max_power)
337296
{
338-
struct dtpm *dtpm = to_dtpm(pcz);
339-
340-
mutex_lock(&dtpm_lock);
341-
*max_power = dtpm->power_max;
342-
mutex_unlock(&dtpm_lock);
297+
*max_power = to_dtpm(pcz)->power_max;
343298

344299
return 0;
345300
}
@@ -442,8 +397,6 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent)
442397
if (IS_ERR(pcz))
443398
return PTR_ERR(pcz);
444399

445-
mutex_lock(&dtpm_lock);
446-
447400
if (parent) {
448401
list_add_tail(&dtpm->sibling, &parent->children);
449402
dtpm->parent = parent;
@@ -459,8 +412,6 @@ int dtpm_register(const char *name, struct dtpm *dtpm, struct dtpm *parent)
459412
pr_debug("Registered dtpm node '%s' / %llu-%llu uW, \n",
460413
dtpm->zone.name, dtpm->power_min, dtpm->power_max);
461414

462-
mutex_unlock(&dtpm_lock);
463-
464415
return 0;
465416
}
466417

@@ -605,8 +556,12 @@ int dtpm_create_hierarchy(struct of_device_id *dtpm_match_table)
605556
struct device_node *np;
606557
int i, ret;
607558

608-
if (pct)
609-
return -EBUSY;
559+
mutex_lock(&dtpm_lock);
560+
561+
if (pct) {
562+
ret = -EBUSY;
563+
goto out_unlock;
564+
}
610565

611566
pct = powercap_register_control_type(NULL, "dtpm", NULL);
612567
if (IS_ERR(pct)) {
@@ -648,12 +603,16 @@ int dtpm_create_hierarchy(struct of_device_id *dtpm_match_table)
648603
dtpm_subsys[i]->name, ret);
649604
}
650605

606+
mutex_unlock(&dtpm_lock);
607+
651608
return 0;
652609

653610
out_err:
654611
powercap_unregister_control_type(pct);
655612
out_pct:
656613
pct = NULL;
614+
out_unlock:
615+
mutex_unlock(&dtpm_lock);
657616

658617
return ret;
659618
}

0 commit comments

Comments
 (0)