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

Linux 软raid - - Barrier

什么是Barriers

在linux软raid中,用来处理正常IO和同步IO的并发问题,可以简单理解为专用于软raid的锁。

软raid在做resync/recovery,或者配置操作时需要raise 屏障,于此同时必须暂停正常IO。
barrier是可以被多次raise的一个计数器,来计算有多少个相关活动事件在发生,其中不包括正常IO。

raise 屏障的条件是没有pending的IO即nr_pending=0。

只有在没有人等待barrier down的情况下,才会选择raise barrier。这意味着,一旦IO请求准备就绪,在IO请求有机会之前,不会启动其他需要屏障的操作。

常规IO调用“wait_barrier”。当返回时,没有后台组IO发生,它必须安排在完成IO后调用allow_barrier。

后台组IO调用必须调用raise_barrier。一旦返回,就没有正常的IO发生。它必须安排在特定后台IO完成时调用lower_barrier。

/* Barriers....* Sometimes we need to suspend IO while we do something else,* either some resync/recovery, or reconfigure the array.* To do this we raise a 'barrier'.* The 'barrier' is a counter that can be raised multiple times* to count how many activities are happening which preclude* normal IO.* We can only raise the barrier if there is no pending IO.* i.e. if nr_pending == 0.* We choose only to raise the barrier if no-one is waiting for the* barrier to go down.  This means that as soon as an IO request* is ready, no other operations which require a barrier will start* until the IO request has had a chance.** So: regular IO calls 'wait_barrier'.  When that returns there*    is no backgroup IO happening,  It must arrange to call*    allow_barrier when it has finished its IO.* backgroup IO calls must call raise_barrier.  Once that returns*    there is no normal IO happeing.  It must arrange to call*    lower_barrier when the particular background IO completes.*/

相关数据结构

用来描述软raid配置相关的所有信息。

struct r1conf {struct mddev		*mddev;struct raid1_info	*mirrors;	/* twice 'raid_disks' to* allow for replacements.*/int			raid_disks;spinlock_t		device_lock;/* list of 'struct r1bio' that need to be processed by raid1d,* whether to retry a read, writeout a resync or recovery* block, or anything else.*/struct list_head	retry_list;/* A separate list of r1bio which just need raid_end_bio_io called.* This mustn't happen for writes which had any errors if the superblock* needs to be written.*/struct list_head	bio_end_io_list;/* queue pending writes to be submitted on unplug */struct bio_list		pending_bio_list;int			pending_count;/* for use when syncing mirrors:* We don't allow both normal IO and resync/recovery IO at* the same time - resync/recovery can only happen when there* is no other IO.  So when either is active, the other has to wait.* See more details description in raid1.c near raise_barrier().*/wait_queue_head_t	wait_barrier;spinlock_t		resync_lock;atomic_t		nr_sync_pending;atomic_t		*nr_pending;atomic_t		*nr_waiting;atomic_t		*nr_queued;atomic_t		*barrier;int			array_frozen;/* Set to 1 if a full sync is needed, (fresh device added).* Cleared when a sync completes.*/int			fullsync;/* When the same as mddev->recovery_disabled we don't allow* recovery to be attempted as we expect a read error.*/int			recovery_disabled;/* poolinfo contains information about the content of the* mempools - it changes when the array grows or shrinks*/struct pool_info	*poolinfo;mempool_t		r1bio_pool;mempool_t		r1buf_pool;struct bio_set		bio_split;/* temporary buffer to synchronous IO when attempting to repair* a read error.*/struct page		*tmppage;/* When taking over an array from a different personality, we store* the new thread here until we fully activate the array.*/struct md_thread	*thread;/* Keep track of cluster resync window to send to other* nodes.*/sector_t		cluster_sync_low;sector_t		cluster_sync_high;};

在当前的例子中,我们需要关注3个成员。

  • nr_pending
    正在处理的正常IO
  • nr_waitting
    等待同步完成的正常IO
  • barrier
    正在处理的同步IO

相关内核函数

raise_barrier

raise_barrier只有在同步IO的场景下raid1_sync_request才会被调用,这就意味着,只有等待正常IO完成之后,才能把屏障加起来。

static sector_t raise_barrier(struct r1conf *conf, sector_t sector_nr)
{int idx = sector_to_idx(sector_nr);	// 获取在bucket中的index。spin_lock_irq(&conf->resync_lock);/* Wait until no block IO is waiting */wait_event_lock_irq(conf->wait_barrier,!atomic_read(&conf->nr_waiting[idx]),conf->resync_lock);/* block any new IO from starting */atomic_inc(&conf->barrier[idx]);/** In raise_barrier() we firstly increase conf->barrier[idx] then* check conf->nr_pending[idx]. In _wait_barrier() we firstly* increase conf->nr_pending[idx] then check conf->barrier[idx].* A memory barrier here to make sure conf->nr_pending[idx] won't* be fetched before conf->barrier[idx] is increased. Otherwise* there will be a race between raise_barrier() and _wait_barrier().*/smp_mb__after_atomic();	// 内存屏障。/* For these conditions we must wait:* A: while the array is in frozen state* B: while conf->nr_pending[idx] is not 0, meaning regular I/O*    existing in corresponding I/O barrier bucket.* C: while conf->barrier[idx] >= RESYNC_DEPTH, meaning reaches*    max resync count which allowed on current I/O barrier bucket.*/wait_event_lock_irq(conf->wait_barrier,(!conf->array_frozen &&!atomic_read(&conf->nr_pending[idx]) &&atomic_read(&conf->barrier[idx]) < RESYNC_DEPTH) ||test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery),conf->resync_lock);if (test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {atomic_dec(&conf->barrier[idx]);spin_unlock_irq(&conf->resync_lock);wake_up(&conf->wait_barrier);return -EINTR;}atomic_inc(&conf->nr_sync_pending);spin_unlock_irq(&conf->resync_lock);return 0;
}

wait_barrier

wait_barrier只有在向下发写请求raid1_write_request时被调用,如果此时对应的磁盘扇区存在barrier,nr_waiting会被添加,表示同一时刻,同一扇区存在同步IO。

static void _wait_barrier(struct r1conf *conf, int idx)
{/** We need to increase conf->nr_pending[idx] very early here,* then raise_barrier() can be blocked when it waits for* conf->nr_pending[idx] to be 0. Then we can avoid holding* conf->resync_lock when there is no barrier raised in same* barrier unit bucket. Also if the array is frozen, I/O* should be blocked until array is unfrozen.*/atomic_inc(&conf->nr_pending[idx]);/** In _wait_barrier() we firstly increase conf->nr_pending[idx], then* check conf->barrier[idx]. In raise_barrier() we firstly increase* conf->barrier[idx], then check conf->nr_pending[idx]. A memory* barrier is necessary here to make sure conf->barrier[idx] won't be* fetched before conf->nr_pending[idx] is increased. Otherwise there* will be a race between _wait_barrier() and raise_barrier().*/smp_mb__after_atomic();/** Don't worry about checking two atomic_t variables at same time* here. If during we check conf->barrier[idx], the array is* frozen (conf->array_frozen is 1), and chonf->barrier[idx] is* 0, it is safe to return and make the I/O continue. Because the* array is frozen, all I/O returned here will eventually complete* or be queued, no race will happen. See code comment in* frozen_array().*/if (!READ_ONCE(conf->array_frozen) &&!atomic_read(&conf->barrier[idx]))return;/** After holding conf->resync_lock, conf->nr_pending[idx]* should be decreased before waiting for barrier to drop.* Otherwise, we may encounter a race condition because* raise_barrer() might be waiting for conf->nr_pending[idx]* to be 0 at same time.*/spin_lock_irq(&conf->resync_lock);atomic_inc(&conf->nr_waiting[idx]);atomic_dec(&conf->nr_pending[idx]);/** In case freeze_array() is waiting for* get_unqueued_pending() == extra*/wake_up(&conf->wait_barrier);/* Wait for the barrier in same barrier unit bucket to drop. */wait_event_lock_irq(conf->wait_barrier,!conf->array_frozen &&!atomic_read(&conf->barrier[idx]),conf->resync_lock);atomic_inc(&conf->nr_pending[idx]);atomic_dec(&conf->nr_waiting[idx]);spin_unlock_irq(&conf->resync_lock);
}static void wait_barrier(struct r1conf *conf, sector_t sector_nr)
{int idx = sector_to_idx(sector_nr);_wait_barrier(conf, idx);
}

wait_read_barrier

wait_read_barrier只有在下发IO读请求时被调用raid1_write_request,读请求入口将对应的bio状态置为pending状态,如果raid处于非frozen状态,直接返回。

static void wait_read_barrier(struct r1conf *conf, sector_t sector_nr)
{int idx = sector_to_idx(sector_nr);/** Very similar to _wait_barrier(). The difference is, for read* I/O we don't need wait for sync I/O, but if the whole array* is frozen, the read I/O still has to wait until the array is* unfrozen. Since there is no ordering requirement with* conf->barrier[idx] here, memory barrier is unnecessary as well.*/atomic_inc(&conf->nr_pending[idx]);if (!READ_ONCE(conf->array_frozen))return;spin_lock_irq(&conf->resync_lock);atomic_inc(&conf->nr_waiting[idx]);atomic_dec(&conf->nr_pending[idx]);/** In case freeze_array() is waiting for* get_unqueued_pending() == extra*/wake_up(&conf->wait_barrier);/* Wait for array to be unfrozen */wait_event_lock_irq(conf->wait_barrier,!conf->array_frozen,conf->resync_lock);atomic_inc(&conf->nr_pending[idx]);atomic_dec(&conf->nr_waiting[idx]);spin_unlock_irq(&conf->resync_lock);
}

lower_barrier

static void lower_barrier(struct r1conf *conf, sector_t sector_nr)
{int idx = sector_to_idx(sector_nr);BUG_ON(atomic_read(&conf->barrier[idx]) <= 0);atomic_dec(&conf->barrier[idx]);atomic_dec(&conf->nr_sync_pending);wake_up(&conf->wait_barrier);
}

相关文章:

Linux 软raid - - Barrier

什么是Barriers 在linux软raid中&#xff0c;用来处理正常IO和同步IO的并发问题&#xff0c;可以简单理解为专用于软raid的锁。 软raid在做resync/recovery&#xff0c;或者配置操作时需要raise 屏障&#xff0c;于此同时必须暂停正常IO。 barrier是可以被多次raise的一个计数…...

航空公司管理系统(迷你版12306)

要求 今天分享一个之前辅导留学生的作业&#xff0c;作业要求如下&#xff1a; Project E: Airways Management System Overall description: Your team is employed by an Airways company for the implementation of a computer system responsible for a large part of th…...

嵌入式硬件电路原理图之跟随电路

描述 电压跟随电路 电压跟随器是共集电极电路&#xff0c;信号从基极输入&#xff0c;射极输出&#xff0c;故又称射极输出器。基极电压与集电极电压相位相同&#xff0c;即输入电压与输出电压同相。这一电路的主要特点是&#xff1a;高输入电阻、低输出电阻、电压增益近似为…...

学习录

概述 这几年在迷茫中看了不少资料&#xff0c;有觉得写得很棒的&#xff0c;也有写的很糟糕的。所以一直想写这块的总结来进行归纳&#xff0c;同时也希望能给其他处于迷茫中的朋友提供一份高质量的资料列表(也许一个读者也没有)&#xff0c;以下清单个人觉得值得反复看以及思…...

MongoDB索引详解

概述 索引是一种用来快速查询数据的数据结构。BTree 就是一种常用的数据库索引数据结构&#xff0c;MongoDB 采用 BTree 做索引&#xff0c;索引创建 colletions 上。MongoDB 不使用索引的查询&#xff0c;先扫描所有的文档&#xff0c;再匹配符合条件的文档。使用索引的查询&…...

一文搞定JVM内存模型

鲁大猿&#xff0c;寻精品资料&#xff0c;帮你构建Java全栈知识体系 www.jiagoujishu.cn 运行时数据区 内存是非常重要的系统资源&#xff0c;是硬盘和 CPU 的中间仓库及桥梁&#xff0c;承载着操作系统和应用程序的实时运行。JVM 内存布局规定了 Java 在运行过程中内存申请、…...

月报总结|Moonbeam 12月份大事一览

一转眼已经到年底啦。本月&#xff0c;Moonbeam基金会发布四个最新战略重点&#xff1a;跨链解决方案、游戏、真实世界资产&#xff08;RWA&#xff09;、新兴市场。其中在新兴市场方面&#xff0c;紧锣密鼓地推出与巴西公司Grupo RO的战略合作。 用户教育方面&#xff0c;为了…...

现有网络模型的使用及修改(VGG16为例)

VGG16 修改默认路径 import os os.environ[TORCH_HOME] rD:\Pytorch\pythonProject\vgg16 # 下载位置太大了&#xff08;140多G&#xff09;不提供直接下载 train_set torchvision.datasets.ImageNet(root./data_image_net, splittrain, downloadTrue, transformtorchvis…...

MacOS M1/M2 Go Debug 配置

前言 换电脑&#xff0c;Go 环境带来一些麻烦&#xff0c;耽误很多时间&#xff0c;稍作记录。 原始电脑是 Mac 旧款&#xff0c;CPU x86 构型&#xff0c;新电脑 M2&#xff0c;因为旧电脑里本地文件很多&#xff0c;为了简化搬迁&#xff0c;还是用了 Mac 自带的迁移&#x…...

paddlehub 文本检测使用

PaddleHub负责模型的管理、获取和预训练模型的使用。 参考&#xff1a;https://github.com/PaddlePaddle/PaddleHub/tree/develop/modules/image/text_recognition/chinese_text_detection_db_server import paddlehub as hub import cv2 # from utils import cv_show import…...

负载均衡概述

负载均衡 负载均衡 建立在现有网络结构之上&#xff0c;它提供了一种廉价有效透明的方法扩展网络设备和服务器的带宽、增加吞吐量、加强网络数据处理能力、提高网络的灵活性和可用性。 四层负载均衡 vs 七层负载均衡 四层负载均衡&#xff08;目标地址和端口交换&#xff09;…...

C# WinForm MessageBox自定义按键文本 COM组件版

c# 更改弹窗MessageBox按钮文字_c# messagebox.show 字体-CSDN博客 需要用到大佬上传到百度云盘的Hook类&#xff0c;在大佬给的例子的基础上改动了点。 应用时自己加GUID和ProgID。 组件实现&#xff1a; using System; using System.Collections.Generic; using System.L…...

基于SpringBoot微信小程序的宠物美容预约系统设计与实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行交流合作✌ 主要内容&#xff1a;SpringBoot、Vue、SSM、HLM…...

在 docker 容器中配置双网卡,解决通讯的问题

目录 1. 查看当前网络信息 2. 创建自定义网络桥 3. 创建双网卡模式 4. 删除默认网卡 已经创建好了的 Docker 容器&#xff0c;要修改它的IP比较麻烦&#xff0c;网上找了几种不同的方法&#xff0c;经过试验都没有成功&#xff0c;下面通过配置双网上来解决 IP 的问题。…...

uniapp中uview组件库CircleProgress 圆形进度条丰富的使用方法

目录 #内部实现 #平台差异说明 #基本使用 #设置圆环的动画时间 #API #Props 展示操作或任务的当前进度&#xff0c;比如上传文件&#xff0c;是一个圆形的进度环。 #内部实现 组件内部通过canvas实现&#xff0c;有更好的性能和通用性。 #平台差异说明 AppH5微信小程…...

Linux操作系统基础(12):Linux的Shell解释器

1. Shell的介绍 在Linux中&#xff0c;Shell 是一种命令行解释器&#xff0c;它是用户与操作系统内核之间的接口&#xff0c;它负责解释用户输入的命令&#xff0c;并将其转换成系统调用或其他操作系统能够执行的指令。 Shell 提供了一种交互式的方式来与操作系统进行通信&am…...

Android开发编程从入门到精通,安卓技术从初级到高级全套教学

一、教程描述 本套教程基于JDK1.8版本&#xff0c;教学内容主要有&#xff0c;1、环境搭建&#xff0c;UI布局&#xff0c;基础UI组件&#xff0c;高级UI组件&#xff0c;通知&#xff0c;自定义组件&#xff0c;样式主题&#xff1b;2、四大组件&#xff0c;Intent&#xff0…...

HackTheBox - Medium - Linux - BroScience

BroScience BroScience 是一款中等难度的 Linux 机器&#xff0c;其特点是 Web 应用程序容易受到“LFI”的攻击。通过读取目标上的任意文件的能力&#xff0c;攻击者可以深入了解帐户激活码的生成方式&#xff0c;从而能够创建一组可能有效的令牌来激活新创建的帐户。登录后&a…...

`nginx/conf/nginx.conf`最简配置说明

nginx/conf/nginx.conf最简配置说明 代码 nginx/conf/nginx.conf worker_processes 1; #工作进程个数;一般对应CPU内核对应一个worker_processes;太多反而让效率变差;# 事件驱动模块; events {worker_connections 1024;#设置每个worker_processes对应多少个联接; }# 网络请…...

商务智能|描述性统计分析与数据可视化

一、商务智能的三大方面 三个主要方面是描述性的统计分析、预测性的分析和指导性的数据分析。 A. 商务智能的知识体系下,数据分析包含了哪三个工作?商务智能体系架构里边关于数据分析的术语是什么? 商务智能的知识体系下,数据分析包含了三个工作,即描述性分析,预测性分析…...

【游记】GDKOI2024

去年稳定 Cu&#xff0c;希望今年来块 Ag。 Day − ∞ -\infty −∞ 不知道什么时候报名交钱的&#xff0c;赶紧问一问。 周四把设备送过来了。最近备战期末 选科 演讲比赛&#xff0c;有点忙不过来。 Day0 下午两点半出发&#xff0c;车程 2h。路上给小绿打肉鸽 1h 掉电…...

linux支持的零拷贝类型以及java对应的支持

在之前整理的零拷贝文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/135321197 https://blog.csdn.net/zlpzlpzyd/article/details/135317834 得出如下 因为开发的程序很多运行在 linux 操作系统上&#xff0c;所以用 linux 进行讲解 linux 调用方式 dma复制次数…...

【TypeScript】声明文件

一、定义 TypeScript 的声明文件包含 .d.ts 扩展名&#xff0c;并用于为 TypeScript 提供关于 JavaScript 代码的类型信息这些文件通常定义了接口、类型别名、类等&#xff0c;但并不包含实际的执行代码当你使用 JavaScript 库或框架时&#xff0c;声明文件就显得非常有用&…...

基于Flutter构建小型新闻App

目录 1. 概述 1.1 功能概述 1.2 技术准备 1.3 源码地址 2. App首页 2.1 pubspec依赖 2.2 热门首页组件 2.2.1 DefaultTabController 2.2.2 Swiper 2.3 新闻API数据访问 2.4 热门首页效果图 3. 新闻分类 3.1 GestureDetector 3.2 新闻分类效果图 4. 收藏功能 4…...

利用python将excel文件转成txt文件,再将txt文件上传hdfs,最后传入hive中

将excel文件转成txt文件&#xff0c;再将txt文件上传hdfs&#xff0c;最后传入hive中 注意的点 &#xff08;1&#xff09;先判断写入的txt文件是否存在&#xff0c;如果不存在就需要创建路径 &#xff08;2&#xff09;如果txt文件已经存在&#xff0c;那么先将对应的文件进行…...

【自学笔记】01Java基础-07面向对象基础-02继承

记录学习Java基础中有关继承、方法重写、构造器调用的基础知识&#xff0c;学习继承之前建议学习static关键字的内容【自学笔记】01Java基础-09Java关键字详解 1 继承概述 1.1 什么是继承&#xff1f; 1.2 继承的特点 子类可以继承父类的属性和行为&#xff0c;但是子类不能…...

二分查找(一)

算法原理 原理&#xff1a;当一个序列有“二段性”的时候&#xff0c;就可以使用二分查找算法。 适用范围&#xff1a;根据规律找一个点&#xff0c;能将这个数组分成两部分&#xff0c;根据规律能有选择性的舍去一部分&#xff0c;进而在另一个部分继续查找。 除了最普通的…...

【华为OD真题 Python】精准核酸检测

文章目录 题目描述输入描述输出描述示例1输入输出说明备注代码实现题目描述 为了达到新冠疫情精准防控的需要,为了避免全员核酸检测带来的浪费,需要精准圈定可能被感染的人群。 现在根据传染病流调以及大数据分析,得到了每个人之间在时间、空间上是否存在轨迹的交叉。 现…...

Springboot使用logback

文章目录 目录 文章目录 前言 一、添加依赖 二、使用步骤 三 、测试使用 总结 前言 Logback 是log4j 框架的作者开发的新一代日志框架&#xff0c;它效率更高、能够适应诸多的运行环境&#xff0c;同时天然支持 SLF4J。 Logback 的定制性更加灵活&#xff0c;同时也是 Sprin…...

【REST2SQL】03 GO读取JSON文件

REST2SQL需要一些配置信息&#xff0c;用JSON文件保存&#xff0c;比如config.json 1 创建config.json配置文件 {"hostPort":"localhost:5217","connString":"oracle://blma:5217127.0.0.1:1521/CQYH","_oracle":"ora…...

做购物网站 需要手续/游戏推广赚钱

深圳市星特科技有限公司为您提供的磁路组装机。具有以下的特点&#xff1a; 1.点胶系统的精度高&#xff0c;胶量可自己调节&#xff0c;实现多种产品的点胶&#xff1b; 2.利用高精度传感检测技术&#xff0c;CCD影像检测系统&#xff0c;智能判断胶水有无漏点、断胶&#x…...

个人博客网站取名/推广服务公司

微积分基本公式课后题和定积分的换元法和分部积分法的定理部分及部分例题。 转载于:https://www.cnblogs.com/bgd140201219/p/6810103.html...

网站做发/搜索指数的数据来源

????????Python : 3.7.3?????????OS : Ubuntu 18.04.2 LTS????????IDE : pycharm-community-2019.1.3??????Conda : 4.7.5???typesetting : Markdown?code[email protected]:~$ source activate py37(py37) [email protected]:~$ ipythonPy…...

做图神器的网站/长沙网站推广排名优化

问题 检测到时钟偏差&#xff0c;主要是两个设备系统之间的时间上存在差距&#xff0c;导致编译失败。 解决方法 回到工作空间中&#xff0c;即build文件夹的上一级路径&#xff1a; cd ..将所有文件都重新touch一遍&#xff0c;更新到本地系统的时间&#xff0c;再make就没…...

南宁营销型网站建设/青岛网站seo

原 多因子选股之策略的实现 经过前两篇文章&#xff0c;我们把多因子选股策略三大步骤&#xff1a;因子的选取&#xff0c;检验&#xff0c;冗余因子剔除等介绍了一遍&#xff0c;接下来这一篇将利用已经得到的结论&#xff0c;完成最后一步&#xff0c;策略的实现。 我们根据…...

企业型网站建设/2022年seo还值得做吗

这个题目不知道取什么好。 其实是两个技术问题。 1.通过HIBERNATE保存BLOB字段。这个可以参考下面的资料&#xff1a; http://edu.codepub.com/2009/0619/6636.php 2.为了做到通用&#xff0c;需要动态传入PO和照片字段&#xff0c;所以需要设计到反射。 http://hi.baidu.com/t…...