writeback: 1. 初始化

init

源码基于5.10

default_bdi_init


static int __init default_bdi_init(void)
{int err;// 分配wq实例bdi_wq = alloc_workqueue("writeback", WQ_MEM_RECLAIM | WQ_UNBOUND |WQ_SYSFS, 0);if (!bdi_wq)return -ENOMEM;// 初始化noop_backing_dev_info,这个bdi没什么实际意义,一般在文件系统卸载了用err = bdi_init(&noop_backing_dev_info);return err;
}

bdi_alloc

struct backing_dev_info *bdi_alloc(int node_id)
{struct backing_dev_info *bdi;// 分配bdibdi = kzalloc_node(sizeof(*bdi), GFP_KERNEL, node_id);if (!bdi)return NULL;if (bdi_init(bdi)) {kfree(bdi);return NULL;}// 有回写能力bdi->capabilities = BDI_CAP_WRITEBACK | BDI_CAP_WRITEBACK_ACCT;// 最大预读的页数,VM_READAHEAD_PAGES=128k/page_size=128k/4k=32页bdi->ra_pages = VM_READAHEAD_PAGES;// 最大的io页数bdi->io_pages = VM_READAHEAD_PAGES;return bdi;
}

bdi_init

static int bdi_init(struct backing_dev_info *bdi)
{int ret;bdi->dev = NULL;// 各种初始化kref_init(&bdi->refcnt);bdi->min_ratio = 0;bdi->max_ratio = 100;// FPROP_FRAC_BASE=1<<10bdi->max_prop_frac = FPROP_FRAC_BASE;INIT_LIST_HEAD(&bdi->bdi_list);INIT_LIST_HEAD(&bdi->wb_list);init_waitqueue_head(&bdi->wb_waitq);// 初始化cgroup相关ret = cgwb_bdi_init(bdi);return ret;
}static int cgwb_bdi_init(struct backing_dev_info *bdi)
{int ret;// 各种初始化INIT_RADIX_TREE(&bdi->cgwb_tree, GFP_ATOMIC);mutex_init(&bdi->cgwb_release_mutex);init_rwsem(&bdi->wb_switch_rwsem);// 终于到了初始化回写结构ret = wb_init(&bdi->wb, bdi, GFP_KERNEL);if (!ret) {// 初始化成功。设置mem, blk cgbdi->wb.memcg_css = &root_mem_cgroup->css;bdi->wb.blkcg_css = blkcg_root_css;}return ret;
}static int wb_init(struct bdi_writeback *wb, struct backing_dev_info *bdi,gfp_t gfp)
{int i, err;// 置0后,再各种初始化memset(wb, 0, sizeof(*wb));if (wb != &bdi->wb)bdi_get(bdi);wb->bdi = bdi;// 刷新时间戳wb->last_old_flush = jiffies;INIT_LIST_HEAD(&wb->b_dirty);INIT_LIST_HEAD(&wb->b_io);INIT_LIST_HEAD(&wb->b_more_io);INIT_LIST_HEAD(&wb->b_dirty_time);spin_lock_init(&wb->list_lock);// 带宽时间戳wb->bw_time_stamp = jiffies;// INIT_BW = (100 << (20 - PAGE_SHIFT))wb->balanced_dirty_ratelimit = INIT_BW;wb->dirty_ratelimit = INIT_BW;wb->write_bandwidth = INIT_BW;wb->avg_write_bandwidth = INIT_BW;spin_lock_init(&wb->work_lock);INIT_LIST_HEAD(&wb->work_list);// 回写工作队列,每次有任务的时候都会调用wb_workfnINIT_DELAYED_WORK(&wb->dwork, wb_workfn);wb->dirty_sleep = jiffies;// 完成回写的统计err = fprop_local_init_percpu(&wb->completions, gfp);if (err)goto out_put_bdi;// 初始化每个计数器,这是wb里统计的内存使用情况for (i = 0; i < NR_WB_STAT_ITEMS; i++) {err = percpu_counter_init(&wb->stat[i], 0, gfp);if (err)goto out_destroy_stat;}return 0;out_destroy_stat:while (i--)percpu_counter_destroy(&wb->stat[i]);fprop_local_destroy_percpu(&wb->completions);
out_put_bdi:if (wb != &bdi->wb)bdi_put(bdi);return err;
}

bdi_register_va

int bdi_register_va(struct backing_dev_info *bdi, const char *fmt, va_list args)
{struct device *dev;struct rb_node *parent, **p;// 已经注册过了if (bdi->dev)	/* The driver needs to use separate queues per device */return 0;vsnprintf(bdi->dev_name, sizeof(bdi->dev_name), fmt, args);// 创建一个设备对象,并在sysfs里注册dev = device_create(bdi_class, NULL, MKDEV(0, 0), bdi, bdi->dev_name);if (IS_ERR(dev))return PTR_ERR(dev);// 把bdi->wb加到bdi->wb_list里cgwb_bdi_register(bdi);// 设置设备bdi->dev = dev;// 在debugfs里创建stats目录bdi_debug_register(bdi, dev_name(dev));// 设置已注册状态set_bit(WB_registered, &bdi->wb.state);spin_lock_bh(&bdi_lock);// idbdi->id = ++bdi_id_cursor;// 下面这3个是把它加到bdi_tree里p = bdi_lookup_rb_node(bdi->id, &parent);rb_link_node(&bdi->rb_node, parent, p);rb_insert_color(&bdi->rb_node, &bdi_tree);// 加到bdi_list里list_add_tail_rcu(&bdi->bdi_list, &bdi_list);spin_unlock_bh(&bdi_lock);trace_writeback_bdi_register(bdi);return 0;
}

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

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

相关文章

数据库索引的作用

1、解释一下数据库索引的作用。 数据库索引是一种数据结构&#xff0c;它可以帮助数据库系统快速查找和检索数据。索引可以加速对数据库表的查询操作&#xff0c;从而提高系统的性能。 在数据库中&#xff0c;索引通常被用于以下情况&#xff1a; 快速查找特定值&#xff1a…

Java中怎样将bytes转换为long类型?

在Java中将字节数组(bytes)转换为long类型&#xff0c;可以使用Java的ByteBuffer类来实现。ByteBuffer类提供了一种方便的方式来处理原始数据类型的字节序列。 以下笔者用具体的代码来演示下如何将bytes转换为long类型&#xff1a; import java.nio.ByteBuffer;public class …

leetcode496. 下一个更大元素 I 【单调栈】

【简单题】&#xff08;暴力遍历法很简单&#xff09;但是时间复杂度很高&#xff0c;n的立方级别了。。。 代码&#xff1a; class Solution { public:vector<int> nextGreaterElement(vector<int>& nums1, vector<int>& nums2) {vector<int&g…

gitee远程仓库——Git常用远程仓库托管服务

远程仓库 我们的代码不能总是放在本地&#xff0c;因为总是放在本地&#xff0c;一旦电脑出现故障&#xff0c;数据将丢失&#xff0c;怎么共享呢&#xff1f;这里我们需要一个服务器&#xff0c;我们可以把代码放到服务器上&#xff0c;然后让别人下载&#xff0c;这样我们既…

Java人脸识别技术探索与实践

人脸识别技术作为生物特征识别领域的一项重要应用&#xff0c;近年来在安全、便捷以及科研等方面取得了显著的进展。在Java编程领域&#xff0c;人脸识别也得到了广泛的关注和应用。本文将介绍Java中人脸识别技术的基本概念、常用库以及实际示例代码&#xff0c;带您深入了解这…

Android Bitmap压缩

Android View截屏长图拼接&#xff08;RecyclerView&#xff09; 我们在实际使用中&#xff0c;往往图片转化成Bitmap&#xff0c;对Bitmap操作的时候&#xff08;如:截屏分享等&#xff09;&#xff0c;可能Bitmap会过大&#xff0c;导致无视实现对应功能。那么我们就需要对B…

k8s-dashboard使用指导手册

一、访问 dashboard http://172.66.209.101:32001 二、选择 Namespace 如下图&#xff1a; 1 在①搜索框中输入 spms 2 在②选择 spms-cloud 三、查找 pod 1 打开 pod 列表 2 打开过滤窗口 3 搜索 pod 在打开的搜索框中输入 pod的关键字&#xff0c;支持模糊搜索 如搜索…

Camunda 7.x 系列【28】启动事件

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 2.7.9 本系列Camunda 版本 7.19.0 源码地址:https://gitee.com/pearl-organization/camunda-study-demo 文章目录 1. 概述2. 空启动事件3. 定时器启动事件3.1 固定时间日期3.2 持续时间3.3 重复间隔4. 消息启…

“石头剪刀布”游戏:while、函数自调用实现循环游戏

if…else实现“石头剪刀布”游戏&#xff0c;while、函数自调用实现循环游戏。 (本笔记适合学过if…else的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c…

ArcGIS学习总结(19)——要素转点与空间连接(属性表字段映射)

1.在新创建的面矢量数据的属性表中没有对应的字段信息&#xff0c;为了能够和有属性信息的数据进行匹配&#xff0c;使其具有对应字段的信息。 2.需要匹配的矢量文件属性表信息。 3.对新创建的矢量文件执行要素转点&#xff1a;数据管理工具→要素→要素转点。 4.选择分析工…

Docker安装MySQL、Redis如何自启?

1、问题&#xff1a; Docker自启&#xff1a;http://t.csdn.cn/L2v55 重新启动虚拟机&#xff0c;Docker自动启动之后&#xff0c;发现MySQL、Redis都没有启动。 docker ps 没查到有启动的容器。 docker ps -a 查看所有的容器。 2、先使用 su root 命令&#xff0c;切换到root…

机器学习之损失函数(Loss Function)

损失函数&#xff08;Loss Function&#xff09;是机器学习和深度学习中的关键概念&#xff0c;它用于衡量模型的预测与实际目标之间的差异或误差。损失函数的选择对于模型的训练和性能评估至关重要&#xff0c;不同的任务和问题通常需要不同的损失函数。 以下是一些常见的损失…

小程序如何手动变更会员卡等级

有时候需要商家手动变更会员卡等级&#xff0c;以让会员获取更多的福利和特权。下面就介绍一些小程序手动变更会员卡等级的常见方法和策略。 1. 找到指定的会员卡。在管理员后台->会员管理处&#xff0c;找到需要更改等级的会员卡。也支持对会员卡按卡号、手机号和等级进行…

盖雅工场获评2023年度苏州市服务型制造示范企业(平台)

苏州市工信局公布 2023年度苏州市服务型制造示范企业&#xff08;平台&#xff09;名单 遴选出服务型制造示范企业34家 服务型制造示范平台19个 苏州盖雅信息技术有限公司 “劳动力管理SaaS云平台服务” 获评2023年度苏州市服务型制造示范平台 全市唯一获评的人力资源服务…

7.接着跑一下triton官方教程

5.Model Ensemble 在此示例中&#xff0c;我们将探索使用模型集成来仅通过单个网络调用在服务器端执行多个模型。这样做的好处是减少了在客户端和服务器之间复制数据的次数&#xff0c;并消除了网络调用固有的一些延迟。 为了说明创建模型集成的过程&#xff0c;我们将重用第…

C#__使用Thread启动线程和传输数据

class Program{static void Test(){Console.WriteLine("Start……");Thread.Sleep(2000); // 1s等于1000ms&#xff0c;暂停2sConsole.WriteLine("end");}static void Download(Object ob){string str ob as string; // 遍历传递过来的ob字符串Console.Wr…

[MySQL]主从服务器布置

配置主服务器 配置文件 /etc/my.cnf 在[mysqld]下进行配置 log_binON //启动二进制日志 log-bin mysql-bin //启用二进制日志&#xff0c;用于记录主服务器的更新操作 server-id 1 // 用来表示mysql服务id,保证集成环境中的唯一性 , 范围 [1,2^32) read-only0 // 1表示只…

爬虫逆向实战(二十二)--某恩数据电影票房

一、数据接口分析 主页地址&#xff1a;某恩数据 1、抓包 通过抓包可以发现数据接口是API/GetData.ashx 2、判断是否有加密参数 请求参数是否加密&#xff1f; 无请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 通过查看“响应”模块可以发现&#xff0c;响应是…

npm init

1、什么是npm init npm是开源 JavaScript 包管理器&#xff0c;允许 JavaScript 开发人员分享和重用代码。npm init是一种在创建新的npm包时使用的命令&#xff0c;它将提示你填写一些信息以便在package.json文件中创建初始配置。 2、为什么要使用npm init初始化项目 在node…

左耳朵耗子:TCP 的那些事儿(下)

原文地址&#xff1a;https://coolshell.cn/articles/11609.html 这篇文章是下篇&#xff0c;所以如果你对TCP不熟悉的话&#xff0c;还请你先看看上篇《TCP的那些事儿&#xff08;上&#xff09;》 上篇中&#xff0c;我们介绍了TCP的协议头、状态机、数据重传中的东西。但是T…