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

浅析Linux内核scatter-gather list实现

文章目录

    • 概述
    • 数据结构
      • struct scatterlist
    • API操作接口
      • 申请分配SGL
      • 遍历SGL表项
      • SGL数据拷贝
    • 相关参考

概述

Linux Scatter-Gather List(离散/聚合列表,简称SGL)是Linux内核中用于描述物理内存不连续内存块的数据结构,主要用于DMA传输和IO操作。现代的DMA控制器普遍都支持Scatter-Gather方式进行数据传输,通过SGL直接描述数据分布,可以避免单独申请物理连续内存拷贝数据,减少CPU参于的数据搬运,提升IO效率。

数据结构

Linux内核使用struct sg_table结构描述Scatter-Gather List,其定义如下;

struct sg_table {struct scatterlist *sgl;	  // SGL表项数组首地址unsigned int nents;    // 已映射的SGL表项数量unsigned int orig_nents;	// SGL表项总数量
};

sg_table结构记录了SGL表项数组的首地址,具体的SGL表项信息由struct scatterlsit结构进行描述,当数据块较多,单个SGL表项数组无法记录时,数组内的最后一个SGL表项会指向下一个SGL表项数组,构成多级SGL,如下:
在这里插入图片描述

单个SGL表项数组支持的数量由SG_MAX_SINGLE_ALLOC进行定义,并与物理内存页面的大小强相关,如下:

#define SG_MAX_SINGLE_ALLOC		(PAGE_SIZE / sizeof(struct scatterlist))

struct scatterlist

struct scatterlist是Linux内核SGL的核心数据结构,用于描述一个物理地址连续的内存块,它的定义如下:

struct scatterlist {unsigned long	page_link;unsigned int	offset;unsigned int	length;dma_addr_t	dma_address;
#ifdef CONFIG_NEED_SG_DMA_LENGTHunsigned int	dma_length;
#endif
#ifdef CONFIG_NEED_SG_DMA_FLAGSunsigned int    dma_flags;
#endif
};

数据结构主要字段意义如下:

  • page_link:记录数据块所在物理页面信息,其中page_link低2位保留,有特殊含义:
    • bit 0:SG_CHAIN,记录下一个 SGL表项数组的首地址;
    • bit 1:SG_END,指示当前SGL表项是SGL中的最后一个表项。
  • offset:记录数据块在物理页面中起始偏移;
  • length:记录数据块大小;
  • dma_address:DMA地址,设备传输数据使用。

API操作接口

申请分配SGL

int sg_alloc_table(struct sg_table *table, unsigned int nents, gfp_t gfp_mask)
{int ret;ret = __sg_alloc_table(table, nents, SG_MAX_SINGLE_ALLOC,NULL, 0, gfp_mask, sg_kmalloc);if (unlikely(ret))sg_free_table(table);return ret;
}

遍历SGL表项

for_each_sg遍历SGL中所有的有效scatterlist:

#define for_each_sg(sglist, sg, nr, __i)	\for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))

sg_next返回当前SGL表项的下一个表项,通常下一个表项位于SGL表项数组的下一项,在多级SGL的情况下,可能跳到下一级SGL表项数组的首项。

struct scatterlist *sg_next(struct scatterlist *sg)
{if (sg_is_last(sg))return NULL;sg++;if (unlikely(sg_is_chain(sg)))sg = sg_chain_ptr(sg);return sg;
}

SGL数据拷贝

SGL API提供了sg_copy_from_buffersg_copy_to_buffer接口,用于从线性缓冲区拷贝数据到分离的数据块,或反之。sg_copy_xxx_buffer调用sg_copy_buffer进行实现:

size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents, void *buf,size_t buflen, off_t skip, bool to_buffer)
{unsigned int offset = 0;struct sg_mapping_iter miter;unsigned int sg_flags = SG_MITER_ATOMIC;if (to_buffer)sg_flags |= SG_MITER_FROM_SG;elsesg_flags |= SG_MITER_TO_SG;sg_miter_start(&miter, sgl, nents, sg_flags);if (!sg_miter_skip(&miter, skip))return 0;while ((offset < buflen) && sg_miter_next(&miter)) {unsigned int len;len = min(miter.length, buflen - offset);if (to_buffer)memcpy(buf + offset, miter.addr, len);elsememcpy(miter.addr, buf + offset, len);offset += len;}sg_miter_stop(&miter);return offset;
}

相关参考

  • Linux内核scatterlist API介绍
  • Linux scatterlist 详解

文章转载自:

http://AQFiosTy.gbfzy.cn
http://hWRRQ03L.gbfzy.cn
http://7owqfXUw.gbfzy.cn
http://SRBkCcHJ.gbfzy.cn
http://MUbi8oaK.gbfzy.cn
http://ytuf2V0e.gbfzy.cn
http://uxwfcIgo.gbfzy.cn
http://iuVufgJ0.gbfzy.cn
http://N7tOJ0fq.gbfzy.cn
http://f2D6zhBO.gbfzy.cn
http://XrUB42Ss.gbfzy.cn
http://bKzbviBp.gbfzy.cn
http://wmnF9d7m.gbfzy.cn
http://10D5W1Qz.gbfzy.cn
http://EfmPe8K7.gbfzy.cn
http://IFV76pp5.gbfzy.cn
http://cdFf9GA3.gbfzy.cn
http://AwRMs5RZ.gbfzy.cn
http://1V7XvIUB.gbfzy.cn
http://zjTlPHxg.gbfzy.cn
http://fCRo2lD1.gbfzy.cn
http://wX0Ag8au.gbfzy.cn
http://IbU4NRnO.gbfzy.cn
http://NTgzcTTh.gbfzy.cn
http://bWHLGhHf.gbfzy.cn
http://hc2Ke8Sz.gbfzy.cn
http://Esgnarnp.gbfzy.cn
http://yE36FN5d.gbfzy.cn
http://w6AG5Flz.gbfzy.cn
http://EJ1HR3c0.gbfzy.cn
http://www.dtcms.com/a/370494.html

相关文章:

  • MotionSound-简单易用的文本转语音工具
  • 【左程云算法03】对数器算法和数据结构大致分类
  • 2.2 Web和Http
  • CuTe C++ 简介02,gemm_device cuda kernel 的实现
  • uniapp开发APP隐私检测不通过解决
  • Monorepo 是什么?如何使用并写自己的第三方库
  • 【56页PPT】华为集成服务交付ISD业务变革总体方案(附下载方式)
  • 九月六号练习题
  • 深度学习——PyTorch保存模型与调用模型
  • Go基础(⑤Consul)
  • 验证平台中所有的组件应该派生自UVM中的类
  • 企业微信智能表格高效使用指南
  • 自动化运维之ansible
  • 2025年上海市星光计划第十一届职业院校技能大赛高职组“信息安全管理与评估”赛项交换部分前6题详解(仅供参考)
  • Orin-Apollo园区版本:订阅多个摄像头画面拼接与硬编码RTMP推流
  • 多线程(六) ~ 定时器与锁
  • OpenSSL 1.0.1e 下载解压和运行方法(小白适用 附安装包)​
  • Qt图表功能学习
  • 【营销策略算法】关联规则学习-购物篮分析
  • 部署AIRI
  • 深度学习基础概念回顾(Pytorch架构)
  • 基于LSTM深度学习的网络流量测量算法matlab仿真
  • 【PyTorch实战:Tensor变形】5、 PyTorch Tensor指南:从基础操作到Autograd与GPU加速实战
  • 【基础-判断】@Entry装饰的自定义组件将作为页面的入口。在单个页面中可以使用多个@Entry装饰不同自定义组件。
  • 驱动开发系列71 - GLSL编译器实现 - 指令选择
  • 贪心算法应用:化工反应器调度问题详解
  • OpenAvatarChat项目在Windows本地运行指南
  • canal+DataX实现数据全量/实时同步
  • Jenkins运维之路(自动获得分支tag自动构建)
  • 服务器内存和普通计算机内存在技术方面有什么区别?