linux 之dma_buf (7)- alloc page 版本

news/2024/7/14 18:59:40/文章来源:https://blog.csdn.net/z20230508/article/details/139264705

一、前言

exporter 所分配的内存都是通过 kzalloc() 来分配的。本篇我们换个方式,使用 alloc_page() 来分配内存。

二、示例

exporter 驱动

结合前面几篇文章的示例代码,将 dma_buf_ops 全部替换成 page 方式。

exporter-page.c

#include <linux/dma-buf.h>
#include <linux/highmem.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/miscdevice.h>static struct dma_buf *dmabuf_exported;static int exporter_attach(struct dma_buf *dmabuf, struct device *dev,struct dma_buf_attachment *attachment)
{pr_info("dmabuf attach device: %s\n", dev_name(dev));return 0;
}static void exporter_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attachment)
{pr_info("dmabuf detach device: %s\n", dev_name(attachment->dev));
}static struct sg_table *exporter_map_dma_buf(struct dma_buf_attachment *attachment,enum dma_data_direction dir)
{struct page *page = attachment->dmabuf->priv;struct sg_table *table;table = kmalloc(sizeof(*table), GFP_KERNEL);sg_alloc_table(table, 1, GFP_KERNEL);sg_set_page(table->sgl, page, PAGE_SIZE, 0);sg_dma_address(table->sgl) = dma_map_page(NULL, page, 0, PAGE_SIZE, dir);return table;
}static void exporter_unmap_dma_buf(struct dma_buf_attachment *attachment,struct sg_table *table,enum dma_data_direction dir)
{dma_unmap_page(NULL, sg_dma_address(table->sgl), PAGE_SIZE, dir);sg_free_table(table);kfree(table);
}static void exporter_release(struct dma_buf *dma_buf)
{struct page *page = dma_buf->priv;pr_info("dmabuf release\n");put_page(page);
}static void *exporter_vmap(struct dma_buf *dma_buf)
{struct page *page = dma_buf->priv;return vmap(&page, 1, 0, PAGE_KERNEL);
}static void exporter_vunmap(struct dma_buf *dma_buf, void *vaddr)
{vunmap(vaddr);
}static int exporter_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma)
{struct page *page = dma_buf->priv;return remap_pfn_range(vma, vma->vm_start, page_to_pfn(page),PAGE_SIZE, vma->vm_page_prot);
}
static int exporter_begin_cpu_access(struct dma_buf *dmabuf,enum dma_data_direction dir)
{struct dma_buf_attachment *attachment;struct sg_table *table;if (list_empty(&dmabuf->attachments))return 0;attachment = list_first_entry(&dmabuf->attachments, struct dma_buf_attachment, node);table = attachment->priv;dma_sync_sg_for_cpu(NULL, table->sgl, 1, dir);return 0;
}static int exporter_end_cpu_access(struct dma_buf *dmabuf,enum dma_data_direction dir)
{struct dma_buf_attachment *attachment;struct sg_table *table;if (list_empty(&dmabuf->attachments))return 0;attachment = list_first_entry(&dmabuf->attachments, struct dma_buf_attachment, node);table = attachment->priv;dma_sync_sg_for_device(NULL, table->sgl, 1, dir);return 0;
}static const struct dma_buf_ops exp_dmabuf_ops = {.attach = exporter_attach,.detach = exporter_detach,.map_dma_buf = exporter_map_dma_buf,.unmap_dma_buf = exporter_unmap_dma_buf,.release = exporter_release,.mmap = exporter_mmap,.vmap = exporter_vmap,.vunmap = exporter_vunmap,.begin_cpu_access = exporter_begin_cpu_access,.end_cpu_access = exporter_end_cpu_access,
};static struct dma_buf *exporter_alloc_page(void)
{DEFINE_DMA_BUF_EXPORT_INFO(exp_info);struct dma_buf *dmabuf;struct page *page;page = alloc_page(GFP_KERNEL);exp_info.ops = &exp_dmabuf_ops;exp_info.size = PAGE_SIZE;exp_info.flags = O_CLOEXEC;exp_info.priv = page;dmabuf = dma_buf_export(&exp_info);sprintf(page_address(page), "hello world!");return dmabuf;
}static long exporter_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{int fd = dma_buf_fd(dmabuf_exported, O_CLOEXEC);if (copy_to_user((int __user *)arg, &fd, sizeof(fd)))return -EFAULT;return 0;
}static struct file_operations exporter_fops = {.owner   = THIS_MODULE,.unlocked_ioctl   = exporter_ioctl,
};
static struct miscdevice mdev = {.minor = MISC_DYNAMIC_MINOR,.name = "exporter",.fops = &exporter_fops,
};static int __init exporter_init(void)
{dmabuf_exported = exporter_alloc_page();return misc_register(&mdev);
}static void __exit exporter_exit(void)
{misc_deregister(&mdev);
}module_init(exporter_init);
module_exit(exporter_exit);

importer 驱动

importer-page.c

#include <linux/dma-buf.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
#include <linux/uaccess.h>static int importer_test1(struct dma_buf *dmabuf)
{void *vaddr;vaddr = dma_buf_kmap(dmabuf, 0);pr_info("read from dmabuf kmap: %s\n", (char *)vaddr);dma_buf_kunmap(dmabuf, 0, vaddr);vaddr = dma_buf_vmap(dmabuf);pr_info("read from dmabuf vmap: %s\n", (char *)vaddr);dma_buf_vunmap(dmabuf, vaddr);return 0;
}static int importer_test2(struct dma_buf *dmabuf)
{struct dma_buf_attachment *attachment;struct sg_table *table;struct device *dev;unsigned int reg_addr, reg_size;dev = kzalloc(sizeof(*dev), GFP_KERNEL);dev_set_name(dev, "importer");attachment = dma_buf_attach(dmabuf, dev);table = dma_buf_map_attachment(attachment, DMA_BIDIRECTIONAL);reg_addr = sg_dma_address(table->sgl);reg_size = sg_dma_len(table->sgl);pr_info("reg_addr = 0x%08x, reg_size = 0x%08x\n", reg_addr, reg_size);dma_buf_unmap_attachment(attachment, table, DMA_BIDIRECTIONAL);dma_buf_detach(dmabuf, attachment);return 0;
}static long importer_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{int fd;struct dma_buf *dmabuf;if (copy_from_user(&fd, (void __user *)arg, sizeof(int)))return -EFAULT;dmabuf = dma_buf_get(fd);importer_test1(dmabuf);importer_test2(dmabuf);dma_buf_put(dmabuf);return 0;
}static struct file_operations importer_fops = {.owner	= THIS_MODULE,.unlocked_ioctl	= importer_ioctl,
};static struct miscdevice mdev = {.minor = MISC_DYNAMIC_MINOR,.name = "importer",.fops = &importer_fops,
};static int __init importer_init(void)
{return misc_register(&mdev);
}static void __exit importer_exit(void)
{misc_deregister(&mdev);
}module_init(importer_init);
module_exit(importer_exit);

没有测试,只是代码示例。

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

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

相关文章

3W 1.5KVDC、3KVDC 隔离,宽电压输入 DC/DC 电源模块——TP03DA 系列

TP03DA系列电源模块额定输出功率为3W&#xff0c;外形尺寸为31.75*20.32*10.65&#xff0c;应用于2:1及4:1宽电压输入范围 4.5-9V、9V-18V、18V-36V、36V-72V、9V-36V和18-72VDC的输入电压环境&#xff0c;输出电压精度可达1%&#xff0c;具有输出短路保护等功能&#xff0c;可…

室内也可以用北斗定位?还能用RTK?

室内卫星顾名思义&#xff0c;就是在室内有遮挡环境中的卫星定位技术&#xff0c;众所周知&#xff0c;目前全球几大GNSS定位系统已经很完善&#xff0c;但是GNSS有个致命的弱点&#xff0c;就是地面如果有遮挡就没有信号&#xff0c;在这样的条件下&#xff0c;在室内定位场景…

结合Django和Vue.js构建现代Web应用

文章目录 1. 创建Django项目2. 配置Django后端3. 创建Vue.js前端4. 连接Django和Vue.js5. 构建和部署 在现代Web开发中&#xff0c;结合后端框架和前端框架是非常常见的&#xff0c;其中Django作为一种流行的Python后端框架&#xff0c;而Vue.js则是一种灵活强大的前端框架。本…

Pyinstaller打包exe文件解决指南

打包命令 打包 Python 文件 输入如下格式的命令即可 默认命令 Pyinstaller 文件名.py Pyinstaller -option1 -option2 -... 要打包的文件 Pyinstaller 文件名.pyPyinstaller -option1 -option2 -... 要打包的文件 参数选项比较多&#xff0c;这里我列一个表&#xff1a;…

新V 系首批订单交付!苏州金龙助新疆游骏文旅集团打造旅运新标杆

热播剧集《我的阿勒泰》收官不久&#xff0c;6月新疆旅游旺季将至。 2024年5月下旬&#xff0c;苏州金龙海格客车新V系首批30辆正式交付新疆客户&#xff01; 作为苏州金龙海格客车新V系首批用户&#xff0c;新疆游骏文旅集团董事长王红强表示&#xff1a;“海格新V系从外观、…

【JavaEE精炼宝库】多线程(3)线程安全 | synchronized

目录 一、线程安全 1.1 经典线程不安全案例&#xff1a; 1.2 线程安全的概念&#xff1a; 1.3 线程不安全的原因&#xff1a; 1.3.1 案例刨析: 1.3.2 线程不安全的名词解释&#xff1a; 1.3.3 Java 内存模型 (JMM)&#xff1a; 1.3.4 解决线程不安全问题&#xff1a; 二…

Python代码:十七、生成列表

1、题目 描述&#xff1a; 一串连续的数据用什么记录最合适&#xff0c;牛牛认为在Python中非列表&#xff08;list&#xff09;莫属了。现输入牛牛朋友们的名字&#xff0c;请使用list函数与split函数将它们封装成列表&#xff0c;再整个输出列表。 输入描述&#xff1a; …

第十三周 5.27面向对象的三大特性(封装、继承、多态)(三)

3.instanceof避免类型转换异常: (1)语法:引用名 instanceof 类名 (2)执行:判断引用中存储的实际对象类型是否兼容于后面的类型(是否为后面类型的一种)&#xff0c;兼容一true&#xff0c;不兼容—false (3)作用:可以在程序设计中避免类型转换异常 直接使用案例…

工程机械比例阀电流采集方案——IPEhub2与IPEmotion APP

自从国家实施一带一路和新基建计划以来&#xff0c;工程机械的需求量呈现出快速增长的趋势。而关于工程机械&#xff0c;其比例阀的控制问题不容忽视。比例阀是一种新型的液压控制装置——在普通压力阀、流量阀和方向阀上&#xff0c;用比例电磁铁替代原有的控制部分&#xff0…

微服务-Nacos-安装-集成SpringBoot

微服务-SpringCloud-ALibaba-Nacos Nacos 是阿里巴巴推出的 SpringCloud的组件 官网:什么是 Nacos 主要是为了解决微服务的架构中 服务治理的问题服务治理就是进行服务的自动化管理&#xff0c;其核心是服务的注册与发现。 服务注册&#xff1a;服务实例将自身服务信息注册…

uni-app 微信 支付宝 小程序 使用 longpress 实现长按删除功能,非常简单 只需两步

1、先看效果 2、直接上代码 ui结构 <view class"bind" longpress"deleteImage" :data-index"index"><view class"bind_left">绑定设备</view><view class"bind_right"><view class"bind_t…

JMeter 测试单节点与集群的并发异常率

一. JMeter 测试单节点与集群的并发异常率 下载地址&#xff1a;https://jmeter.apache.org/download_jmeter.cgi 单个tomcat测试结果(2000个用户&#xff0c;每个用户访问100次) nginx集群负载均衡tomcat结果(2000个用户&#xff0c;每个用户访问100次)

Go 实现 WebSocket 的双向通信

在Go语言中实现WebSocket的双向通信通常需要使用第三方库&#xff0c;其中 gorilla/websocket 是一个非常流行和广泛使用的库。 1、安装 go get github.com/gorilla/websocket 2、编写WebSocket服务器代码 package mainimport ("fmt""github.com/gorilla/we…

金蝶云星空与旺店通·企业版对接集成采购入库查询打通创建采购入库单

金蝶云星空与旺店通企业版对接集成采购入库查询打通创建采购入库单 数据源系统:金蝶云星空 金蝶K/3Cloud&#xff08;金蝶云星空&#xff09;是移动互联网时代的新型ERP&#xff0c;是基于WEB2.0与云技术的新时代企业管理服务平台。金蝶K/3Cloud围绕着“生态、人人、体验”&…

代码随想录算法训练营第21天|● 530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先

二叉搜索树的最小绝对差 题目连接 https://leetcode.cn/problems/minimum-absolute-difference-in-bst/ 思路&#xff1a; 利用二叉搜索树的中序遍历的特性&#xff0c;将二叉树转成有序数组&#xff0c;进而求任意两个数的最小绝对差。 代码 /*** Definition for a bina…

MFC密码对话框之间数据传送实例(源码下载)

新建一个login工程项目对话框&#xff0c;主对话框IDD_LOGIN_DIALOG中一个显示按钮IDC_BUTTON1、一个密码按钮IDC_BUTTON2。添加一个密码对话框IDD_DIALOG1&#xff0c;添加类password&#xff0c;在对话框中添加一个编辑框IDC_EDIT1、一个确定按钮IDC_BUTTON1。 程序功能&…

记一次攻防演练中的若依(thymeleaf 模板注入)getshell

记一次攻防演练中幸运的从若依弱口令到后台getshell的过程和分析。 0x01 漏洞发现 首先我会先把目标的二级域名拿去使用搜索引擎来搜索所用的搜索引擎收集到包含这个目标二级域名的三级域名或者四级域名的网站。 这样子可以快速的定位到你所要测试的漏洞资产。 1、推荐三个…

新能源汽车为乙炔炭黑行业带来了发展机遇

新能源汽车为乙炔炭黑行业带来了发展机遇 乙炔炭黑&#xff08;Acetylene carbon black&#xff09;又称乙炔黑&#xff0c;外观为黑色极细粉末&#xff0c;相对密度1.95&#xff08;氮置换法&#xff09;&#xff0c;纯度很高&#xff0c;含碳量大于99.5%&#xff0c;氢含量小…

微信小程序实现容器图片流式布局功能,配合小程序原生框架使用。

小程序实现容器图片流式布局功能&#xff0c;因为目前论坛上也有很多博主出过类似的文章&#xff0c;这里我就以一个小白角度去讲一下如何实现的吧。给作者一点点鼓励&#xff0c;先点个赞赞吧&#x1f44d;&#xff0c;蟹蟹&#xff01;&#xff01; 目标 实现下方效果图 技术…

【Sql Server】随机查询一条表记录,并重重温回顾下自定义函数的封装和使用

大家好&#xff0c;我是全栈小5&#xff0c;欢迎来到《小5讲堂》。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 前言随机查询语…