Skip to content
This repository has been archived by the owner on Jul 7, 2021. It is now read-only.

Commit

Permalink
qos: Don't disable interrupts while holding pm_qos_lock
Browse files Browse the repository at this point in the history
None of the pm_qos functions actually run in interrupt context; if some
driver calls pm_qos_update_target in interrupt context then it's already
broken. There's no need to disable interrupts while holding pm_qos_lock,
so don't do it.

Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
  • Loading branch information
kerneltoast authored and 0ctobot committed May 4, 2020
1 parent 316b8c3 commit 702d288
Showing 1 changed file with 11 additions and 18 deletions.
29 changes: 11 additions & 18 deletions kernel/power/qos.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
/*
* locking rule: all changes to constraints or notifiers lists
* or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock
* held, taken with _irqsave. One lock to rule them all
* held. One lock to rule them all
*/
struct pm_qos_object {
struct pm_qos_constraints *constraints;
Expand Down Expand Up @@ -337,7 +337,6 @@ static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused)
struct pm_qos_constraints *c;
struct pm_qos_request *req;
char *type;
unsigned long flags;
int tot_reqs = 0;
int active_reqs = 0;

Expand All @@ -352,7 +351,7 @@ static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused)
}

/* Lock to ensure we have a snapshot */
spin_lock_irqsave(&pm_qos_lock, flags);
spin_lock(&pm_qos_lock);
if (plist_head_empty(&c->list)) {
seq_puts(s, "Empty!\n");
goto out;
Expand Down Expand Up @@ -388,7 +387,7 @@ static int pm_qos_dbg_show_requests(struct seq_file *s, void *unused)
type, pm_qos_get_value(c), active_reqs, tot_reqs);

out:
spin_unlock_irqrestore(&pm_qos_lock, flags);
spin_unlock(&pm_qos_lock);
return 0;
}

Expand Down Expand Up @@ -465,12 +464,11 @@ static inline int pm_qos_set_value_for_cpus(struct pm_qos_constraints *c,
int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
enum pm_qos_req_action action, int value)
{
unsigned long flags;
int prev_value, curr_value, new_value;
unsigned long cpus = 0;
int ret;

spin_lock_irqsave(&pm_qos_lock, flags);
spin_lock(&pm_qos_lock);
prev_value = pm_qos_get_value(c);
if (value == PM_QOS_DEFAULT_VALUE)
new_value = c->default_value;
Expand Down Expand Up @@ -501,7 +499,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, struct plist_node *node,
pm_qos_set_value(c, curr_value);
ret = pm_qos_set_value_for_cpus(c, &cpus);

spin_unlock_irqrestore(&pm_qos_lock, flags);
spin_unlock(&pm_qos_lock);

trace_pm_qos_update_target(action, prev_value, curr_value);

Expand Down Expand Up @@ -554,10 +552,9 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf,
struct pm_qos_flags_request *req,
enum pm_qos_req_action action, s32 val)
{
unsigned long irqflags;
s32 prev_value, curr_value;

spin_lock_irqsave(&pm_qos_lock, irqflags);
spin_lock(&pm_qos_lock);

prev_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;

Expand All @@ -580,7 +577,7 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf,

curr_value = list_empty(&pqf->list) ? 0 : pqf->effective_flags;

spin_unlock_irqrestore(&pm_qos_lock, irqflags);
spin_unlock(&pm_qos_lock);

trace_pm_qos_update_flags(action, prev_value, curr_value);
return prev_value != curr_value;
Expand Down Expand Up @@ -615,12 +612,11 @@ EXPORT_SYMBOL_GPL(pm_qos_request_active);

int pm_qos_request_for_cpumask(int pm_qos_class, struct cpumask *mask)
{
unsigned long irqflags;
int cpu;
struct pm_qos_constraints *c = NULL;
int val;

spin_lock_irqsave(&pm_qos_lock, irqflags);
spin_lock(&pm_qos_lock);
c = pm_qos_array[pm_qos_class]->constraints;
val = c->default_value;

Expand All @@ -639,7 +635,7 @@ int pm_qos_request_for_cpumask(int pm_qos_class, struct cpumask *mask)
break;
}
}
spin_unlock_irqrestore(&pm_qos_lock, irqflags);
spin_unlock(&pm_qos_lock);

return val;
}
Expand Down Expand Up @@ -674,7 +670,6 @@ static void pm_qos_work_fn(struct work_struct *work)
#ifdef CONFIG_SMP
static void pm_qos_irq_release(struct kref *ref)
{
unsigned long flags;
struct irq_affinity_notify *notify = container_of(ref,
struct irq_affinity_notify, kref);
struct pm_qos_request *req = container_of(notify,
Expand All @@ -691,7 +686,6 @@ static void pm_qos_irq_release(struct kref *ref)
static void pm_qos_irq_notify(struct irq_affinity_notify *notify,
const cpumask_t *unused_mask)
{
unsigned long flags;
struct pm_qos_request *req = container_of(notify,
struct pm_qos_request, irq_notify);
struct pm_qos_constraints *c =
Expand Down Expand Up @@ -1004,17 +998,16 @@ static ssize_t pm_qos_power_read(struct file *filp, char __user *buf,
size_t count, loff_t *f_pos)
{
s32 value;
unsigned long flags;
struct pm_qos_request *req = filp->private_data;

if (!req)
return -EINVAL;
if (!pm_qos_request_active(req))
return -EINVAL;

spin_lock_irqsave(&pm_qos_lock, flags);
spin_lock(&pm_qos_lock);
value = pm_qos_get_value(pm_qos_array[req->pm_qos_class]->constraints);
spin_unlock_irqrestore(&pm_qos_lock, flags);
spin_unlock(&pm_qos_lock);

return simple_read_from_buffer(buf, count, f_pos, &value, sizeof(s32));
}
Expand Down

0 comments on commit 702d288

Please sign in to comment.