通过pci-sysfs来查询当前设备支持的最多几个vf
来源:互联网 发布:商业数据保密协议范本 编辑:程序博客网 时间:2024/05/22 05:49
当通过pci_alloc_dev 来申请pci_dev的时候会指定dev->dev.type = &pci_dev_type;
struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
{
struct pci_dev *dev;
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!dev)
return NULL;
INIT_LIST_HEAD(&dev->bus_list);
dev->dev.type = &pci_dev_type;
dev->bus = pci_bus_get(bus);
return dev;
}
也就是说每个pci device都有一个pci_dev_type。
pci_dev_type的定义在pci/pci-sysfs.c中
static const struct attribute_group *pci_dev_attr_groups[] = {
&pci_dev_attr_group,
&pci_dev_hp_attr_group,
#ifdef CONFIG_PCI_IOV
&sriov_dev_attr_group,
#endif
NULL,
};
struct device_type pci_dev_type = {
.groups = pci_dev_attr_groups,
};
这里可以发现所谓的pci_dev_type 就是一组接口可以读写当前的pci device.
例如 通过lscpi查到vga的id为0007:91:00.0
root@ubuntu:~# lspci
0002:80:00.0 PCI bridge: Device 19e5:1610 (rev 01)
0007:91:00.0 VGA compatible controller: Device 19e5:1711 (rev 01)
就可以在通过下面的命令读到boot_vga 这个变量
root@ubuntu:/sys/bus/pci/devices/0007:91:00.0# pwd
/sys/bus/pci/devices/0007:91:00.0
root@ubuntu:/sys/bus/pci/devices/0007:91:00.0# cat boot_vga
0
具体的code 分析为:
在pci_dev_attr_groups中调用
static struct attribute *pci_dev_dev_attrs[] = {
&vga_attr.attr,
NULL,
};
static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_dev *vga_dev = vga_default_device();
if (vga_dev)
return sprintf(buf, "%u\n", (pdev == vga_dev));
return sprintf(buf, "%u\n",
!!(pdev->resource[PCI_ROM_RESOURCE].flags &
IORESOURCE_ROM_SHADOW));
}
static struct device_attribute vga_attr = __ATTR_RO(boot_vga);
看到原来boot_vga 这个代表的是当前是被是否是vga设备,如果是的话就返回0.而全面前面cat boot_vga 等于0,也表明当前的设备就是vga设备。
下面是重点,当前设备如果支持vf的话,就可以通过sriov_dev_attr_group-
static struct attribute_group sriov_dev_attr_group = {
.attrs = sriov_dev_attrs,
.is_visible = sriov_attrs_are_visible,
};
如果当前设备不支持vf的话
static umode_t sriov_attrs_are_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
if (!dev_is_pf(dev))
return 0;
return a->mode;
}
就没有办法看到sriov_dev_attrs
其定义如下:
static struct attribute *sriov_dev_attrs[] = {
&sriov_totalvfs_attr.attr,
&sriov_numvfs_attr.attr,
NULL,
};
static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs);
static struct device_attribute sriov_numvfs_attr =
__ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP),
sriov_numvfs_show, sriov_numvfs_store);
这样我们就通过sriov_totalvfs 这个变量查看当前dev支持多少个vf.
static ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
//得到pci_dev *pdev
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev));
}
从pci_sriov_get_totalvfs 中就可以看出原来是从pci_dev的dev->sriov->total_VFs 得到这个设备可以支持的最多的vf
int pci_sriov_get_totalvfs(struct pci_dev *dev)
{
if (!dev->is_physfn)
return 0;
if (dev->sriov->driver_max_VFs)
return dev->sriov->driver_max_VFs;
return dev->sriov->total_VFs;
}
struct pci_dev *pci_alloc_dev(struct pci_bus *bus)
{
struct pci_dev *dev;
dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!dev)
return NULL;
INIT_LIST_HEAD(&dev->bus_list);
dev->dev.type = &pci_dev_type;
dev->bus = pci_bus_get(bus);
return dev;
}
也就是说每个pci device都有一个pci_dev_type。
pci_dev_type的定义在pci/pci-sysfs.c中
static const struct attribute_group *pci_dev_attr_groups[] = {
&pci_dev_attr_group,
&pci_dev_hp_attr_group,
#ifdef CONFIG_PCI_IOV
&sriov_dev_attr_group,
#endif
NULL,
};
struct device_type pci_dev_type = {
.groups = pci_dev_attr_groups,
};
这里可以发现所谓的pci_dev_type 就是一组接口可以读写当前的pci device.
例如 通过lscpi查到vga的id为0007:91:00.0
root@ubuntu:~# lspci
0002:80:00.0 PCI bridge: Device 19e5:1610 (rev 01)
0007:91:00.0 VGA compatible controller: Device 19e5:1711 (rev 01)
就可以在通过下面的命令读到boot_vga 这个变量
root@ubuntu:/sys/bus/pci/devices/0007:91:00.0# pwd
/sys/bus/pci/devices/0007:91:00.0
root@ubuntu:/sys/bus/pci/devices/0007:91:00.0# cat boot_vga
0
具体的code 分析为:
在pci_dev_attr_groups中调用
static struct attribute *pci_dev_dev_attrs[] = {
&vga_attr.attr,
NULL,
};
static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct pci_dev *vga_dev = vga_default_device();
if (vga_dev)
return sprintf(buf, "%u\n", (pdev == vga_dev));
return sprintf(buf, "%u\n",
!!(pdev->resource[PCI_ROM_RESOURCE].flags &
IORESOURCE_ROM_SHADOW));
}
static struct device_attribute vga_attr = __ATTR_RO(boot_vga);
看到原来boot_vga 这个代表的是当前是被是否是vga设备,如果是的话就返回0.而全面前面cat boot_vga 等于0,也表明当前的设备就是vga设备。
下面是重点,当前设备如果支持vf的话,就可以通过sriov_dev_attr_group-
static struct attribute_group sriov_dev_attr_group = {
.attrs = sriov_dev_attrs,
.is_visible = sriov_attrs_are_visible,
};
如果当前设备不支持vf的话
static umode_t sriov_attrs_are_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct device *dev = kobj_to_dev(kobj);
if (!dev_is_pf(dev))
return 0;
return a->mode;
}
就没有办法看到sriov_dev_attrs
其定义如下:
static struct attribute *sriov_dev_attrs[] = {
&sriov_totalvfs_attr.attr,
&sriov_numvfs_attr.attr,
NULL,
};
static struct device_attribute sriov_totalvfs_attr = __ATTR_RO(sriov_totalvfs);
static struct device_attribute sriov_numvfs_attr =
__ATTR(sriov_numvfs, (S_IRUGO|S_IWUSR|S_IWGRP),
sriov_numvfs_show, sriov_numvfs_store);
这样我们就通过sriov_totalvfs 这个变量查看当前dev支持多少个vf.
static ssize_t sriov_totalvfs_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
//得到pci_dev *pdev
struct pci_dev *pdev = to_pci_dev(dev);
return sprintf(buf, "%u\n", pci_sriov_get_totalvfs(pdev));
}
从pci_sriov_get_totalvfs 中就可以看出原来是从pci_dev的dev->sriov->total_VFs 得到这个设备可以支持的最多的vf
int pci_sriov_get_totalvfs(struct pci_dev *dev)
{
if (!dev->is_physfn)
return 0;
if (dev->sriov->driver_max_VFs)
return dev->sriov->driver_max_VFs;
return dev->sriov->total_VFs;
}
0 0
- 通过pci-sysfs来查询当前设备支持的最多几个vf
- 通过sysfs 读写pci的配置空间和rom空间
- 查询pci卡支持的特性
- DOS下BC编译的遍历PCI总线查询PCI设备及基地址
- PCI设备的初始化
- pci设备的初始化
- pci设备的初始化
- pci设备的初始化
- MySQL通过以下方法查询当前数据库支持的存储引擎
- 查询系统当前消耗句柄最多的10个进程
- Documentation-filesystems-sysfs-pci
- 为设备服务的文件系统sysfs--sysfs文件的读写
- PCI Express的几个基本概念
- kvm创建虚拟pci设备的几个函数(老版本)
- linux文件系统的系统分析--(十六)sysfs和设备模型--从platform和rtc来感受设备模型
- linux文件系统的系统分析--(十六)sysfs和设备模型--从platform和rtc来感受设备模型
- pci设备的枚举(转)
- PCI设备内存的访问
- 安卓animation动画
- HTML meta viewport属性说明(mark)
- LLVM学习笔记(9)
- 利用JasperReport+iReport进行Web报表开发(java)
- 文字旋转的几种方法
- 通过pci-sysfs来查询当前设备支持的最多几个vf
- 这几个细节可能与效率有关(1)
- poj 2488 A Knight's Journey 【骑士周游 dfs + 记忆路径】
- 关于用折半查找来定位目标值的区间
- java notify notifyall 区别
- throw er; // Unhandled 'error' event
- 关键字this的用法及作用
- (三)android recovery差分升级过程掉电分析
- CodeForces 609 D.Gadgets for dollars and pounds(二分+贪心)