On Mon, 23 Jun 2025 13:06:35 +0200
Laurent Vivier
In vhost-user mode, where `pool->buf` doesn't store packet data directly, this patch repurposes it to hold the `struct iovec` array describing a scattered packet. This enables pools to manage true scatter-gather descriptors, with iovecs pointing to guest memory.
`p->pkt[idx].iov_base` is now an index into this `pool->buf` iovec array, and `p->pkt[idx].iov_len` is the count of iovecs. `packet_add_do` uses `iov_tail_slice` to store these iovec descriptors from an input iov_tail into `pool->buf`. `packet_data_do` reconstructs the iov_tail for a packet by pointing to this stored array of iovecs.
Signed-off-by: Laurent Vivier
--- packet.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 148 insertions(+), 16 deletions(-) diff --git a/packet.c b/packet.c index fd3b6db57c30..8dbe00af12c6 100644 --- a/packet.c +++ b/packet.c @@ -84,6 +84,122 @@ bool pool_full(const struct pool *p) return p->count >= p->size; }
+/** + * packet_iov_max_cnt() - Return the maximum number of iovec entries we can + * store + * @p: Pointer to packet pool + * + * Return: the maximum number of iovec entries we can store in the memory of + * the pool buffer + */ +static size_t packet_iov_max_cnt(const struct pool *p) +{ + return p->buf_size / sizeof(struct iovec); +} + +/** + * packet_iov_idx() - For a given packet index, return the iovec index and + * the number of iovec entry of the packet + * @p: Pointer to packet pool + * @idx: Index of packet descriptor in pool + * @iov_cnt: Pointer to store the number of the iovec entry of the packet + * @func: For tracing: name of calling function + * @line: For tracing: caller line of function call + * + * Return: the iovec index for the given packet index, @iov_cnt is set + * to the number of the iovec entry of the packet + */ +static int packet_iov_idx(const struct pool *p, size_t idx, size_t *iov_cnt, + const char *func, int line) +{ + size_t iov_idx, max = packet_iov_max_cnt(p); + + iov_idx = (size_t)p->pkt[idx].iov_base; + *iov_cnt = p->pkt[idx].iov_len; + + ASSERT_WITH_MSG(iov_idx + *iov_cnt <= max, + "Corrupt iov entry: (%zu, %zu), max: %zu, %s:%i", + iov_idx, *iov_cnt, max, func, line); + + return iov_idx; +} + +/** + * packet_iov_next_idx() - Give the the next available iovec index
I'm taking the liberty to fix this comment while applying ("Get the next available iovec index"). -- Stefano