配置详解
- num_queue 一个queue就是一个vring
- cmd_size 单个请求需要额外存储的最大大小
vblk->tag_set.cmd_size =
sizeof(struct virtblk_req) +
sizeof(struct scatterlist) * sg_elems;
- queue_depth 等于queue_size / 2 是块设备同时可以处理的I/O请求数量
/* Default queue sizing is to fill the ring. */
if (!virtblk_queue_depth) {
virtblk_queue_depth = vblk->vqs[0].vq->num_free;
/* ... but without indirect descs, we use 2 descs per req */
if (!virtio_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC))
virtblk_queue_depth /= 2;
}
/* We need to know how many segments before we allocate. */
err = virtio_cread_feature(vdev, VIRTIO_BLK_F_SEG_MAX,
struct virtio_blk_config, seg_max,
&sg_elems);
/* We need at least one SG element, whatever they say. */
if (err || !sg_elems)
sg_elems = 1;
/* We need an extra sg elements at head and tail. */
sg_elems += 2;
vblk->sg_elems = sg_elems;
- queue_size决定了vring的大小,就是vring descriptor所在的内存位置,用来存放vring descriptor本身的。
static inline unsigned vring_size(unsigned int num, unsigned long align)
{
return ((sizeof(struct vring_desc) * num + sizeof(__virtio16) * (3 + num)
+ align - 1) & ~(align - 1))
+ sizeof(__virtio16) * 3 + sizeof(struct vring_used_elem) * num;
}
/* TODO: allocate each queue chunk individually */
for (; num && vring_size(num, vring_align) > PAGE_SIZE; num /= 2) {
queue = vring_alloc_queue(vdev, vring_size(num, vring_align),
&dma_addr,
GFP_KERNEL|__GFP_NOWARN|__GFP_ZERO);
if (queue)
break;
if (!may_reduce_num)
return NULL;
}
- VIRTIO_BLK_F_BLK_SIZE
- VIRTIO_BLK_F_CONFIG_WCE
- VIRTIO_BLK_F_FLUSH
- VIRTIO_BLK_F_TOPOLOGY
- VIRTIO_BLK_F_WRITE_ZEROES
- VIRTIO_BLK_F_SECURE_ERASE
- VIRTIO_BLK_F_ZONED
- VIRTIO_BLK_F_DISCARD
- VIRTIO_BLK_F_RO
- VIRTIO_BLK_F_GEOMETRY