From 6f887df95a5662e48eff36bca50039581171e0f5 Mon Sep 17 00:00:00 2001 From: Anil Kumar Mamidala Date: Fri, 22 Apr 2016 12:42:51 +0530 Subject: [PATCH] ANDROID: GKI: 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. Test: build, boot Bug: 150901210 Change-Id: I99869cc233573b5db10e4f3224d65c29511050ea Signed-off-by: Anil Kumar Mamidala (cherry picked from commit 5db62557cb0e0fb88a638bd300295d1adb8f5bd7) Signed-off-by: Hridya Valsaraju Signed-off-by: celtare21 --- kernel/power/qos.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 00f802b7499e..35d786cc7c9b 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -389,9 +389,13 @@ void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) #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; + struct cpumask *mask; + + if (!desc) + return; + + mask = desc->irq_data.common->affinity; /* Get the current affinity */ cpumask_copy(&req->cpus_affine, mask); @@ -399,13 +403,6 @@ void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) 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, "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); @@ -426,6 +423,24 @@ void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) req->qos = &cpu_latency_constraints; cpu_latency_qos_apply(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->node, PM_QOS_UPDATE_REQ, value); + } + } +#endif } EXPORT_SYMBOL_GPL(cpu_latency_qos_add_request);