For the devices which implement the get_vq_num_min callback, the driver should not negotiate with virtqueue size with the backend vdpa device if the value returned by get_vq_num_min equals to the value returned by get_vq_num_max. This is useful for vdpa devices based on legacy virtio specfication.
Unified · Split
| @@ -145,7 +145,8 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index, · 144 unmodified lines | ||
| 145 | 145 | /* Assume split virtqueue, switch to packed if necessary */ |
| 146 | 146 | struct vdpa_vq_state state = {0}; |
| 147 | 147 | unsigned long flags; |
| 148 | − u32 align, num; | |
| 148 | + u32 align, max_num, min_num = 1; | |
| 149 | + bool may_reduce_num = true; | |
| 149 | 150 | int err; |
| 150 | 151 | |
| 151 | 152 | if (!name) |
| @@ -163,16 +164,21 @@ virtio_vdpa_setup_vq(struct virtio_device *vdev, unsigned int index, · 11 unmodified lines | ||
| 163 | 164 | if (!info) |
| 164 | 165 | return ERR_PTR(-ENOMEM); |
| 165 | 166 | |
| 166 | − num = ops->get_vq_num_max(vdpa); | |
| 167 | − if (num == 0) { | |
| 167 | + max_num = ops->get_vq_num_max(vdpa); | |
| 168 | + if (max_num == 0) { | |
| 168 | 169 | err = -ENOENT; |
| 169 | 170 | goto error_new_virtqueue; |
| 170 | 171 | } |
| 171 | 172 | |
| 173 | + if (ops->get_vq_num_min) | |
| 174 | + min_num = ops->get_vq_num_min(vdpa); | |
| 175 | + | |
| 176 | + may_reduce_num = (max_num == min_num) ? false : true; | |
| 177 | + | |
| 172 | 178 | /* Create the vring */ |
| 173 | 179 | align = ops->get_vq_align(vdpa); |
| 174 | − vq = vring_create_virtqueue(index, num, align, vdev, | |
| 175 | − true, true, ctx, | |
| 180 | + vq = vring_create_virtqueue(index, max_num, align, vdev, | |
| 181 | + true, may_reduce_num, ctx, | |
| 176 | 182 | virtio_vdpa_notify, callback, name); |
| 177 | 183 | if (!vq) { |
| 178 | 184 | err = -ENOMEM; |