在 QEMU 中,vCPU 线程的启动流程涉及多个阶段,包括初始化、线程创建和执行逻辑。以下是基于搜索结果的详细分析:

QEMU vCPU 线程的启动流程

1. 初始化阶段

  • 设备实例化:QEMU 使用 QOM(QEMU Object Model)系统进行设备的实例化。CPU 设备也需要通过 type_init() 方法注册到 QOM 系统中,这样可以通过 object_new() 创建 CPU 实例。
  • CPU 模型初始化:在 QEMU 启动时,会根据用户指定的 CPU 模型类型(通过命令行参数指定)初始化 vCPU 的特性。例如,对于 x86 架构,QEMU 会加载对应的 CPU 模型定义,并设置支持的特性。

2. 线程创建

  • vCPU 线程创建:在 qemu_init_vcpu() 函数中,QEMU 会为每个 vCPU 创建一个线程。这个线程的主体逻辑是在一个大循环中反复执行取指令、翻译和执行的操作。
  • 线程函数:对于 RISC-V 架构,vCPU 线程的主体函数是 mttcg_cpu_thread_fn,它负责模拟 vCPU 的执行。

3. CPU 状态配置

  • CPU 复位:在 qemu_init_vcpu() 中,vCPU 的初始状态被设置为停止状态(stopped)。在后续的 cpu_reset() 函数中,会调用 riscv_cpu_reset() 来配置 CPU 的初始状态。
  • 启动 vCPU:在 CPU 实例化完成后,通过调用 cpu_resume() 将 vCPU 设置为可以运行的状态。

4. 执行阶段

  • 指令执行循环:vCPU 线程进入一个主循环,不断从虚拟机的内存中取指令、翻译并执行。如果 CPU 处于停止状态,线程会等待直到被唤醒。
  • KVM 支持:在使用 KVM 时,QEMU 会通过 KVM 的 ioctl 接口与内核进行交互,以加速 vCPU 的执行。

5. 多核启动逻辑

  • 主从核协调:在多核虚拟机中,QEMU 会启动多个 vCPU 线程。主核(通常为第一个 vCPU)会初始化公共资源,而从核(其他 vCPU)可能会通过 WFI(Wait for Interrupt)指令挂起,直到主核通过 IPI(Inter-Processor Interrupt)唤醒它们。
  • 固件与内核启动:QEMU 在启动时会加载固件(如 OpenSBI),并通过固件引导内核启动。内核会通过 SBI 接口下发启动命令给从核,从而完成多核启动。

6.小结

QEMU vCPU 线程的启动流程包括初始化设备、创建线程、配置 CPU 状态、进入指令执行循环以及多核协调等阶段。具体实现涉及多个函数和模块,如 qemu_init_vcpu()cpu_reset()cpu_resume()。对于 RISC-V 架构,QEMU 使用 mttcg_cpu_thread_fn 作为 vCPU 线程的主体函数。

如果您需要进一步深入研究,可以参考 QEMU 的源码,特别是 qemu_init_vcpu()cpu_reset() 等函数的实现。

7.tcg解释器创建过程:

static void tcg_accel_ops_init(AccelOpsClass *ops)
{if (qemu_tcg_mttcg_enabled()) {ops->create_vcpu_thread = mttcg_start_vcpu_thread;ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;ops->handle_interrupt = tcg_handle_interrupt;} else {ops->create_vcpu_thread = rr_start_vcpu_thread;ops->kick_vcpu_thread = rr_kick_vcpu_thread;if (icount_enabled()) {ops->handle_interrupt = icount_handle_interrupt;ops->get_virtual_clock = icount_get;ops->get_elapsed_ticks = icount_get;} else {ops->handle_interrupt = tcg_handle_interrupt;}}ops->cpu_reset_hold = tcg_cpu_reset_hold;ops->supports_guest_debug = tcg_supports_guest_debug;ops->insert_breakpoint = tcg_insert_breakpoint;ops->remove_breakpoint = tcg_remove_breakpoint;ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
}

这段代码是 QEMU 中与 TCG(Tiny Code Generator)加速器相关的初始化逻辑,用于设置不同加速模式下的虚拟 CPU(vCPU)线程操作函数。以下是对这段代码的详细解析和解释:

7.1. 函数定义
static void tcg_accel_ops_init(AccelOpsClass *ops)
  • tcg_accel_ops_init:这是一个静态函数,用于初始化 TCG 加速器的操作函数。
  • AccelOpsClass *ops:这是一个指向 AccelOpsClass 结构的指针,该结构定义了加速器的操作接口。
7.2. 多线程 TCG(MTTCG)模式
if (qemu_tcg_mttcg_enabled()) {ops->create_vcpu_thread = mttcg_start_vcpu_thread;ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;ops->handle_interrupt = tcg_handle_interrupt;
}
  • qemu_tcg_mttcg_enabled():检查是否启用了多线程 TCG(MTTCG)模式。
    • 如果启用,ops 的相关操作函数会被设置为 MTTCG 版本。
  • mttcg_start_vcpu_thread:用于启动 vCPU 线程的函数。
  • mttcg_kick_vcpu_thread:用于唤醒 vCPU 线程的函数。
  • tcg_handle_interrupt:处理中断的通用函数。
7.3. 单线程 TCG(RR)模式
else {ops->create_vcpu_thread = rr_start_vcpu_thread;ops->kick_vcpu_thread = rr_kick_vcpu_thread;if (icount_enabled()) {ops->handle_interrupt = icount_handle_interrupt;ops->get_virtual_clock = icount_get;ops->get_elapsed_ticks = icount_get;} else {ops->handle_interrupt = tcg_handle_interrupt;}
}
  • rr_start_vcpu_thread:用于启动 vCPU 线程的函数(单线程模式)。
  • rr_kick_vcpu_thread:用于唤醒 vCPU 线程的函数(单线程模式)。
  • icount_enabled():检查是否启用了指令计数模式(Instruction Counting Mode)。
    • 如果启用,中断处理和时钟获取函数会被设置为指令计数版本。
    • icount_handle_interrupt:处理中断的指令计数版本。
    • icount_get:获取虚拟时钟和已过时钟的指令计数版本。
    • 如果未启用指令计数模式,则使用通用的 tcg_handle_interrupt 函数。
7.4. 通用操作
ops->cpu_reset_hold = tcg_cpu_reset_hold;
ops->supports_guest_debug = tcg_supports_guest_debug;
ops->insert_breakpoint = tcg_insert_breakpoint;
ops->remove_breakpoint = tcg_remove_breakpoint;
ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
  • tcg_cpu_reset_hold:用于在 CPU 重置时保持状态的函数。
  • tcg_supports_guest_debug:检查是否支持客户机调试的函数。
  • tcg_insert_breakpoint:插入断点的函数。
  • tcg_remove_breakpoint:移除断点的函数。
  • tcg_remove_all_breakpoints:移除所有断点的函数。
7.5 功能总结

这段代码的主要功能是根据 QEMU 的配置(MTTCG 或 RR 模式,以及是否启用指令计数)初始化 TCG 加速器的操作函数。这些操作函数定义了 vCPU 线程的启动、唤醒、中断处理以及调试支持等行为。

7.6 关键点
  1. MTTCG 模式

    • 启用多线程 TCG 时,使用 mttcg_start_vcpu_threadmttcg_kick_vcpu_thread
    • 这种模式适合多核系统,可以提高性能。
  2. RR 模式

    • 单线程 TCG 模式,使用 rr_start_vcpu_threadrr_kick_vcpu_thread
    • 适合单核系统或调试场景。
  3. 指令计数模式

    • 如果启用指令计数,中断处理和时钟获取函数会被设置为指令计数版本。
    • 这种模式用于精确模拟指令执行时间。
  4. 调试支持

    • 提供了断点插入和移除的功能,支持客户机调试。

通过这段代码,QEMU 能够灵活地根据配置选择合适的加速模式和操作函数,从而优化虚拟机的性能和调试能力。

8. vcpu 线程建立细节

void mttcg_start_vcpu_thread(CPUState *cpu)
{char thread_name[VCPU_THREAD_NAME_SIZE];g_assert(tcg_enabled());tcg_cpu_init_cflags(cpu, current_machine->smp.max_cpus > 1);/* create a thread per vCPU with TCG (MTTCG) */snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",cpu->cpu_index);qemu_thread_create(cpu->thread, thread_name, mttcg_cpu_thread_fn,cpu, QEMU_THREAD_JOINABLE);
}
qemu_thread_createqemu_thread_startthread_context_class_initthread_context_set_cpu_affinityqemu_thread_set_affinitystatic void thread_context_class_init(ObjectClass *oc, void *data)
{UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);ucc->complete = thread_context_instance_complete;object_class_property_add(oc, "thread-id", "int",thread_context_get_thread_id, NULL, NULL,NULL);object_class_property_add(oc, "cpu-affinity", "int",thread_context_get_cpu_affinity,thread_context_set_cpu_affinity, NULL, NULL);object_class_property_add(oc, "node-affinity", "int", NULL,thread_context_set_node_affinity, NULL, NULL);
}

9. cpu属性更改 object_class_property_add

在 QEMU 中,object_class_property_add 函数用于为一个对象类添加一个属性。这个属性可以被用户通过 QEMU 的命令行工具(如 qemu-monitor)或 API 访问和修改。以下是如何使用 object_class_property_add 添加 cpu-affinity 属性的详细说明,以及如何通过 QEMU 的机制访问和修改这个属性。

9.1. object_class_property_add 函数的参数
object_class_property_add(ObjectClass *oc, const char *name, const char *type,ObjectPropertyAccessor *get,ObjectPropertyAccessor *set,ObjectPropertyRelease *release,void *opaque);
  • oc:指向 ObjectClass 的指针,表示当前正在初始化的类。
  • name:属性的名称(例如 "cpu-affinity")。
  • type:属性的类型(例如 "int" 表示整数)。
  • get:获取属性值的回调函数。
  • set:设置属性值的回调函数。
  • release:释放属性值的回调函数(可选)。
  • opaque:用户数据,传递给回调函数(可选)。
9.2. 回调函数

在您的代码中,cpu-affinity 属性的 getset 回调函数分别是 thread_context_get_cpu_affinitythread_context_set_cpu_affinity

获取属性值的回调函数
static int thread_context_get_cpu_affinity(Object *obj, Error **errp)
{ThreadContext *tc = THREAD_CONTEXT(obj);return tc->cpu_affinity;
}
  • obj:指向对象的指针。
  • errp:用于返回错误信息的指针。
  • 返回值:当前的 CPU 亲和性值。
设置属性值的回调函数
static void thread_context_set_cpu_affinity(Object *obj, int value, Error **errp)
{ThreadContext *tc = THREAD_CONTEXT(obj);tc->cpu_affinity = value;
}
  • obj:指向对象的指针。
  • value:要设置的属性值。
  • errp:用于返回错误信息的指针。
9.3. 如何使用 cpu-affinity 属性
通过 QEMU 命令行工具

假设您已经创建了一个 ThreadContext 对象,并且它被添加到了 QEMU 的对象模型中,您可以通过 QEMU 的命令行工具(如 qemu-monitor)访问和修改 cpu-affinity 属性。

  1. 查询当前的 CPU 亲和性

    (qemu) info object <object-name>
    

    这将显示对象的所有属性,包括 cpu-affinity

  2. 设置 CPU 亲和性

    (qemu) object_property_set <object-name> cpu-affinity=2
    

    这将设置 cpu-affinity 属性为 2。

通过 QEMU API

您也可以通过 QEMU 的 C API 访问和修改属性。

  1. 查询当前的 CPU 亲和性

    int cpu_affinity = object_property_get_int(OBJECT(tc), "cpu-affinity", &error_abort);
    printf("Current CPU affinity: %d\n", cpu_affinity);
    
  2. 设置 CPU 亲和性

    object_property_set_int(OBJECT(tc), "cpu-affinity", 2, &error_abort);
    
9.4. 完整示例

以下是一个完整的示例,展示如何定义和使用 cpu-affinity 属性。

定义 ThreadContext
typedef struct ThreadContext {Object parent_obj;int cpu_affinity;
} ThreadContext;static void thread_context_class_init(ObjectClass *oc, void *data)
{UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);ucc->complete = thread_context_instance_complete;object_class_property_add(oc, "cpu-affinity", "int",thread_context_get_cpu_affinity,thread_context_set_cpu_affinity, NULL, NULL);
}static void thread_context_instance_init(Object *obj)
{ThreadContext *tc = THREAD_CONTEXT(obj);tc->cpu_affinity = 0; // 默认值
}static int thread_context_get_cpu_affinity(Object *obj, Error **errp)
{ThreadContext *tc = THREAD_CONTEXT(obj);return tc->cpu_affinity;
}static void thread_context_set_cpu_affinity(Object *obj, int value, Error **errp)
{ThreadContext *tc = THREAD_CONTEXT(obj);tc->cpu_affinity = value;
}static void thread_context_register_types(void)
{static const TypeInfo thread_context_info = {.name = TYPE_THREAD_CONTEXT,.parent = TYPE_OBJECT,.instance_size = sizeof(ThreadContext),.instance_init = thread_context_instance_init,.class_init = thread_context_class_init,};type_register_static(&thread_context_info);
}type_init(thread_context_register_types)
使用 ThreadContext
int main(int argc, char *argv[])
{ThreadContext *tc = THREAD_CONTEXT(object_new(TYPE_THREAD_CONTEXT));// 设置 CPU 亲和性object_property_set_int(OBJECT(tc), "cpu-affinity", 2, &error_abort);// 查询 CPU 亲和性int cpu_affinity = object_property_get_int(OBJECT(tc), "cpu-affinity", &error_abort);printf("Current CPU affinity: %d\n", cpu_affinity);object_unref(OBJECT(tc));return 0;
}
9.5小结

通过 object_class_property_add,您可以为 QEMU 的对象类添加属性,并通过回调函数实现对属性的访问和修改。在您的代码中,cpu-affinity 属性允许用户通过 QEMU 的命令行工具或 API 查询和设置线程的 CPU 亲和性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/90578.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/90578.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/90578.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Security架构与实战全解析

Spring security1.安全架构1. 认证who are you登陆系统&#xff1a;用户系统2. 授权权限管理&#xff1a;用户授权3. 攻击防护xss (cross-site scripting)csrf (cross-site request forgery)cors (cross-origin resource sharing)sql注入4. 扩展&#xff1a;权限管理模型a. RBA…

LeetCode Hot 100 搜索二维矩阵 II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a;每行的元素从左到右升序排列。每列的元素从上到下升序排列。示例 1&#xff1a;输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[…

Windows Edge 播放 H.265 视频指南

目录 &#x1f4cc;前言 一 . 什么是 H.265&#xff08;HEVC&#xff09;&#xff1f; 二、为什么 Edge 默认不能播放 H.265&#xff1f; 三、Edge 播放 H.265 解决方案 1 . 查看显卡是否支持硬解AMD GPU Decoder Device InformationNVIDIA GPU Decoder Device Informat…

线性代数--AI数学基础复习

原文链接&#xff1a;Github-Funny_Mr_Zhi GNN_playground 参考&#xff1a;麻省理工公开课 线性代数 MIT Linear Algebra Chapter1 可以带着问题去读&#xff0c;线性代数到底是什么&#xff0c;矩阵又是什么。尽管深入学习数学需要一种抽离出现实和直观理解的高度抽象思维&…

Cursor配置DeepSeek调用MCP服务实现任务自动化

文章目录1. 任务需求2. 环境准备2.1 Cursor安装2.2 Node.js安装2.3 DeepSeek模型Key申请2.4 高德地图Key申请3. MCP服务配置3.1 Cursor配置Server方式3.1.1全局设置3.1.2 项目级别设置3.2 MCP服务接入3.2.1 高德地图MCP服务3.2.2 Mysql MCP服务3.2.3 FileSystem MCP服务3.2.4 验…

java SpringBoot数据库查询 时间范围查询

exTime的类型为varchar 存储的数据格式为yyy-MM-ddTHH:mm:ss,查询时传进来的时间格式也需要为yyy-MM-ddTHH:mm:ss格式Query(value "SELECT * FROM test_fbep fbep WHERE delFlag 1 " "AND IF(?1 ! AND ?1 IS NOT NULL, fbep.passId ?1, TRUE) " &q…

Linux 操作系统如何实现软硬件解耦?从容器与硬件接口封装谈起

在计算机系统中&#xff0c;软硬件解耦是提升系统灵活性、可移植性和可维护性的核心设计思想。Linux 作为开源操作系统的典范&#xff0c;通过数十年的演进形成了一套成熟的解耦机制。本文将从容器技术和硬件接口封装两个维度&#xff0c;深入解析 Linux 如何实现软硬件解耦&am…

7月10号总结 (1)

今天开始写web项目&#xff0c;画了一下登录界面&#xff0c;借鉴了一下网上的资源。 <!DOCTYPE html> <html lang"zh.CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initi…

Docker 高级管理 -- 容器通信技术与数据持久化

目录 第一节:容器通信技术 一&#xff1a;Docker 容器的网络模式 1&#xff1a;Bridge模式 2&#xff1a;Host模式 3&#xff1a;Container模式 4&#xff1a;None模式 5&#xff1a;Overlay 模式 6&#xff1a;Macvlan 模式 7&#xff1a;自定义网络模式 二&#xff…

链路管理和命令管理

第1章 链路管理在通信领域&#xff0c;链路&#xff08;Link&#xff09; 是两个设备之间进行数据传输的物理或逻辑路径。例如&#xff1a;网络链路&#xff1a;TCP/IP 连接、UDP 通信、WebSocket串口链路&#xff1a;RS232、RS485、CAN 总线无线链路&#xff1a;蓝牙、Wi-Fi、…

BERT模型基本原理及实现示例

BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是Google在2018年提出的预训练语言模型&#xff0c;其核心思想是通过双向Transformer结构捕捉上下文信息&#xff0c;为下游NLP任务提供通用的语义表示。 一、模型架构BERT基于Transforme…

NPM组件包 json-cookie-csv 等窃取主机敏感信息

【高危】NPM组件包 json-cookie-csv 等窃取主机敏感信息 漏洞描述 当用户安装受影响版本的 json-cookie-csv 等NPM组件包时会窃取用户的主机名、用户名、工作目录、IP地址等信息并发送到攻击者可控的服务器地址。 MPS编号MPS-xo1f-4kue处置建议强烈建议修复发现时间2025-07-…

【Netty+WebSocket详解】WebSocket全双工通信与Netty的高效结合与实战

一、 Netty网络框架、WebSocket协议基础 1.1 Netty网络框架介绍 1.2 WebSocket简介 1.3 WebSocket握手流程 二、为什么选择NettyWebSocket&#xff1f; 三、NettyWebSocket与Spring WebSocket 3.1 架构层级对比 3.2 核心组件差异 3.3 协议支持深度 3.4 性能基准测试 3.5 开发…

5、Vue中使用Cesium实现交互式折线绘制详解

引言 Cesium是一款强大的开源3D地理信息可视化引擎&#xff0c;广泛应用于数字地球、地图可视化等领域。在Vue项目中集成Cesium可以快速构建高性能的地理信息应用。本文将详细介绍如何在Vue项目中实现交互式折线绘制功能&#xff0c;包括顶点添加、临时绘制、距离计算等核心功…

mysql实战之主从复制

原理图理论&#xff1a;一、配置准备每台主机都安装mysql对每台主机都进行对时操作&#xff0c;减少时间误差[rooteveryone ~]# timedatectl set-timezone Asia/Shanghai [rooteveryone ~]# systemctl restart chronyd.service 对每台主机都进行关闭防火墙、上下文等&#xff0…

中望CAD2026亮点速递(5):【相似查找】高效自动化识别定位

本文为CAD芯智库整理&#xff0c;未经允许请勿复制、转载&#xff01;原文转自&#xff1a;www.xwzsoft.com/h-nd-594.html CAD的相似查找功能主要应用于需要重复操作、标准化控制、一致性检查或复杂模式识别的场景&#xff0c;通过图形相似度算法&#xff0c;快速找到匹配的图…

国产化条码类库Spire.Barcode教程:使用 C# 读取二维码(QR Code)——从图片或数据流解析

二维码已成为现代应用的常见组成部分&#xff0c;广泛应用于用户身份验证、移动支付、商品包装和活动票务等场景。很多使用 C# 开发的系统需要从图像或扫描件中提取二维码信息&#xff0c;因此掌握二维码识别技术显得尤为重要。 为满足这类需求&#xff0c;开发者需要一种既可…

IPSAN 共享存储详解:架构、优化与落地实践指南

一、IPSAN 技术定位与核心价值核心价值对比矩阵&#xff1a;维度IPSANFC-SAN实现方案成本端口成本$500端口成本$2000复用IP网络设备传输距离跨地域&#xff08;VPN/专线&#xff09;≤10公里两地三中心架构运维效率SNMP/CLI管理Zone/ALPA管理自动化运维工具链协议标准IETF RFC …

【卫星语音】基于神经网络的低码率语音编解码(ULBC)方案架构分析:以SoundStream为例

摘要 随着深度学习技术的快速发展&#xff0c;基于神经网络的音频编解码技术已成为下一代音频压缩的重要研究方向。本文以Google提出的SoundStream为核心分析对象&#xff0c;深入探讨其在低码率语音编解码领域的创新架构设计和关键技术突破。SoundStream通过全卷积编解码器网络…

技术面试问题总结一

MySQL的几种锁机制一、从锁的粒度角度划分表级锁机制&#xff1a;它是对整张表进行锁定的一种锁。当一个事务对表执行写操作时&#xff0c;会获取写锁&#xff0c;在写锁持有期间&#xff0c;其他事务无法对该表进行读写操作&#xff1b;而当事务执行读操作时&#xff0c;会获取…