Changeset View
Standalone View
share/man/man9/virtqueue.9
- This file was added.
| .\" | ||||||||||
| .\" SPDX-License-Identifier: BSD-2-Clause | ||||||||||
| .\" | ||||||||||
| .\" Copyright (c) 2023 The FreeBSD Foundation | ||||||||||
| .\" | ||||||||||
| .\" This manual page was written by Mina Galić <FreeBSD@igalic.co> under | ||||||||||
| .\" sponsorship from the FreeBSD Foundation. | ||||||||||
| .\" | ||||||||||
| .Dd August 8, 2023 | ||||||||||
| .Dt VIRTQUEUE 9 | ||||||||||
| .Os | ||||||||||
| .Sh NAME | ||||||||||
| .Nm virtqueue | ||||||||||
| .Nd "functions for accessing and manipulating virtqueues" | ||||||||||
| .Sh SYNOPSIS | ||||||||||
| .In dev/virtio/virtio.h | ||||||||||
| .In dev/virtio/virtqueue.h | ||||||||||
| .Ss /* virtqueue allocation functions */ | ||||||||||
mhorne: The C-style comments are strange for a man page. IMO just the text would be fine if you want to… | ||||||||||
freebsd_igalic.coAuthorUnsubmitted Done Inline ActionsI think this is kinda part of not knowing whether this page needs to remain as-is, or if it needs to be split up. freebsd_igalic.co: I think this is kinda part of not knowing whether this page needs to remain as-is, or if it… | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_alloc | ||||||||||
| .Fa "device_t dev" | ||||||||||
| .Fa "uint16_t queue" | ||||||||||
| .Fa "uint16_t size" | ||||||||||
| .Fa "bus_size_t notify_offset" | ||||||||||
| .Fa "int align" | ||||||||||
| .Fa "vm_paddr_t highaddr" | ||||||||||
| .Fa "struct vq_alloc_info *info" | ||||||||||
| .Fa "struct virtqueue **vqp" | ||||||||||
| .Fc | ||||||||||
| .Ft void* | ||||||||||
| .Fo virtqueue_drain | ||||||||||
Not Done Inline Actions
Here and below. mhorne: Here and below. | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "int *last" | ||||||||||
| .Fc | ||||||||||
| .Ft void | ||||||||||
| .Fo virtqueue_free | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_reinit | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "uint16_t size" | ||||||||||
| .Fc | ||||||||||
| .Ss /* virtqueue interrupt callback functions */ | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_intr_filter | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft void | ||||||||||
| .Fo virtqueue_intr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_enable_intr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_postpone_intr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "vq_postpone_t hint" | ||||||||||
| .Fc | ||||||||||
| .Ft void | ||||||||||
| .Fo virtqueue_disable_intr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ss /* Get physical address of the virtqueue ring */ | ||||||||||
| .Ft vm_paddr_t | ||||||||||
| .Fo virtqueue_paddr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft vm_paddr_t | ||||||||||
| .Fo virtqueue_desc_paddr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft vm_paddr_t | ||||||||||
| .Fo virtqueue_avail_paddr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft vm_paddr_t | ||||||||||
| .Fo virtqueue_used_paddr | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ss /* virtqueue size and index information functions */ | ||||||||||
| .Ft uint16_t | ||||||||||
| .Fo virtqueue_index | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft bool | ||||||||||
| .Fo virtqueue_full | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft bool | ||||||||||
| .Fo virtqueue_empty | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_size | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_nfree | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_nused | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ft void | ||||||||||
| .Fo virtqueue_dump | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Ss /* Receive data from or send data to a virtqueue */ | ||||||||||
| .Ft int | ||||||||||
| .Fo virtqueue_enqueue | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "void *cookie" | ||||||||||
| .Fa "struct sglist *sg" | ||||||||||
| .Fa "int readable" | ||||||||||
| .Fa "int writable" | ||||||||||
| .Fc | ||||||||||
| .Ft void* | ||||||||||
| .Fo virtqueue_dequeue | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "uint32_t *len" | ||||||||||
| .Fc | ||||||||||
| .Ft void* | ||||||||||
| .Fo virtqueue_poll | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fa "uint32_t *len" | ||||||||||
| .Fc | ||||||||||
| .Ft void | ||||||||||
| .Fo virtqueue_notify | ||||||||||
| .Fa "struct virtqueue *vq" | ||||||||||
| .Fc | ||||||||||
| .Sh DESCRIPTION | ||||||||||
| The virtqueue functions provide an API into the most important VirtIO abstraction. | ||||||||||
mhorneUnsubmitted Not Done Inline ActionsThis first paragraph should briefly state what the virtqueue abstraction is: what is the purpose and function of a virtqueue object? Knowing this helps the reader determine if they are looking at the correct page. mhorne: This first paragraph should briefly state what the virtqueue abstraction is: what is the… | ||||||||||
freebsd_igalic.coAuthorUnsubmitted Done Inline Actions
I haven't quite figured that out fully yet ;) freebsd_igalic.co: > what is the purpose and function of a virtqueue object?
I haven't quite figured that out… | ||||||||||
freebsd_igalic.coAuthorUnsubmitted Done Inline Actionsmaybe i can reuse some words from the spec? https://docs.oasis-open.org/virtio/virtio/v1.1/csprd01/virtio-v1.1-csprd01.html#x1-230005 freebsd_igalic.co: maybe i can reuse some words from the spec? https://docs.oasis-open.org/virtio/virtio/v1. | ||||||||||
| .Pp | ||||||||||
| The low-level | ||||||||||
| .Fn virtqueue_alloc | ||||||||||
| function allocates a | ||||||||||
| .Ft virtqueue | ||||||||||
mhorneUnsubmitted Not Done Inline Actions.Ft is for function return types only. For general C data types, you should use .Vt. Although, I think several instances of the word 'virtqueue' in this document do not really need markup (including this one). You are either talking about the conceptual 'virtqueue' object (no markup), or the struct virtqueue C type (.Vt). mhorne: `.Ft` is for function return types only. For general C data types, you should use `.Vt`. | ||||||||||
| using | ||||||||||
| .Xr malloc 9 , | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsThis is an implementation detail (and it uses more than just malloc) and I don't see why this is relevant. bryanv: This is an implementation detail (and it uses more than just malloc) and I don't see why this… | ||||||||||
| and associating it with the | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsIt doesn't associate with the device. That done by a transport specific method later. bryanv: It doesn't associate with the device. That done by a transport specific method later. | ||||||||||
| .Xr device 9 | ||||||||||
| .Fa dev . | ||||||||||
| .Pp | ||||||||||
| A high-level function which abstracts the binding to the bus can be found in | ||||||||||
| .Xr virtio_alloc_virtqueues 9 . | ||||||||||
Done Inline Actionsthe the pstef: the the | ||||||||||
| .Pp | ||||||||||
| .Fn virtqueue_drain | ||||||||||
| drains the queue, and is typically called on detachment of the | ||||||||||
| .Xr device 9 . | ||||||||||
| .Pp | ||||||||||
| .Fn virtqueue_free | ||||||||||
| frees the | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq , | ||||||||||
| and is called automatically by either the bus, or by the allocation function in case of failure. | ||||||||||
Done Inline Actionsbuses? pstef: buses? | ||||||||||
Done Inline Actionswe got 67 "buses" and 17 "busses". freebsd_igalic.co: we got 67 "buses" and 17 "busses".
my dictionary said busses is the American spelling, which I… | ||||||||||
| Similarly, | ||||||||||
| .Fn virtqueue_reinit | ||||||||||
Done Inline ActionsI would move this up before virtqueue_free paragraph to respect the order set before. fernape: I would move this up before `virtqueue_free` paragraph to respect the order set before. | ||||||||||
| is a low-level function used by buses to reinitialize the virtqueue when the bus is reinitialized. | ||||||||||
| .Pp | ||||||||||
| The virtqueue interrupt functions | ||||||||||
| .Fn virtqueue_intr | ||||||||||
| and | ||||||||||
| .Fn virtqueue_intr_filter | ||||||||||
| help attach an interrupt handlers to a | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsThsese don't "attach" - it is really just doing a callback. bryanv: Thsese don't "attach" - it is really just doing a callback. | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq | ||||||||||
| and can be used for example in | ||||||||||
| .Xr bus_setup_intr 9 . | ||||||||||
| While | ||||||||||
| .Fn virttqueue_enable_intr , | ||||||||||
mhorneUnsubmitted Not Done Inline Actions
mhorne: | ||||||||||
| .Fn virtqueue_postpone_intr , | ||||||||||
| and | ||||||||||
| .Fn virtqueue_disable_intr | ||||||||||
| allow finer grained control of what interrupts to process in | ||||||||||
Done Inline ActionsI would respect the previous order and say ...enable, ...postpone and ...disable... or sort them alphabetically in the top description. fernape: I would respect the previous order and say `...enable, ...postpone and ...disable...` or sort… | ||||||||||
| .Xr driver 9 | ||||||||||
| code, and when. | ||||||||||
| .Pp | ||||||||||
| The functions | ||||||||||
| .Fn virtqueue_paddr , | ||||||||||
| .Fn virtqueue_desc_paddr , | ||||||||||
| .Fn virtqueue_avail_paddr , | ||||||||||
| .Fn virtqueue_used_paddr , | ||||||||||
| return the physical address | ||||||||||
| .Ft vm_paddr_t | ||||||||||
| of the underlying ring buffer, its description, the "available ring", and "used | ||||||||||
| ring", respectively, as mapping to the kernel virtual address of their | ||||||||||
| underlying structures, as per | ||||||||||
| .Xr vtophys 9 | ||||||||||
| of each platform. | ||||||||||
mhorneUnsubmitted Not Done Inline ActionsHere you are trying to explain way too much with one sentence. How about this: Several helper functions are provided for obtaining the physical address (vm_paddr_t) of the ring buffer and its components. The virtqueue_paddr() function returns the address of the underlying ring buffer. The virtqueue_desc_paddr() function returns the address of the first descriptor in the ring. The virtqueue_avail_paddr() and virtqueue_used_paddr() functions return the address of the "available" and "used" rings, respectively. These helper functions are wrappers around vtophys(). This description might feel more natural if preceded by a more general description of the ring buffer, such as the difference between the available and used rings. If most consumers of the virtqueue(9) interface don't need to mess around with these paddrs (i.e. it is an implementation detail), then we might just shorten it and say: The .Fn virtqueue_paddr , .Fn virtqueue_desc_paddr , .Fn virtqueue_avail_paddr , and .Fn virtqueue_used_paddr helper functions return the physical address of the virtqueue's ring buffer, and the ring's individual components. mhorne: Here you are trying to explain way too much with one sentence.
How about this:
```
Several… | ||||||||||
| .Pp | ||||||||||
| The | ||||||||||
| .Fn virtqueue_index | ||||||||||
| function returns the current index in the underlying queue. | ||||||||||
| .Pp | ||||||||||
| The | ||||||||||
| .Fn virtqueue_full , | ||||||||||
| and | ||||||||||
| .Fn virtqueue_empty | ||||||||||
| functions return a | ||||||||||
| .Ft bool | ||||||||||
| value showing whether the | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq | ||||||||||
| in their parameter is full or empty. | ||||||||||
Done Inline ActionsShould probably go before the virtqueue_full paragraph. fernape: Should probably go before the `virtqueue_full` paragraph. | ||||||||||
| .Pp | ||||||||||
| The | ||||||||||
| .Fn virtqueue_size , | ||||||||||
| .Fn virtqueue_nfree , | ||||||||||
| and | ||||||||||
| .Fn virtqueue_nused | ||||||||||
| functions return the size, number of free, and number of used elements in the | ||||||||||
| .Ft virtqueue . | ||||||||||
| .Pp | ||||||||||
| The most generic and least useful information function in this group is the | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsWhen things go wrong, this can be the most useful :) bryanv: When things go wrong, this can be the most useful :) | ||||||||||
| debugging function | ||||||||||
Done Inline Actionsis is pstef: is is | ||||||||||
| .Fn virtqueue_dump | ||||||||||
| which dumps the contents of the | ||||||||||
Done Inline Actionssurplus newline? pstef: surplus newline? | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq | ||||||||||
| using | ||||||||||
| .Xr printf 9 . | ||||||||||
| .Pp | ||||||||||
| The | ||||||||||
| .Fn virtqueue_enqueue | ||||||||||
| function is used to send data between the guest and the host via the | ||||||||||
Done Inline ActionsThe function virtqueue_enqueue... --> The virtqueue_enqueue function... fernape: The function `virtqueue_enqueue`... --> The `virtqueue_enqueue` function... | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsThis doesn't send data - it is really just sending buffers, that may or may not have any data in them depending how they are being used. bryanv: This doesn't send data - it is really just sending buffers, that may or may not have any data… | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq . | ||||||||||
| .Fn virtqueue_enqueue | ||||||||||
| uses | ||||||||||
Not Done Inline ActionsThis might be removed? It does not add much fernape: This might be removed? It does not add much | ||||||||||
| .Fa readable | ||||||||||
| to determine how many segments of the | ||||||||||
Done Inline Actionsintegers in plural referring to readable and writable, but the latter is too far in the sentence. uses readable..., and writable... dropping the integers. It is already in the function signature. fernape: //integers// in plural referring to `readable` and `writable`, but the latter is too far in the… | ||||||||||
| .Xr sglist 9 | ||||||||||
| .Fa sg | ||||||||||
| are to be transferred to the host, and | ||||||||||
| .Fa writable | ||||||||||
| to tell how much data it expects. | ||||||||||
| .Fa cookie | ||||||||||
| is used as an identifying pointer that the caller controls. | ||||||||||
| This makes it possible to verify if we are receiving data from the expected | ||||||||||
bryanvUnsubmitted Not Done Inline ActionsThe cookie does not imply verifying anything. It is just an opaque pointer that's returned on deq and drain. bryanv: The cookie does not imply verifying anything. It is just an opaque pointer that's returned on… | ||||||||||
| source in functions such as | ||||||||||
| .Fn virtqueue_dequeue . | ||||||||||
Done Inline Actionsis used as? pstef: is used as? | ||||||||||
| .Fn virtqueue_enqueue | ||||||||||
| returns 0 on success, or else an error. | ||||||||||
| .Pp | ||||||||||
| .Fn virtqueue_dequeue | ||||||||||
| sets | ||||||||||
| .Fa len | ||||||||||
| to the amount of data returned as | ||||||||||
| .Ft void * | ||||||||||
| from the | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq . | ||||||||||
| .Fn virtqueue_dequeue | ||||||||||
| can return | ||||||||||
| .Dv NULL , | ||||||||||
Done Inline ActionsIf not exhausted, what does it return? fernape: If not exhausted, what does it return? | ||||||||||
| when the queue is exhausted. | ||||||||||
| .Fn virtqueue_poll | ||||||||||
| polls a | ||||||||||
| .Ft virtqueue | ||||||||||
Done Inline Actions.F vq --> .Fa vq Damn! it took me a while to catch this! fernape: `.F vq` --> `.Fa vq`
Damn! it took me a while to catch this! | ||||||||||
| .Fa vq | ||||||||||
| until it no longer returns | ||||||||||
Done Inline ActionsWhat's the len parameter for in this case? fernape: What's the `len` parameter for in this case? | ||||||||||
| .Dv NULL , | ||||||||||
| returning data as | ||||||||||
| .Ft void * | ||||||||||
| otherwise, and setting | ||||||||||
| .Fa len | ||||||||||
| to the length of the returned data. | ||||||||||
| .Pp | ||||||||||
| Finally, the | ||||||||||
| .Fn virtqueue_notify | ||||||||||
| function sends a notification to the host system that data has been enqueued or | ||||||||||
| dequeued on the | ||||||||||
| .Ft virtqueue | ||||||||||
| .Fa vq . | ||||||||||
| .Sh EXAMPLES | ||||||||||
| .Ss TODO | ||||||||||
mhorneUnsubmitted Not Done Inline ActionsStill todo :) mhorne: Still todo :) | ||||||||||
| .Sh SEE ALSO | ||||||||||
| .Xr sglist 9 , | ||||||||||
mhorneUnsubmitted Not Done Inline ActionsPlease sort alphabetically. mhorne: Please sort alphabetically. | ||||||||||
| .Xr BUS_SETUP_INTR 9 , | ||||||||||
| .Xr pmap 9 , | ||||||||||
| .Xr virtio_alloc_virtqueues 9 . | ||||||||||
| .Sh AUTHORS | ||||||||||
| This manual page was written by | ||||||||||
| .An Mina Galić . | ||||||||||
The C-style comments are strange for a man page. IMO just the text would be fine if you want to split up the prototypes.