From 1a72216c7d7a518aa042716afc616eb5a78b312c Mon Sep 17 00:00:00 2001 From: Pavankumar Kondeti Date: Tue, 4 Dec 2018 12:04:59 +0530 Subject: [PATCH] power: qos: Use effective affinity mask PM_QOS_REQ_AFFINE_IRQ request is supposed to apply the QoS vote for the CPU(s) on which the attached interrupt arrives. Currently the QoS vote is applied to all the CPUs present in the IRQ affinity mask i.e desc->irq_data.common->affinity. However some chips configure only a single CPU from this affinity mask to receive the IRQ. This information is present in effective affinity mask of an IRQ. Start using it so that a QoS vote is not applied to other CPUs on which the IRQ never comes but present in the affinity mask. Change-Id: If26aa23bebe4a7d07ffedb5ff833ccdb4f4fb6ea Signed-off-by: Pavankumar Kondeti Signed-off-by: celtare21 --- kernel/power/qos.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 35d786cc7c9b..3d994019d14d 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -340,19 +340,29 @@ static void pm_qos_irq_release(struct kref *ref) } static void pm_qos_irq_notify(struct irq_affinity_notify *notify, - const cpumask_t *mask) + 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 = pm_qos_array[req->pm_qos_class]->constraints; + struct irq_desc *desc = irq_to_desc(req->irq); + struct cpumask *new_affinity = + irq_data_get_effective_affinity_mask(&desc->irq_data); + bool affinity_changed = false; spin_lock_irqsave(&pm_qos_lock, flags); - cpumask_copy(&req->cpus_affine, mask); + if (!cpumask_equal(&req->cpus_affine, new_affinity)) { + cpumask_copy(&req->cpus_affine, new_affinity); + affinity_changed = true; + } + spin_unlock_irqrestore(&pm_qos_lock, flags); - pm_qos_update_target(c, &req->node, PM_QOS_UPDATE_REQ, req->node.prio); + if (affinity_changed) + pm_qos_update_target(c, &req->node, PM_QOS_UPDATE_REQ, + req->node.prio); } #endif @@ -395,9 +405,16 @@ void cpu_latency_qos_add_request(struct pm_qos_request *req, s32 value) if (!desc) return; - mask = desc->irq_data.common->affinity; + /* + * If the IRQ is not started, the effective affinity + * won't be set. So fallback to the default affinity. + */ + mask = irq_data_get_effective_affinity_mask( + &desc->irq_data); + if (cpumask_empty(mask)) + mask = irq_data_get_affinity_mask( + &desc->irq_data); - /* Get the current affinity */ cpumask_copy(&req->cpus_affine, mask); req->irq_notify.irq = req->irq; req->irq_notify.notify = pm_qos_irq_notify;