diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c index ff564de1f8c6..3f998f516a8a 100644 --- a/drivers/gpu/msm/kgsl.c +++ b/drivers/gpu/msm/kgsl.c @@ -4737,6 +4737,7 @@ int kgsl_device_platform_probe(struct kgsl_device *device) { int status = -EINVAL; struct resource *res; + int cpu; status = _register_device(device); if (status) @@ -4863,8 +4864,12 @@ int kgsl_device_platform_probe(struct kgsl_device *device) device->pwrctrl.l2pc_cpus_qos.type = PM_QOS_REQ_AFFINE_CORES; - atomic_set(&device->pwrctrl.l2pc_cpus_qos.cpus_affine, - device->pwrctrl.l2pc_cpus_mask); + cpumask_empty(&device->pwrctrl.l2pc_cpus_qos.cpus_affine); + for_each_possible_cpu(cpu) { + if ((1 << cpu) & device->pwrctrl.l2pc_cpus_mask) + cpumask_set_cpu(cpu, &device->pwrctrl. + l2pc_cpus_qos.cpus_affine); + } pm_qos_add_request(&device->pwrctrl.l2pc_cpus_qos, PM_QOS_CPU_DMA_LATENCY, diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 21da3bb70968..ff49ab3516b1 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h @@ -54,7 +54,7 @@ enum pm_qos_req_type { struct pm_qos_request { enum pm_qos_req_type type; - atomic_t cpus_affine; + struct cpumask cpus_affine; #ifdef CONFIG_SMP uint32_t irq; /* Internal structure members */ diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 1a7d40f8bc4e..da9222575be2 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c @@ -51,8 +51,6 @@ #include #include -#define CPUMASK_ALL (BIT(NR_CPUS) - 1) - /* * 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 @@ -270,7 +268,7 @@ static const struct file_operations pm_qos_debug_fops = { }; static inline int pm_qos_set_value_for_cpus(struct pm_qos_constraints *c, - unsigned long *cpus) + struct cpumask *cpus) { struct pm_qos_request *req = NULL; int cpu; @@ -285,9 +283,7 @@ static inline int pm_qos_set_value_for_cpus(struct pm_qos_constraints *c, return -EINVAL; plist_for_each_entry(req, &c->list, node) { - unsigned long affined_cpus = atomic_read(&req->cpus_affine); - - for_each_cpu(cpu, to_cpumask(&affined_cpus)) { + for_each_cpu(cpu, &req->cpus_affine) { switch (c->type) { case PM_QOS_MIN: if (qos_val[cpu] > req->node.prio) @@ -309,7 +305,7 @@ static inline int pm_qos_set_value_for_cpus(struct pm_qos_constraints *c, for_each_possible_cpu(cpu) { if (c->target_per_cpu[cpu] != qos_val[cpu]) - *cpus |= BIT(cpu); + cpumask_set_cpu(cpu, cpus); c->target_per_cpu[cpu] = qos_val[cpu]; } @@ -334,7 +330,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, unsigned long flags; int prev_value, curr_value, new_value; struct plist_node *node = &req->node; - unsigned long cpus = 0; + struct cpumask cpus; int ret; spin_lock_irqsave(&pm_qos_lock, flags); @@ -365,6 +361,7 @@ int pm_qos_update_target(struct pm_qos_constraints *c, } curr_value = pm_qos_get_value(c); + cpumask_clear(&cpus); pm_qos_set_value(c, curr_value); ret = pm_qos_set_value_for_cpus(c, &cpus); @@ -377,7 +374,8 @@ int pm_qos_update_target(struct pm_qos_constraints *c, * to update the new qos restriction for the cores */ - if (cpus || (ret && prev_value != curr_value)) { + if (!cpumask_empty(&cpus) || + (ret && prev_value != curr_value)) { ret = 1; if (c->notifiers) blocking_notifier_call_chain(c->notifiers, @@ -541,6 +539,7 @@ 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, @@ -548,19 +547,26 @@ static void pm_qos_irq_release(struct kref *ref) struct pm_qos_constraints *c = pm_qos_array[req->pm_qos_class]->constraints; - atomic_set(&req->cpus_affine, CPUMASK_ALL); + spin_lock_irqsave(&pm_qos_lock, flags); + cpumask_setall(&req->cpus_affine); + spin_unlock_irqrestore(&pm_qos_lock, flags); + pm_qos_update_target(c, req, PM_QOS_UPDATE_REQ, c->default_value); } static void pm_qos_irq_notify(struct irq_affinity_notify *notify, const cpumask_t *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; - atomic_set(&req->cpus_affine, *cpumask_bits(mask)); + spin_lock_irqsave(&pm_qos_lock, flags); + cpumask_copy(&req->cpus_affine, mask); + spin_unlock_irqrestore(&pm_qos_lock, flags); + pm_qos_update_target(c, req, PM_QOS_UPDATE_REQ, req->node.prio); } #endif @@ -591,8 +597,9 @@ void pm_qos_add_request(struct pm_qos_request *req, switch (req->type) { case PM_QOS_REQ_AFFINE_CORES: - if (!atomic_cmpxchg_relaxed(&req->cpus_affine, 0, CPUMASK_ALL)) { + if (cpumask_empty(&req->cpus_affine)) { req->type = PM_QOS_REQ_ALL_CORES; + cpumask_setall(&req->cpus_affine); WARN(1, KERN_ERR "Affine cores not set for request with affinity flag\n"); } break; @@ -608,14 +615,14 @@ void pm_qos_add_request(struct pm_qos_request *req, mask = desc->irq_data.common->affinity; /* Get the current affinity */ - atomic_set(&req->cpus_affine, *cpumask_bits(mask)); + cpumask_copy(&req->cpus_affine, mask); req->irq_notify.irq = req->irq; req->irq_notify.notify = pm_qos_irq_notify; req->irq_notify.release = pm_qos_irq_release; } else { req->type = PM_QOS_REQ_ALL_CORES; - atomic_set(&req->cpus_affine, CPUMASK_ALL); + cpumask_setall(&req->cpus_affine); WARN(1, KERN_ERR "IRQ-%d not set for request with affinity flag\n", req->irq); } @@ -625,7 +632,7 @@ void pm_qos_add_request(struct pm_qos_request *req, WARN(1, KERN_ERR "Unknown request type %d\n", req->type); /* fall through */ case PM_QOS_REQ_ALL_CORES: - atomic_set(&req->cpus_affine, CPUMASK_ALL); + cpumask_setall(&req->cpus_affine); break; } @@ -645,7 +652,7 @@ void pm_qos_add_request(struct pm_qos_request *req, if (ret) { WARN(1, "IRQ affinity notify set failed\n"); req->type = PM_QOS_REQ_ALL_CORES; - atomic_set(&req->cpus_affine, CPUMASK_ALL); + cpumask_setall(&req->cpus_affine); pm_qos_update_target( pm_qos_array[pm_qos_class]->constraints, req, PM_QOS_UPDATE_REQ, value); diff --git a/techpack/audio/asoc/sdm660-ext-dai-links.c b/techpack/audio/asoc/sdm660-ext-dai-links.c index 62f777935069..b26430ce9816 100644 --- a/techpack/audio/asoc/sdm660-ext-dai-links.c +++ b/techpack/audio/asoc/sdm660-ext-dai-links.c @@ -283,10 +283,15 @@ static struct snd_soc_ops msm_tdm_be_ops = { static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) { + cpumask_t mask; + if (pm_qos_request_active(&substream->latency_pm_qos_req)) pm_qos_remove_request(&substream->latency_pm_qos_req); - atomic_set(&substream->latency_pm_qos_req.cpus_affine, BIT(1) | BIT(2)); + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; diff --git a/techpack/audio/asoc/sdm660-internal.c b/techpack/audio/asoc/sdm660-internal.c index 4a042375a6c1..fc141e32530e 100644 --- a/techpack/audio/asoc/sdm660-internal.c +++ b/techpack/audio/asoc/sdm660-internal.c @@ -1639,10 +1639,15 @@ static struct snd_soc_ops msm_sdw_mi2s_be_ops = { static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) { + cpumask_t mask; + if (pm_qos_request_active(&substream->latency_pm_qos_req)) pm_qos_remove_request(&substream->latency_pm_qos_req); - atomic_set(&substream->latency_pm_qos_req.cpus_affine, BIT(1) | BIT(2)); + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES; diff --git a/techpack/audio/asoc/sdm845.c b/techpack/audio/asoc/sdm845.c index 2ba93a59b201..c68d4f837c00 100644 --- a/techpack/audio/asoc/sdm845.c +++ b/techpack/audio/asoc/sdm845.c @@ -5030,10 +5030,15 @@ static struct snd_soc_ops sdm845_tdm_be_ops = { static int msm_fe_qos_prepare(struct snd_pcm_substream *substream) { + cpumask_t mask; + if (pm_qos_request_active(&substream->latency_pm_qos_req)) pm_qos_remove_request(&substream->latency_pm_qos_req); - atomic_set(&substream->latency_pm_qos_req.cpus_affine, BIT(1) | BIT(2)); + cpumask_clear(&mask); + cpumask_set_cpu(1, &mask); /* affine to core 1 */ + cpumask_set_cpu(2, &mask); /* affine to core 2 */ + cpumask_copy(&substream->latency_pm_qos_req.cpus_affine, &mask); substream->latency_pm_qos_req.type = PM_QOS_REQ_AFFINE_CORES;