summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnil Kumar Mamidala <amami@codeaurora.org>2016-04-22 12:42:51 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2016-11-27 08:21:28 -0800
commit9879d0300bc4d0ecbacce7969b1712a8d205ebaf (patch)
tree42742f7537bc6dac776ae3b199cc8d60114770cb /kernel
parentd0fd03a2cf02a46b343329c8dd6f7df346a0fa0a (diff)
qos: Register irq notify after adding the qos request
Before adding the irq affinity based qos request to the list, if the affinity of the interrupt changes it will trigger notify call. This notifier call will try to update the qos request. Accessing the qos request which is not yet added to the list leads to a NULL pointer exception. Avoid this race by registering the notifier after adding the qos request. Change-Id: I99869cc233573b5db10e4f3224d65c29511050ea Signed-off-by: Anil Kumar Mamidala <amami@codeaurora.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/power/qos.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/kernel/power/qos.c b/kernel/power/qos.c
index b822206ac811..582b66e882ce 100644
--- a/kernel/power/qos.c
+++ b/kernel/power/qos.c
@@ -596,7 +596,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
#ifdef CONFIG_SMP
case PM_QOS_REQ_AFFINE_IRQ:
if (irq_can_set_affinity(req->irq)) {
- int ret = 0;
struct irq_desc *desc = irq_to_desc(req->irq);
struct cpumask *mask = desc->irq_data.common->affinity;
@@ -606,13 +605,6 @@ void pm_qos_add_request(struct pm_qos_request *req,
req->irq_notify.notify = pm_qos_irq_notify;
req->irq_notify.release = pm_qos_irq_release;
- ret = irq_set_affinity_notifier(req->irq,
- &req->irq_notify);
- if (ret) {
- WARN(1, KERN_ERR "IRQ affinity notify set failed\n");
- req->type = PM_QOS_REQ_ALL_CORES;
- cpumask_setall(&req->cpus_affine);
- }
} else {
req->type = PM_QOS_REQ_ALL_CORES;
cpumask_setall(&req->cpus_affine);
@@ -634,6 +626,24 @@ void pm_qos_add_request(struct pm_qos_request *req,
trace_pm_qos_add_request(pm_qos_class, value);
pm_qos_update_target(pm_qos_array[pm_qos_class]->constraints,
req, PM_QOS_ADD_REQ, value);
+
+#ifdef CONFIG_SMP
+ if (req->type == PM_QOS_REQ_AFFINE_IRQ &&
+ irq_can_set_affinity(req->irq)) {
+ int ret = 0;
+
+ ret = irq_set_affinity_notifier(req->irq,
+ &req->irq_notify);
+ if (ret) {
+ WARN(1, "IRQ affinity notify set failed\n");
+ req->type = PM_QOS_REQ_ALL_CORES;
+ cpumask_setall(&req->cpus_affine);
+ pm_qos_update_target(
+ pm_qos_array[pm_qos_class]->constraints,
+ req, PM_QOS_UPDATE_REQ, value);
+ }
+ }
+#endif
}
EXPORT_SYMBOL_GPL(pm_qos_add_request);