vdpa 特性协商机制

首先每一个 vdpa 设备都有自己的基础特性,举例如下两个设备,其中是基本的环境信息

版本
virsh 8.0.0
qemu qemu-kvm-6.2.0-53.module+el8.10.0+1882+0c885e98.2
guest os 4.18.0-348.el8.x86_64

那我们看一下 feature 的几个来源以及其中的作用

设备的硬件feature

下面是两种卡的 feature 的信息

hw特性 guest feature
CX6 0x114c60180b 0x140201803
DPU 0x20003700cb982f 0x100029803

vdpa 对 featue 的修改

从上面看 guest features 是不同的,如果两种设备之间互相热迁移将会导致迁移失败,那我们如何提前知道设备之间可以热迁移呢,我们先看一下 vdpa 是如何协商 features 的
首先经过 vdpa app 获取到 hw feature 之后,我们是有可能修改设备的 features 的,并不是完全的透传给 qemu,具体代码如下:

vdpa_hw_notify_addr_init(hw: &vadapter->hw, nr_vrings: vadapter->max_vrings);
/* Remove IOMMU support and add vhost-user related feature bits. */
vadapter->features = vadapter->hw.hw_features & ~(1ULL << VIRTIO_F_IOMMU_PLATFORM); // 关闭了 iommu_paltform
vadapter->features |= vdpa_types[vadapter->hw.device_type].features; // 使能了 VIRTIO_NET_F_GUEST_ANNOUNCE
VDPA_LOG(INFO, "vadapter->features: 0x%" PRIx64 ".", vadapter->features);

所以即使hw 看起来没有的feature,也可能在 vdpa-app 里面使能该feature

qemu 对 feature 的校验和修改

首先是在设备会走到这个函数

uint64_t vhost_net_get_features(struct vhost_net *net, uint64_t features)
{
return vhost_get_features(&net->dev, vhost_net_get_feature_bits(net),
│ │ features);
}

其中 vhost_net_get_feature_bits 主要是根据vhost-user 还是 vhost-kernel 获取 qemu 对设备的 feature 支持

hw/net/vhost_net.c
/* Features supported by others. */
static const int user_feature_bits[] = {
│ VIRTIO_F_NOTIFY_ON_EMPTY,
│ VIRTIO_RING_F_INDIRECT_DESC,
│ VIRTIO_RING_F_EVENT_IDX,
│ VIRTIO_F_ANY_LAYOUT,
│ VIRTIO_F_VERSION_1,
│ VIRTIO_NET_F_CSUM,
│ VIRTIO_NET_F_GUEST_CSUM,
│ VIRTIO_NET_F_GSO,
│ VIRTIO_NET_F_GUEST_TSO4,
│ VIRTIO_NET_F_GUEST_TSO6,
│ VIRTIO_NET_F_GUEST_ECN,
│ VIRTIO_NET_F_GUEST_UFO,
│ VIRTIO_NET_F_HOST_TSO4,
│ VIRTIO_NET_F_HOST_TSO6,
│ VIRTIO_NET_F_HOST_ECN,
│ VIRTIO_NET_F_HOST_UFO,
│ VIRTIO_NET_F_MRG_RXBUF,
│ VIRTIO_NET_F_MTU,
│ VIRTIO_F_IOMMU_PLATFORM,
│ VIRTIO_F_RING_PACKED,
│ VIRTIO_NET_F_RSS,
│ VIRTIO_NET_F_HASH_REPORT,
/* This bit implies RARP isn't sent by QEMU out of band */
│ VIRTIO_NET_F_GUEST_ANNOUNCE,
│ VIRTIO_NET_F_MQ,
│ VHOST_INVALID_FEATURE_BIT
};

vhost_get_features

uint64_t vhost_get_features(struct vhost_dev *hdev, const int *feature_bits,
uint64_t features /* 这里是vhost user 提供的能力集 */)
{
const int *bit = feature_bits;
while (*bit != VHOST_INVALID_FEATURE_BIT) {
│ │ uint64_t bit_mask = (1ULL << *bit);
│ │ if (!(hdev->features & bit_mask)) {
│ │ │ features &= ~bit_mask;
│ │ }
│ │ bit++;
│ }
return features;
}

这个是 qemu 根据 qemu 支持的 feature 和 host feature 最终协商出来的一个 features,继续看 guest 的驱动提供的 feature 是如何参与进来的我们少啰嗦直接看代码 vhost_net_ack_features

void vhost_net_ack_features(struct vhost_net *net, uint64_t features /* 这里面是 guest os 提供的能力集 */)
{
│ net->dev.acked_features = net->dev.backend_features;
│ vhost_ack_features(&net->dev, vhost_net_get_feature_bits(net), features);
}

这个是 qemu 根据 guest feature 和 host feature 最终协商出来的一个 features

void vhost_ack_features(struct vhost_dev *hdev, const int *feature_bits,
uint64_t features)
{
const int *bit = feature_bits;
while (*bit != VHOST_INVALID_FEATURE_BIT) {
│ │ uint64_t bit_mask = (1ULL << *bit);
│ │ if (features & bit_mask) {
│ │ │ hdev->acked_features |= bit_mask;
│ │ }
│ │ bit++;
│ }
}

总结

到这里我们就清楚了最总协商起来的 feature 是三者的集合 vhost & qemu & guest driver

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇