mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 07:03:09 -04:00
Merge "guestvm_loader: isolate cpus when VM is starting"
This commit is contained in:
commit
e14ef833ac
1 changed files with 89 additions and 1 deletions
|
|
@ -11,12 +11,17 @@
|
|||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/haven/hh_rm_drv.h>
|
||||
|
||||
#include <soc/qcom/subsystem_notif.h>
|
||||
#include <soc/qcom/subsystem_restart.h>
|
||||
|
||||
#define MAX_LEN 256
|
||||
#define DEFAULT_UNISO_TIMEOUT_MS 8000
|
||||
#define NUM_RESERVED_CPUS 2
|
||||
|
||||
const static struct {
|
||||
enum hh_vm_names val;
|
||||
|
|
@ -41,6 +46,63 @@ struct guestvm_loader_private {
|
|||
u8 vm_status;
|
||||
};
|
||||
|
||||
static struct timer_list guestvm_cpu_isolate_timer;
|
||||
static struct completion isolation_done;
|
||||
static struct work_struct unisolation_work;
|
||||
static cpumask_t guestvm_isolated_cpus;
|
||||
static cpumask_t guestvm_reserve_cpus;
|
||||
static u32 guestvm_unisolate_timeout;
|
||||
|
||||
static void guestvm_isolate_cpu(void)
|
||||
{
|
||||
int cpu, ret;
|
||||
|
||||
for_each_cpu_and(cpu, &guestvm_reserve_cpus, cpu_online_mask) {
|
||||
ret = sched_isolate_cpu(cpu);
|
||||
if (ret < 0) {
|
||||
pr_err("fail to isolate CPU%d. ret=%d\n", cpu, ret);
|
||||
continue;
|
||||
}
|
||||
cpumask_set_cpu(cpu, &guestvm_isolated_cpus);
|
||||
}
|
||||
|
||||
pr_info("%s: reserved_cpus=%*pbl isolated=%*pbl\n", __func__,
|
||||
cpumask_pr_args(&guestvm_isolated_cpus),
|
||||
cpumask_pr_args(cpu_isolated_mask));
|
||||
}
|
||||
|
||||
static void guestvm_unisolate_cpu(void)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
for_each_cpu(i, &guestvm_isolated_cpus) {
|
||||
ret = sched_unisolate_cpu(i);
|
||||
if (ret < 0) {
|
||||
pr_err("fail to un-isolate CPU%d. ret=%d\n", i, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
cpumask_clear_cpu(i, &guestvm_isolated_cpus);
|
||||
}
|
||||
|
||||
pr_info("%s: isolated mask=%*pbl\n", __func__,
|
||||
cpumask_pr_args(cpu_isolated_mask));
|
||||
del_timer(&guestvm_cpu_isolate_timer);
|
||||
}
|
||||
|
||||
static void guestvm_unisolate_work(struct work_struct *work)
|
||||
{
|
||||
if (wait_for_completion_interruptible(&isolation_done))
|
||||
pr_err("%s: CPU unisolation is interrupted\n", __func__);
|
||||
|
||||
guestvm_unisolate_cpu();
|
||||
}
|
||||
|
||||
static void guestvm_timer_callback(struct timer_list *t)
|
||||
{
|
||||
complete(&isolation_done);
|
||||
}
|
||||
|
||||
static inline enum hh_vm_names get_hh_vm_name(const char *str)
|
||||
{
|
||||
int vmid;
|
||||
|
|
@ -137,6 +199,11 @@ static ssize_t guestvm_loader_start(struct kobject *kobj,
|
|||
dev_err(priv->dev, "VM start completion interrupted\n");
|
||||
|
||||
priv->vm_status = HH_RM_VM_STATUS_RUNNING;
|
||||
INIT_WORK(&unisolation_work, guestvm_unisolate_work);
|
||||
schedule_work(&unisolation_work);
|
||||
guestvm_isolate_cpu();
|
||||
mod_timer(&guestvm_cpu_isolate_timer,
|
||||
jiffies + msecs_to_jiffies(guestvm_unisolate_timeout));
|
||||
ret = hh_rm_vm_start(priv->vmid);
|
||||
if (ret)
|
||||
dev_err(priv->dev, "VM start failed for vmid = %d ret = %d\n",
|
||||
|
|
@ -161,7 +228,8 @@ static int guestvm_loader_probe(struct platform_device *pdev)
|
|||
{
|
||||
struct guestvm_loader_private *priv = NULL;
|
||||
const char *sub_sys;
|
||||
int ret = 0;
|
||||
int ret = 0, i, reserve_cpus_len;
|
||||
u32 reserve_cpus[NUM_RESERVED_CPUS] = {0};
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
|
|
@ -191,11 +259,31 @@ static int guestvm_loader_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
init_completion(&priv->vm_start);
|
||||
init_completion(&isolation_done);
|
||||
priv->guestvm_nb.notifier_call = guestvm_loader_nb_handler;
|
||||
ret = hh_rm_register_notifier(&priv->guestvm_nb);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
reserve_cpus_len = of_property_read_variable_u32_array(
|
||||
pdev->dev.of_node,
|
||||
"qcom,reserved-cpus",
|
||||
reserve_cpus, 0, NUM_RESERVED_CPUS);
|
||||
for (i = 0; i < reserve_cpus_len; i++)
|
||||
if (reserve_cpus[i] < num_possible_cpus())
|
||||
cpumask_set_cpu(reserve_cpus[i], &guestvm_reserve_cpus);
|
||||
|
||||
/* Default to (4,5) as reserve cpus */
|
||||
if (reserve_cpus_len <= 0) {
|
||||
cpumask_set_cpu(4, &guestvm_reserve_cpus);
|
||||
cpumask_set_cpu(5, &guestvm_reserve_cpus);
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(pdev->dev.of_node, "qcom,unisolate-timeout-ms",
|
||||
&guestvm_unisolate_timeout);
|
||||
if (ret)
|
||||
guestvm_unisolate_timeout = DEFAULT_UNISO_TIMEOUT_MS;
|
||||
timer_setup(&guestvm_cpu_isolate_timer, guestvm_timer_callback, 0);
|
||||
priv->vm_status = HH_RM_VM_STATUS_NO_STATE;
|
||||
return 0;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue