当前位置: 首页 > news >正文

RCU安全引用计数

原文网址:https://lwn.net/Articles/93617

原文作者:Corbet

原文时间:2004年7月14日

内核提供了一种用于实现引用计数的简单机制kref;该机制是今年3月份完成的。kref机制的核心思想是,提供支持原子操作的计数器,用于对未决引用【outstanding references】进行计数。如果计数器数值为零,内核不再需要引用对象了,引用对象可以被释放掉。

kref机制的函数很简单,在引用对象数据结构内直接包含一个struct kref计数器或struct kref *计数器指针,在引用对象被操作之前调用kref_get函数,引用计数器递增。

struct kref *kref_get(struct kref *kref)
{WARN_ON(!atomic_read(&kref->refcount));atomic_inc(&kref->refcount);return kref;
}

在对对象操作完成之后调用kref_put函数,引用计数器递减,如果计数器数值为零,就调用回调函数释放引用对象相关资源。

void kref_put(struct kref *kref)
{if (atomic_dec_and_test(&kref->refcount)) {kref->release(kref);   //release函数是回调函数}
}

对引用计数refcount域进行原子操作,使得上述两个函数可以安全地在多CPU或抢断环境下直接调用,也就是说在这两个环境下,引用计数器的数值总能获得正确的结果。但是,如果两个内核线程在使用kref机制时,存在下面情况,kref机制也会出错。

内核线程1内核线程2
/* In kref_get() */
WARN_ON(!atomic_read(&kref->refcount));
kref_put(&kref);
atomic_inc(&kref->refcount);
return kref;

在上面的例子中,内核线程1在调用atomic_inc之前的那一刻,被引用对象的相关资源很可能被释放掉了。kref代码强制要求:对同一个引用对象不允许kref_get和kref_put并行运行。也就是说,这种强制性要求上述两个函数都需要用锁来避免对同一个引用对象的并行访问。

但是关注高可扩展性的程序员经常会使用免锁算法。因为在线程数量比较大的时候,锁往往会成为性能瓶颈,因此尽可能不用锁,内核的可扩展性会更好。这也是内核提供seqlock和RCU这两种技术的原因。kref机制对锁机制的需求,使得seqlock和RCU很难派上用途。

Ravikiran G Thirumalai最近提交了一份题为“Refcounting of objects part of a lockfree collection”的补丁,实现了一个新的锁机制refcount_t,用于对象的免锁管理。并用大量篇幅介绍了和RCU一起工作时引用计数过程,所有补丁构建了一种类似kref的数据类型,这种数据类型不需要用锁就能避免前面提到的竞争问题。

伴随并行写的过程【as currently written】,kref_get首先检查引用计数数值;如果计数数值为零,表示对象已经被释放了。当前的实现是,检查到数值为零时,仅仅是抱怨一下【我理解为信息输出,而不做更多的处理】;有人可能要说了,这种情况下应该做进一步的处理才好。然而,真正的问题是,对引用计数的测试和递增如果不能在一个原子操作中实现,那么在这两个操作之间就有可能插入其他操作。Ravikiran的补丁通过提供另一个XXXX_get函数来解决这个问题:

 static inline int refcount_get_rcu(refcount_t *rc){int c, old;c = atomic_read(&rc->count);while ( c && (old = cmpxchg(&rc->count.counter, c, c+1)) != c) c = old;return c;}

上面函数的核心是cmpxchg函数,这是一个内联汇编函数,可以直接使用CPU的cmpxchg指令。这个函数的原型是:

int cmpxchg(int *location, int old, int new);

cmpxchg函数实现了以下基本功能:

1)用原子操作实现:比较location内存单元数值和old变量数值;如果两者数值相等,将location内存单元设置为new变量数值。

2)如果上述原子操作成功,即判断两者数值相等后location内存单元被修改,cmpxchg函数返回old变量数值;如果上述原子操作不成功,cmpxchg返回location内存单元的数值。

cmpxchg指令是CPU提供的测试-设置原子指令。用cmpxchg实现的XXXX_get函数在不用锁的情况下就可以实现引用计数器的获取。

这里还是有点小问题。考虑一种情况:内核线程2对引用计数对象释放后又重新使用该对象,然后内核线程1才试图去获取引用计数。在这种情况下,内核线程1可能看到的是一个随机的引用计数,就误以为成功获取了引用计数。引入RCU机制,可以避免这种情况发生。引用对象的释放是通过RCU回调函数来实现;这样一来,引用对象就不会被真正释放直到每一个处理器都发生了调度。只要内核线程能通过指针找到引用对象,那么这个对象就一直存在,即使对象的引用计数数值为零。经过一个完整静默期,没有内核线程去访问这样的指针了,引用对象才会被安全地删除。

另一个潜在的问题是,并不是所有的体系结构都提供cmpxchg原子指令。针对这样的系统,Ravikiran用到了一个从未见过但相当巧妙的方案,用到了自旋锁的哈希数组;如果你们好奇就自己去看补丁好了。

这些努力都是值得的;这个技术已经用于文件描述符查找了,tiobench测试性能提高了13% ~ 21%。内核系统里还有类似kref API一样的对象,也有创建新的引用计数API。因此,补丁还可能会重写。

相关文章:

RCU安全引用计数

原文网址:https://lwn.net/Articles/93617 原文作者:Corbet 原文时间:2004年7月14日 内核提供了一种用于实现引用计数的简单机制kref;该机制是今年3月份完成的。kref机制的核心思想是,提供支持原子操作的计数器&…...

Linux 可重入、异步信号安全和线程安全

可重入函数 当一个被捕获的信号被一个进程处理时,进程执行的普通的指令序列会被一个信号处理器暂时地中断。它首先执行该信号处理程序中的指令。如果从信号处理程序返回(例如没有调用exit或longjmp),则继续执行在捕获到信号时进程…...

WPF中手写地图控件(3)——动态加载地图图片

瓦片增加一个Loading动画 可以查看我的另一个博客WPF中自定义Loading图 从中心扩散 进行从里到外的扩散,方向是上左下右。如下图所示 于是我们可以定义一个拥有坐标X跟Y的集合,他允许这个集合,内部使用枚举器的MoveNext自动排序&#xf…...

智慧充电桩物联网方案架构

智慧充电桩物联网采用“云-管-边-端”的边缘计算物联网架构,融合5G、AI、Wi-Fi 6等技术,实现充电基础设施由数字化向智能化演进。智慧充电桩物联网方案架构设计,如下图所示: 云端: 物联网平台具备广泛协议的南向接入…...

C语言基础之——操作符(上)

本篇文章,我们将展开讲解C语言中的各种常用操作符,帮助大家更容易的解决一些运算类问题。 这里提醒一下小伙伴们,本章知识会大量涉及到二进制序列,不清楚二进制序列的小伙伴,可以去阅读我的另一篇文章《数据在内存中的…...

手写链式调用

遇到一个有趣的题目,做个笔记 实现一个arrange函数,可以进行时间和工作调度 //[> …]表示调用函数后的打印内容 //arrange(‘William’).execute(); //> William is notified //arrange(‘William’).do(‘commit’).execute(); //>William …...

DETRs with Collaborative Hybrid Assignments Training论文笔记

Title:[DETRs with Collaborative Hybrid Assignments Training Code 文章目录 1. Motivation2. one to one VS one to many3. Method(1)Encoder feature learning(2)Decoder attention learning 1. Motivation 当前…...

慧程HiperM3系列工业物联网、MES平台

产品链接:慧程产品主页...

SHELL 基础 入门(三) Bash 快捷键 命令执行顺序,详解通配符

目录 Bash 常用快捷键 输入输出重定向 << 用法 输出重定向 命令执行顺序 ; 分号 && || 通配符 传统通配符 &#xff1f; * [ ] [ - ] [ ^ ] 常用字符 强调 &#xff1a; { } 生成序列 Bash 常用快捷键 Ctrl A 把光…...

nvm安装使用教程

文章目录 下载配置安装最新稳定版 node安装指定版本查看版本切换版本删除版本 常见问题安装node后 显示拒绝访问的问题使用cnpm会报错的问题降低cnpm版本npm镜像 下载 NVM for Windows 下载地址&#xff1a;https://link.juejin.cn/?targethttps%3A%2F%2Fgithub.com%2Fcoreyb…...

【Android】JUnit和Espresso单元测试新手快速入门

引入依赖 android {defaultConfig {testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"}}dependencies {testImplementation junit:junit:4.13.2androidTestImplementation androidx.test.ext:junit:1.1.0androidTestImplementation androidx.tes…...

8.4 【C语言】通过指针引用字符串

8.4.1 字符串的引用方式 在C程序中&#xff0c;字符串是存放在字符数组中的。想引用一个字符串&#xff0c;可以用以下两种方法。 &#xff08;1&#xff09;用字符数组存放一个字符串&#xff0c;可以通过数组名和下标引用字符串中一个字符&#xff0c;也可以通过数组名和格…...

【广州华锐视点】AR配电所巡检系统:可视化巡检利器

随着科技的发展&#xff0c;人工智能、大数据等技术逐渐应用于各个领域&#xff0c;为人们的生活带来便利。在电力行业&#xff0c;AR(增强现实)技术的应用也日益广泛。AR配电所巡检系统作为一种新型的巡检方式&#xff0c;可以实现多种功能&#xff0c;提高巡检效率&#xff0…...

微服务中间件--http客户端Feign

http客户端Feign http客户端Feigna.Feign替代RestTemplateb.自定义Feign的配置c.Feign的性能优化d.Feign的最佳实践分析e.Feign实现最佳实践(方式二) http客户端Feign a.Feign替代RestTemplate 以前利用RestTemplate发起远程调用的代码&#xff1a; String url "http:…...

C语言学习系列-->【关于qsort函数的详解以及它的模拟实现】

文章目录 一、概述二、qsort函数参数介绍三、qsort实现排序3.1 qsort实现整型数组排序3.2 qsort实现结构体数组排序 四、模拟实现qsort函数 一、概述 对数组的元素进行排序 对数组中由 指向的元素进行排序&#xff0c;每个元素字节长&#xff0c;使用该函数确定顺序。 此函数使…...

Linux系统安全:NAT(SNAT、DNAT)

目录 一.NAT 二.SNAT 三.DNAT 一.NAT NAT: network address translation&#xff0c;支持PREROUTING&#xff0c;INPUT&#xff0c;OUTPUT&#xff0c;POSTROUTING四个链 请求报文&#xff1a;修改源/目标IP&#xff0c; 响应报文&#xff1a;修改源/目标IP&#xff0c;根据…...

【数据库】MySQL存储过程:提升数据库性能和操作效率的利器

在数据库管理系统中&#xff0c;存储过程是一种重要的数据库对象&#xff0c;它允许将一组复杂的SQL语句组合起来&#xff0c;形成一个独立的单元进行重复使用。存储过程可以极大地提高数据库的性能和操作效率&#xff0c;降低网络流量&#xff0c;减轻系统负载。本文将深入探讨…...

rust写一个多线程和协程的例子

当涉及到多线程和协程时&#xff0c;Rust提供了一些非常强大的工具&#xff0c;其中最常用的库之一是tokio&#xff0c;它用于异步编程和协程。下面我将为你展示一个简单的Rust程序&#xff0c;演示如何使用多线程和协程。 首先&#xff0c;你需要在你的项目的Cargo.toml文件中…...

react18+antd5.x(1):Notification组件的二次封装

antdesign已经给我们提供了很好的组件使用体验,但是我们还需要根据自己的项目业务进行更好的封装,减少我们的代码量,提升开发体验 效果展示 开起来和官网的使用没什么区别,但是我们在使用的时候,进行了二次封装,更利于我们进行开发 MyNotification.jsx,是我们的业务页面…...

jenkins运行pytest测试用例脚本报错:没有权限,无法写日志PermissionError:[Error 13]Permission denied

报错信息&#xff1a; PermissionError:[Error 13]Permission denied&#xff1a;‘/var/jenkins_home/workspace/deleverySystem/Delivery_System/out_files/logs/waimai_20230823.log’ 解决方法&#xff1a; 在jenkins容器内部输入 chmod -R 777 /var/jenkins_home/works…...

为什么92%的Sora 2初学者卡在第4步?——帧一致性崩塌诊断工具包+时间轴锚点校准法

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Sora 2视频生成的核心原理与环境准备 Sora 2并非OpenAI官方发布的模型&#xff0c;而是社区基于Sora技术理念构建的开源复现与增强框架&#xff0c;其核心依托于时空联合建模的扩散变换器&#xff08;Spacetim…...

2026年,本地精准营销高性价比服务商来袭,你还不了解一下?

在本地商业竞争日益激烈的2026年&#xff0c;实体店面临着诸多挑战&#xff0c;引流难、成本高、复购率低等问题困扰着众多商家。而中粤&#xff08;广州&#xff09;信息科技有限公司作为本地精准营销的高性价比服务商&#xff0c;正以其独特的优势和卓越的服务&#xff0c;为…...

CausalVLR基准测试报告:在IU X-Ray和MIMIC-CXR数据集上的性能分析

CausalVLR基准测试报告&#xff1a;在IU X-Ray和MIMIC-CXR数据集上的性能分析 【免费下载链接】CausalVLR CausalVLR: A Toolbox and Benchmark for Vision-Language Causal Reasoning (多模态因果推理开源框架) 项目地址: https://gitcode.com/gh_mirrors/ca/CausalVLR …...

Adobe-GenP 3.0:轻松激活Adobe全家桶的完整指南

Adobe-GenP 3.0&#xff1a;轻松激活Adobe全家桶的完整指南 【免费下载链接】Adobe-GenP Adobe CC 2019/2020/2021/2022/2023 GenP Universal Patch 3.0 项目地址: https://gitcode.com/gh_mirrors/ad/Adobe-GenP Adobe-GenP 3.0是一款专为Adobe Creative Cloud系列软件…...

在线文档协作工具选型必看:14款产品对比(2026版)

一、在线文档协作工具的概念解析及其核心功能 在线文档协作工具是基于云端的文档创建、编辑、共享与协同沟通平台&#xff0c;核心目标是让团队在同一份资料上“实时共同工作”&#xff0c;减少反复传文件、版本混乱与沟通成本。 企业常见的核心能力包括&#xff1a; 多人实…...

圈复杂度>12=技术债炸弹?DeepSeek静态分析实战:从17.8→3.2的重构路径全披露

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;圈复杂度&#xff1e;12技术债炸弹&#xff1f;DeepSeek静态分析实战&#xff1a;从17.8→3.2的重构路径全披露 当函数圈复杂度&#xff08;Cyclomatic Complexity&#xff09;持续高于12&#xff0c;它不再是…...

告别漫长等待:UE5.2.1 Windows打包效率优化与插件问题排查指南

告别漫长等待&#xff1a;UE5.2.1 Windows打包效率优化与插件问题排查指南第一次点击"打包项目"按钮时&#xff0c;进度条仿佛被冻结的场景&#xff0c;每个UE5开发者都经历过。尤其当项目规模达到数十GB时&#xff0c;等待时间可能超过一小时——这背后隐藏着引擎底…...

机器学习的最佳实践:这7个原则让你的模型更稳定

对于软件测试从业者而言&#xff0c;机器学习技术正在快速融入测试流程&#xff1a;从自动化测试用例生成、缺陷预测到测试环境异常检测&#xff0c;机器学习模型的稳定性直接决定了测试结果的可靠性——如果模型在测试环境波动、输入数据变化时性能骤降&#xff0c;不仅无法提…...

别再纠结了!给激光焊接新手讲透单模和多模激光到底怎么选(附M²因子解读)

激光焊接设备选型指南&#xff1a;单模与多模激光的实战抉择 当你第一次站在激光焊接设备采购的十字路口&#xff0c;面对"单模"和"多模"这两个专业术语时&#xff0c;那种迷茫感我深有体会。五年前&#xff0c;我作为产线技术负责人&#xff0c;需要为汽车…...

告别RaiDrive广告!用开源rclone+Alist,免费把阿里云盘/百度网盘变成电脑本地硬盘

开源方案实战&#xff1a;用rcloneAlist打造无广告的云盘本地化体验 每次打开RaiDrive时弹出的广告窗口是否让您感到困扰&#xff1f;商业软件的收费模式是否让您犹豫不决&#xff1f;今天&#xff0c;我们将彻底解决这些问题。通过开源工具Alist和rclone的组合&#xff0c;您不…...