From c1b84fedb0e9424f4ba35c5a21da079ecc3952cf Mon Sep 17 00:00:00 2001 From: Satya Durga Srinivasu Prabhala Date: Tue, 4 Aug 2020 05:11:35 -0700 Subject: [PATCH 1/2] soc: qcom: hyp_core_ctl: fix issue with CPU Freq policy dependency commit 9acfa80c3d1ebc0 ("BACKPORT: driver core: fw_devlink: Add support for batching fwnode parsing") changed the way drivers gets probed and by the time hyp core ctl driver tries to get CPU freq policy, cpufreq driver is not probed which leads to hyp core ctl driver probe failure. Fix the dependency on CPU Freq policy by moving freq qos initialization from probe to first write of the min freq node. Change-Id: I75c628e768ee37a78d1ee54df3e55b6d2389f9a2 Signed-off-by: Satya Durga Srinivasu Prabhala --- drivers/soc/qcom/hyp_core_ctl.c | 76 ++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 30 deletions(-) diff --git a/drivers/soc/qcom/hyp_core_ctl.c b/drivers/soc/qcom/hyp_core_ctl.c index 5875c2890422..626452493fe6 100644 --- a/drivers/soc/qcom/hyp_core_ctl.c +++ b/drivers/soc/qcom/hyp_core_ctl.c @@ -792,6 +792,44 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR_RO(status); +static bool freq_qos_init_done; +static int init_freq_qos_req(void) +{ + int cpu, ret; + struct cpufreq_policy *policy; + struct freq_qos_request *qos_req; + + for_each_possible_cpu(cpu) { + policy = cpufreq_cpu_get(cpu); + if (!policy) { + pr_err("cpufreq policy not found for cpu%d\n", cpu); + ret = -ESRCH; + goto remove_qos_req; + } + + qos_req = &per_cpu(qos_min_req, cpu); + ret = freq_qos_add_request(&policy->constraints, qos_req, + FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); + if (ret < 0) { + pr_err("Failed to add min freq constraint (%d)\n", ret); + cpufreq_cpu_put(policy); + goto remove_qos_req; + } + cpufreq_cpu_put(policy); + } + + return 0; + +remove_qos_req: + for_each_possible_cpu(cpu) { + qos_req = &per_cpu(qos_min_req, cpu); + if (freq_qos_request_active(qos_req)) + freq_qos_remove_request(qos_req); + } + + return ret; +} + static ssize_t hcc_min_freq_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) @@ -806,6 +844,12 @@ static ssize_t hcc_min_freq_store(struct device *dev, goto err_out; } + if (!freq_qos_init_done) { + if (init_freq_qos_req()) + goto err_out; + freq_qos_init_done = true; + } + while ((cp = strpbrk(cp + 1, " :"))) ntokens++; @@ -947,37 +991,15 @@ static int hyp_core_ctl_probe(struct platform_device *pdev) int ret; struct hyp_core_ctl_data *hcd; struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; - int cpu; - struct cpufreq_policy *policy; - struct freq_qos_request *qos_req; ret = hh_rm_register_notifier(&hh_vcpu_nb); if (ret) return ret; - for_each_possible_cpu(cpu) { - policy = cpufreq_cpu_get(cpu); - if (!policy) { - pr_err("cpufreq policy not found for cpu%d\n", cpu); - ret = -ESRCH; - goto remove_qos_req; - } - - qos_req = &per_cpu(qos_min_req, cpu); - ret = freq_qos_add_request(&policy->constraints, qos_req, - FREQ_QOS_MIN, FREQ_QOS_MIN_DEFAULT_VALUE); - if (ret < 0) { - pr_err("Failed to add min freq constraint (%d)\n", ret); - cpufreq_cpu_put(policy); - goto remove_qos_req; - } - cpufreq_cpu_put(policy); - } - hcd = kzalloc(sizeof(*hcd), GFP_KERNEL); if (!hcd) { ret = -ENOMEM; - goto remove_qos_req; + goto unregister_rm_notifier; } spin_lock_init(&hcd->lock); @@ -1018,13 +1040,7 @@ stop_task: kthread_stop(hcd->task); free_hcd: kfree(hcd); -remove_qos_req: - for_each_possible_cpu(cpu) { - qos_req = &per_cpu(qos_min_req, cpu); - if (freq_qos_request_active(qos_req)) - freq_qos_remove_request(qos_req); - } - +unregister_rm_notifier: hh_rm_unregister_notifier(&hh_vcpu_nb); return ret; From 94ee947a37d65c4e71b1c6ab25f42f68653839f7 Mon Sep 17 00:00:00 2001 From: Sai Harshini Nimmala Date: Tue, 28 Jul 2020 20:37:26 -0700 Subject: [PATCH 2/2] soc: qcom: hyp_core_ctl: Minor cleanup Change member sid in driver data structure to cap_id. Fix condition check in hh_vcpu_done_populate_affinity_info for better readability. Change-Id: Idc7f8a4fd6b6a7ac8e004eb96c2020a9f1f4444b Signed-off-by: Sai Harshini Nimmala --- drivers/soc/qcom/hyp_core_ctl.c | 57 ++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/drivers/soc/qcom/hyp_core_ctl.c b/drivers/soc/qcom/hyp_core_ctl.c index 626452493fe6..3d7917632476 100644 --- a/drivers/soc/qcom/hyp_core_ctl.c +++ b/drivers/soc/qcom/hyp_core_ctl.c @@ -33,7 +33,7 @@ static DEFINE_PER_CPU(unsigned int, qos_min_freq); /** * struct hyp_core_ctl_cpumap - vcpu to pcpu mapping for the other guest - * @sid: System call id to be used while referring to this vcpu + * @cap_id: System call id to be used while referring to this vcpu * @pcpu: The physical CPU number corresponding to this vcpu * @curr_pcpu: The current physical CPU number corresponding to this vcpu. * The curr_pcu is set to another CPU when the original assigned @@ -41,7 +41,7 @@ static DEFINE_PER_CPU(unsigned int, qos_min_freq); * */ struct hyp_core_ctl_cpu_map { - hh_capid_t sid; + hh_capid_t cap_id; hh_label_t pcpu; hh_label_t curr_pcpu; }; @@ -162,7 +162,7 @@ static void finalize_reservation(struct hyp_core_ctl_data *hcd, cpumask_t *temp) * maintained in vcpu_adjust_mask and processed in the 2nd pass. */ for (i = 0; i < MAX_RESERVE_CPUS; i++) { - if (hcd->cpumap[i].sid == 0) + if (hcd->cpumap[i].cap_id == 0) break; orig_cpu = hcd->cpumap[i].pcpu; @@ -179,11 +179,11 @@ static void finalize_reservation(struct hyp_core_ctl_data *hcd, cpumask_t *temp) * is available in final_reserved_cpus. so restore * the assignment. */ - err = hh_hcall_vcpu_affinity_set(hcd->cpumap[i].sid, + err = hh_hcall_vcpu_affinity_set(hcd->cpumap[i].cap_id, orig_cpu); if (err != HH_ERROR_OK) { - pr_err("restore: fail to assign pcpu for vcpu#%d err=%d sid=%d cpu=%d\n", - i, err, hcd->cpumap[i].sid, orig_cpu); + pr_err("restore: fail to assign pcpu for vcpu#%d err=%d cap_id=%d cpu=%d\n", + i, err, hcd->cpumap[i].cap_id, orig_cpu); continue; } @@ -224,11 +224,11 @@ static void finalize_reservation(struct hyp_core_ctl_data *hcd, cpumask_t *temp) replacement_cpu = cpumask_any(temp); cpumask_clear_cpu(replacement_cpu, temp); - err = hh_hcall_vcpu_affinity_set(hcd->cpumap[i].sid, + err = hh_hcall_vcpu_affinity_set(hcd->cpumap[i].cap_id, replacement_cpu); if (err != HH_ERROR_OK) { - pr_err("adjust: fail to assign pcpu for vcpu#%d err=%d sid=%d cpu=%d\n", - i, err, hcd->cpumap[i].sid, replacement_cpu); + pr_err("adjust: fail to assign pcpu for vcpu#%d err=%d cap_id=%d cpu=%d\n", + i, err, hcd->cpumap[i].cap_id, replacement_cpu); continue; } @@ -635,10 +635,10 @@ static void hyp_core_ctl_init_reserve_cpus(struct hyp_core_ctl_data *hcd) cpumask_clear(&hcd->reserve_cpus); for (i = 0; i < MAX_RESERVE_CPUS; i++) { - if (hh_cpumap[i].sid == 0) + if (hh_cpumap[i].cap_id == 0) break; - hcd->cpumap[i].sid = hh_cpumap[i].sid; + hcd->cpumap[i].cap_id = hh_cpumap[i].cap_id; hcd->cpumap[i].pcpu = hh_cpumap[i].pcpu; hcd->cpumap[i].curr_pcpu = hh_cpumap[i].curr_pcpu; cpumask_set_cpu(hcd->cpumap[i].pcpu, &hcd->reserve_cpus); @@ -650,6 +650,10 @@ static void hyp_core_ctl_init_reserve_cpus(struct hyp_core_ctl_data *hcd) pr_info("reserve_cpus=%*pbl\n", cpumask_pr_args(&hcd->reserve_cpus)); } +/* + * Called when vm_status is STATUS_READY, multiple times before status + * moves to STATUS_RUNNING + */ int hh_vcpu_populate_affinity_info(u32 cpu_idx, u64 cap_id) { if (!init_done) { @@ -657,13 +661,16 @@ int hh_vcpu_populate_affinity_info(u32 cpu_idx, u64 cap_id) return -ENXIO; } - hh_cpumap[nr_vcpus].sid = cap_id; - hh_cpumap[nr_vcpus].pcpu = cpu_idx; - hh_cpumap[nr_vcpus].curr_pcpu = cpu_idx; + if (!is_vcpu_info_populated) { + hh_cpumap[nr_vcpus].cap_id = cap_id; + hh_cpumap[nr_vcpus].pcpu = cpu_idx; + hh_cpumap[nr_vcpus].curr_pcpu = cpu_idx; - nr_vcpus++; - pr_debug("cpu_index:%u vcpu_cap_id:%llu nr_vcpus:%d\n", + nr_vcpus++; + pr_debug("cpu_index:%u vcpu_cap_id:%llu nr_vcpus:%d\n", cpu_idx, cap_id, nr_vcpus); + } + return 0; } @@ -673,15 +680,15 @@ static int hh_vcpu_done_populate_affinity_info(struct notifier_block *nb, struct hh_rm_notif_vm_status_payload *vm_status_payload = data; u8 vm_status = vm_status_payload->vm_status; - if (cmd != HH_RM_NOTIF_VM_STATUS || - vm_status != HH_RM_VM_STATUS_RUNNING) - goto done; + if (cmd == HH_RM_NOTIF_VM_STATUS && + vm_status == HH_RM_VM_STATUS_RUNNING && + !is_vcpu_info_populated) { + mutex_lock(&the_hcd->reservation_mutex); + hyp_core_ctl_init_reserve_cpus(the_hcd); + is_vcpu_info_populated = true; + mutex_unlock(&the_hcd->reservation_mutex); + } - mutex_lock(&the_hcd->reservation_mutex); - hyp_core_ctl_init_reserve_cpus(the_hcd); - is_vcpu_info_populated = true; - mutex_unlock(&the_hcd->reservation_mutex); -done: return NOTIFY_DONE; } @@ -776,7 +783,7 @@ static ssize_t status_show(struct device *dev, struct device_attribute *attr, "Vcpu to Pcpu mappings:\n"); for (i = 0; i < MAX_RESERVE_CPUS; i++) { - if (hcd->cpumap[i].sid == 0) + if (hcd->cpumap[i].cap_id == 0) break; count += scnprintf(buf + count, PAGE_SIZE - count,