当前位置: 首页 > 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…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇&#xff0c;在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下&#xff1a; 【Note】&#xff1a;如果你已经完成安装等操作&#xff0c;可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作&#xff0c;重…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用

文章目录 问题现象问题原因解决办法 问题现象 macOS启动台&#xff08;Launchpad&#xff09;多出来了&#xff1a;Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显&#xff0c;都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...