/* SPDX-License-Identifier: GPL-2.0-or-later * Copyright (c) 2022 Red Hat GmbH * Author: Stefano Brivio */ #ifndef PACKET_H #define PACKET_H #include #include "iov.h" struct vdev_memory; /* Maximum size of a single packet stored in pool, including headers */ #define PACKET_MAX_LEN ((size_t)UINT16_MAX) /** * struct pool - Generic pool of packets stored in a buffer * @memory: Memory regions defined for vhost-user, NULL otherwise * @buf: Buffer storing packet descriptors or iovec entries, * @buf_size: Total size of buffer, * @size: Number of usable descriptors for the pool * @count: Number of used descriptors for the pool * @pkt: Descriptors: see macros below */ struct pool { struct vdev_memory *memory; char *buf; size_t buf_size; size_t size; size_t count; struct iovec pkt[]; }; int vu_packet_check_range(struct vdev_memory *memory, const char *ptr, size_t len); void packet_add_do(struct pool *p, struct iov_tail *data, const char *func, int line); bool packet_data_do(const struct pool *p, const size_t idx, struct iov_tail *data, const char *func, int line); bool pool_full(const struct pool *p); void pool_flush(struct pool *p); #define packet_add(p, data) \ packet_add_do(p, data, __func__, __LINE__) #define packet_data(p, idx, data) \ packet_data_do(p, idx, data, __func__, __LINE__) #define PACKET_POOL_DECL(_name, _size) \ struct _name ## _t { \ struct vdev_memory *memory; \ char *buf; \ size_t buf_size; \ size_t size; \ size_t count; \ struct iovec pkt[_size]; \ } #define PACKET_POOL_INIT_NOCAST(_size, _buf, _buf_size, _memory) \ { \ .buf_size = _buf_size, \ .buf = _buf, \ .size = _size, \ .memory = _memory \ } #define PACKET_INIT(name, size, buf, buf_size, memory) \ (struct name ## _t) \ PACKET_POOL_INIT_NOCAST(size, buf, buf_size, memory) #define PACKET_POOL_NOINIT(name, size) \ PACKET_POOL_DECL(name, size) name ## _storage; \ static struct pool *name = (struct pool *)&name ## _storage #endif /* PACKET_H */