自动持有自旋锁时返回是否不安全?

2024-04-20

受人尊敬的书

The flags参数传递给spin_unlock_irqrestore必须与传递给的变量相同spin_lock_irqsave. 您还必须致电spin_lock_irqsave and spin_unlock_irqrestore在同一功能中;否则你的代码可能会在某些架构上崩溃。

但我找不到任何此类限制与内核代码本身捆绑在一起的官方文档 https://www.kernel.org/doc/Documentation/locking/spinlocks.txt。我发现违反本指南的驱动程序代码 https://github.com/ToshibaSemiconductor/TJET/blob/master/tjet-driver/src/os/linux/syscall/cmn_lock.c#L231.

显然打电话不是一个好主意spin_lock_irqsave and spin_unlock_irqrestore来自单独的函数,因为您应该最大限度地减少持有锁时完成的工作(禁用中断,同样如此!)。但是,如果小心翼翼地进行的话,对内核的更改是否可以实现这一点,它实际上从未违反 API 合同,还是仍然禁止这样做?

如果限制在某个时候被删除,它是否适用于版本 3.10.17?


这只是一个猜测,但可能不清楚地指的是如果您尝试使用可能发生的潜在错误nonlocal变量或存储位置flags.

基本上,flags必须是当前执行上下文私有的,这就是为什么spin_lock_irqsave是一个宏,其名称为flags. While flags正在保存,您还没有自旋锁。

这与不同函数中的锁定和解锁有何关系:

考虑一些驱动程序开发人员可能编写的两个函数:

void my_lock(my_object *ctx)
{
  spin_lock_irqsave(&ctx->mylock, ctx->myflags);  /* BUG */
}

void my_unlock(my_object *ctx)
{
  spin_unlock_irqrestore(&ctx->mylock, ctx->myflags);
}

这是一个错误,因为当时ctx->myflags已写入,锁尚未持有,并且它是对其他上下文和处理器可见的共享变量。本地标志必须保存到堆栈上的私有位置。然后,当调用者拥有锁时,可以将标志的副本保存到独占拥有的对象中。换句话说,它可以这样修复:

void my_lock(my_object *ctx)
{
  unsigned long flags;
  spin_lock_irqsave(&ctx->mylock, flag);
  ctx->myflags = flags;
}

void my_unlock(my_object *ctx)
{
  unsigned long flags = ctx->myflags; /* probably unnecessary */
  spin_unlock_irqrestore(&ctx->mylock, flags); 
}

如果不能像这样修复它,那么实现需要包装 IRQ 自旋锁的更高级别原语将非常困难。

它如何依赖于拱门:

假设spin_lock_irqsave扩展为机器代码,将当前标志保存在某个寄存器中,then获取锁,并且then将该寄存器保存到指定的flags目的地。在这种情况下,有错误的代码实际上是安全的。如果扩展代码将标志保存到实际的flags调用者指定的对象,然后尝试获取锁,然后它就被破坏了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

自动持有自旋锁时返回是否不安全? 的相关文章

  • simple_read_from_buffer/simple_write_to_buffer 与 copy_to_user/copy_from_user

    我最近编写了一个实现这些功能的模块 两者有什么区别 据我了解 copy user功能更加安全 如果我错了 请纠正我 此外 将这两个功能混合在一个程序中是不是一个坏主意 例如 我用过simple read from buffer在我的杂项开发
  • 将内核内置模块替换为可加载模块

    我开发了一个内核模块来管理 nf4 标签作为字符设备 我在内核之外开发了这个模块 并在开发阶段将其编译为可加载内核模块 即 ko 进行了测试 一旦驱动程序功能正常且足够稳定 我就使用补丁将其插入 Linux 内核源代码 v4 9 30 以便
  • 开放固件设备树概述/参考手册

    我正在尝试为嵌入式 PowerPC 板设置驱动程序 今天执行此操作的正确方法是使用 OpenFirmware 设备树数据结构 dtb 文件 从 dts 文件编译 创建树非常简单 但是如何让我的设备驱动程序找到它的节点和其中的数据 我还没有找
  • Kubernetes Node 中的内核内存使用率较高

    我非常绝望地寻找解决方案 我正在 AWS 上运行 Kubernetes 集群 v1 16 7 节点规格为 它是一个亚马逊 EC2 t3 medium实例与4GB RAM和 AMI k8s 1 11 debian stretch amd64
  • ARM Cortex A8 PMNC 读取在启用后也给出 0.. 有什么想法/建议吗?

    MODULE LICENSE GPL MODULE DESCRIPTION user mode access to performance registers int init arm init void unsigned int valu
  • 内核虚拟地址转换

    考虑到 Linux 和 32 位 x86 架构 可访问的 4GB 地址空间的比例为 3 1 用户空间分配0 3 Gb 而3 4 Gb 分配给内核 大于 3Gb 且位于内核地址空间的虚拟地址如何转换为物理地址 页表会出现吗 梅尔 戈尔曼的书中
  • 为什么函数 printk() 不使用逗号来分隔参数?

    一个例子printk call printk KERN INFO Log message n 也许这个问题更多地是关于C的 因为我之前从未见过C中的函数可以不用逗号分隔参数 这是如何运作的 编译器如何处理这些信息 由于日志级别是一个整数 而
  • 自动持有自旋锁时返回是否不安全?

    受人尊敬的书说 The flags参数传递给spin unlock irqrestore必须与传递给的变量相同spin lock irqsave 您还必须致电spin lock irqsave and spin unlock irqrest
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • Linux 内核:为什么调用 kstrtol 会崩溃?

    我正在学习内核编程 并且对 kstrtol 进行了简单的调用 我用它来将字符串转换为数字 然而 每次我编译这个模块并使用 insmod 将其放入内核时 我都会收到 BUG 无法处理 f862b026 处的内核分页请求 然后是寄存器和堆栈转储
  • I2C 驱动程序应如何在 ACPI 中与 HID PRP0001 匹配

    我正在尝试实例化这个传感器 https elixir bootlin com linux v5 2 source drivers iio proximity vl53l0x i2c c在 ACPI 中使用设备特定数据 即Name DSD 并
  • USB 端口速度 Linux [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何以编程方式确定运行 Linux 内核的嵌入式设备中的 USB 端口速度 你可以阅读 sys bus usb devices usb s
  • dmesg 和 /var/log/kern.log 之间的区别

    我正在修改kvm模块 并在内核代码中添加了printk语句 运行虚拟机后 printk为我提供了错误地址和有关客户操作系统的其他信息 我需要根据此信息生成统计信息 当我使用 dmesg 时 我只能看到错误地址 在内核空间中 即它们的地址高于
  • 如何编写需要内核源头文件的 BitBake 驱动程序配方?

    介绍 我有一个do install我为驱动程序编写的 BitBake 配方中的任务 我在其中执行自定义install脚本 任务失败 因为安装脚本无法在其中找到内核源头文件
  • 使用Linux虚拟鼠标驱动

    我正在尝试实施一个虚拟鼠标驱动程序根据基本 Linux 设备驱动程序书 有一个用户空间应用程序 它生成坐标以及内核模块 See 虚拟鼠标驱动程序和用户空间应用程序代码 http www embeddedlinux org cn Essent
  • “do { ... } while (0)”在内核代码中到底做了什么? [复制]

    这个问题在这里已经有答案了 可能的重复 当我们定义宏时 do while 0 有什么用 https stackoverflow com questions 923822 whats the use of do while0 when we
  • 内存地址是否指向一个字节的信息?

    以下是 DTS 文件的摘录 linux arch powerpc boot dts 板名 dts memory device type memory reg lt 0x00000000 0x40000000 gt 1GB at 0 嵌入式设
  • 如何在 Linux x86_64 上模拟 iret

    我正在编写一个基于 Intel VT 的调试器 由于当 NMI Exiting 1 时 iret 指令在 vmx guest 中的性能发生了变化 所以我应该自己处理vmx主机中的NMI 否则 guest会出现nmi可重入错误 我查了英特尔手
  • modinfo srcversion:如何从我的源生成此版本?

    我有一个 Linux 模块的编译版本 然后我有大约 20 多个其源代码的变体 由于各种愚蠢的错误 我已经不知道哪个版本的源代码是我用来制作模块的实际版本了 我注意到modinfo
  • 了解 U-Boot 内存占用

    我不明白加载 U Boot 时 RAM 中发生了什么 我正在开发 Xilinx Zynq ZC702 评估套件 并尝试使用 U Boot 在其上加载 Linux 内核 于是我使用Xilinx工具Vivado和SDK生成了一个BOOT bin

随机推荐

  • 如何确定使用哪种认证方式?

    我想知道 我如何确定正在使用哪种身份验证方法 例如 如果我的身份验证基于 FORMS 身份验证 而不是 WINDOWS 身份验证 我想执行代码 您可以使用配置管理器检查网络配置上的内容 ConfigurationManager GetSec
  • 停放正在使用的线程

    我正在尝试线程停放并决定构建某种服务 它是这样的 public class TestService private static final Logger logger LoggerFactory getLogger TestService
  • 如何使用引脚和选项卡像 Delphi IDE 一样进行拖动和停靠?

    我想让 拖放 和 停靠 在我的应用程序中像在 Delphi IDE 中一样工作 即能够在对象检查器 结构视图周围拖动并将它们停靠在合适的位置 我在将表单对接到 PageControl 方面取得了相当大的成功 但想知道是否有人知道如何让它与小
  • 如何更改 Hybris 站点地图 XML 中的本地主机 URL

    我正在尝试通过开箱即用的方式为我的 Hybris 站点创建一个 sitemap xml 并复制我的 site impex 中开箱即用商店中给出的 ImpEx 如何更改 Hybris 站点地图 XML 中的本地主机 URL 运行 cronjo
  • 如何在 CDI 中动态创建实例

    假设我有一个汽车课程 在我的代码中我想创建 10 辆汽车 汽车类有一些 Inject带注释的依赖项 做到这一点的最佳方法是什么 CDI 有一个Provider我可以用它来创建汽车的界面 Inject Provider
  • 在 java 中返回多个原始对象。不推荐?

    我刚刚开始学习 Java 的 OOP 编程 我已经用 C 编写过一些程序 而我在 Java 中最怀念的事情之一就是可以返回多个值 确实 C 函数仅严格返回一个变量 但我们可以使用按引用参数返回更多变量 相反 在Java中我们不能做这样的事情
  • 预测误差指标的差距是什么:MAPE 和 WMAPE?

    我知道 MAPE 和 WMAPE 作为预测误差指标 它们有一些好处 但差距是什么 有人说 For MAPE Combinations with very small or zero volumes can cause large skew
  • Treeview——如何滚动直到所选项目位于顶部?

    我正在开发个人文件浏览器应用程序一年 我正在尝试关注我选择的文件夹 例如 如果我说我的默认文件夹是 C Users Me 那么它会自动展开 C 然后是 Users 等等 最后 我选择了 我 文件夹 我没有设法滚动到 自动 这样我就可以在我的
  • 带有异步等待的 chrome.runtime.onMessage 响应

    我想在 onMessage 侦听器中使用异步等待 chrome runtime onMessage addListener async request sender sendResponse gt var key await getKey
  • 简要说明:JDBC 是如何工作的? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 访问对象中的属性[重复]

    这个问题在这里已经有答案了 可能的重复 JavaScript 属性访问 点符号与方括号 https stackoverflow com questions 4968406 javascript property access dot not
  • 如何撤消“git重置”?

    如何撤消该命令 git reset HEAD 简短回答 git reset HEAD 1 长答案 Git 保留所有引用更新的日志 例如 签出 重置 提交 合并 您可以通过输入以下内容来查看它 git reflog 此列表中的某个位置是您丢失
  • 使用 C++ 的音频流教程和示例代码 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我想学习音频流的基础知识 特别是 我
  • 在 Protractor 中定位父元素的推荐方法

    根据最新公布的时尚指南 https github com angular protractor blob master docs style guide md never use xpath 使用by xpath 定位器被认为是一种不好的做
  • Qt5 链接器错误:找不到版本“Qt_5”

    1 问题 我正在尝试构建开源motorcar https github com evil0sheep motorcar在 Arch Linux 机器上从头开始项目 Motorcar 是一款 Linux VR 窗口管理器 可与 Oculus
  • 无法打开原子

    我无法打开 Atom 编辑器 昨天还好好的 今天不知道为什么打不开了 我的电脑上没有 Windows 更新或任何东西 我尝试删除一些在线论坛中提到的 存储 文件夹 但没有帮助 有什么建议么 我使用的是 Atom 版本 1 19 6 0 如果
  • Kafka 连接教程停止工作

    我在此链接中执行了步骤 7 使用 Kafka Connect 导入 导出数据 http kafka apache org documentation html quickstart http kafka apache org documen
  • 链接描述文件未按预期跳过字节

    因此 我有这个汇编文件 我使用 GNU as 进行汇编 并使用链接器脚本与 GNU ld 进行链接 链接描述文件 boot ld INPUT boot o OUTPUT boot out ENTRY boot start SECTIONS
  • 并行处理 vec:如何安全地进行,或者不使用不稳定的功能?

    我有一个巨大的向量 我希望能够并行加载 操作 例如在一个线程中加载前十万个索引 然后在另一个线程中加载下一个索引 依此类推 由于这将是代码中非常热门的部分 因此我提出了以下概念验证不安全代码来在不使用 Arcs 和互斥体的情况下执行此操作
  • 自动持有自旋锁时返回是否不安全?

    受人尊敬的书说 The flags参数传递给spin unlock irqrestore必须与传递给的变量相同spin lock irqsave 您还必须致电spin lock irqsave and spin unlock irqrest