 d043e2db87
			
		
	
	
		d043e2db87
		
	
	
	
	
		
			
			To support reconnecting after restart or crash, VDUSE backend might need to resubmit inflight I/Os. This stores the metadata such as the index of inflight I/O's descriptors to a shm file so that VDUSE backend can restore them during reconnecting. Signed-off-by: Xie Yongji <xieyongji@bytedance.com> Message-Id: <20220523084611.91-9-xieyongji@bytedance.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
		
			
				
	
	
		
			248 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * VDUSE (vDPA Device in Userspace) library
 | |
|  *
 | |
|  * Copyright (C) 2022 Bytedance Inc. and/or its affiliates. All rights reserved.
 | |
|  *
 | |
|  * Author:
 | |
|  *   Xie Yongji <xieyongji@bytedance.com>
 | |
|  *
 | |
|  * This work is licensed under the terms of the GNU GPL, version 2 or
 | |
|  * later.  See the COPYING file in the top-level directory.
 | |
|  */
 | |
| 
 | |
| #ifndef LIBVDUSE_H
 | |
| #define LIBVDUSE_H
 | |
| 
 | |
| #include <stdint.h>
 | |
| #include <sys/uio.h>
 | |
| 
 | |
| #define VIRTQUEUE_MAX_SIZE 1024
 | |
| 
 | |
| /* VDUSE device structure */
 | |
| typedef struct VduseDev VduseDev;
 | |
| 
 | |
| /* Virtqueue structure */
 | |
| typedef struct VduseVirtq VduseVirtq;
 | |
| 
 | |
| /* Some operation of VDUSE backend */
 | |
| typedef struct VduseOps {
 | |
|     /* Called when virtqueue can be processed */
 | |
|     void (*enable_queue)(VduseDev *dev, VduseVirtq *vq);
 | |
|     /* Called when virtqueue processing should be stopped */
 | |
|     void (*disable_queue)(VduseDev *dev, VduseVirtq *vq);
 | |
| } VduseOps;
 | |
| 
 | |
| /* Describing elements of the I/O buffer */
 | |
| typedef struct VduseVirtqElement {
 | |
|     /* Descriptor table index */
 | |
|     unsigned int index;
 | |
|     /* Number of physically-contiguous device-readable descriptors */
 | |
|     unsigned int out_num;
 | |
|     /* Number of physically-contiguous device-writable descriptors */
 | |
|     unsigned int in_num;
 | |
|     /* Array to store physically-contiguous device-writable descriptors */
 | |
|     struct iovec *in_sg;
 | |
|     /* Array to store physically-contiguous device-readable descriptors */
 | |
|     struct iovec *out_sg;
 | |
| } VduseVirtqElement;
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * vduse_get_virtio_features:
 | |
|  *
 | |
|  * Get supported virtio features
 | |
|  *
 | |
|  * Returns: supported feature bits
 | |
|  */
 | |
| uint64_t vduse_get_virtio_features(void);
 | |
| 
 | |
| /**
 | |
|  * vduse_queue_get_dev:
 | |
|  * @vq: specified virtqueue
 | |
|  *
 | |
|  * Get corresponding VDUSE device from the virtqueue.
 | |
|  *
 | |
|  * Returns: a pointer to VDUSE device on success, NULL on failure.
 | |
|  */
 | |
| VduseDev *vduse_queue_get_dev(VduseVirtq *vq);
 | |
| 
 | |
| /**
 | |
|  * vduse_queue_get_fd:
 | |
|  * @vq: specified virtqueue
 | |
|  *
 | |
|  * Get the kick fd for the virtqueue.
 | |
|  *
 | |
|  * Returns: file descriptor on success, -1 on failure.
 | |
|  */
 | |
| int vduse_queue_get_fd(VduseVirtq *vq);
 | |
| 
 | |
| /**
 | |
|  * vduse_queue_pop:
 | |
|  * @vq: specified virtqueue
 | |
|  * @sz: the size of struct to return (must be >= VduseVirtqElement)
 | |
|  *
 | |
|  * Pop an element from virtqueue available ring.
 | |
|  *
 | |
|  * Returns: a pointer to a structure containing VduseVirtqElement on success,
 | |
|  * NULL on failure.
 | |
|  */
 | |
| void *vduse_queue_pop(VduseVirtq *vq, size_t sz);
 | |
| 
 | |
| /**
 | |
|  * vduse_queue_push:
 | |
|  * @vq: specified virtqueue
 | |
|  * @elem: pointer to VduseVirtqElement returned by vduse_queue_pop()
 | |
|  * @len: length in bytes to write
 | |
|  *
 | |
|  * Push an element to virtqueue used ring.
 | |
|  */
 | |
| void vduse_queue_push(VduseVirtq *vq, const VduseVirtqElement *elem,
 | |
|                       unsigned int len);
 | |
| /**
 | |
|  * vduse_queue_notify:
 | |
|  * @vq: specified virtqueue
 | |
|  *
 | |
|  * Request to notify the queue.
 | |
|  */
 | |
| void vduse_queue_notify(VduseVirtq *vq);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_get_priv:
 | |
|  * @dev: VDUSE device
 | |
|  *
 | |
|  * Get the private pointer passed to vduse_dev_create().
 | |
|  *
 | |
|  * Returns: private pointer on success, NULL on failure.
 | |
|  */
 | |
| void *vduse_dev_get_priv(VduseDev *dev);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_get_queue:
 | |
|  * @dev: VDUSE device
 | |
|  * @index: virtqueue index
 | |
|  *
 | |
|  * Get the specified virtqueue.
 | |
|  *
 | |
|  * Returns: a pointer to the virtqueue on success, NULL on failure.
 | |
|  */
 | |
| VduseVirtq *vduse_dev_get_queue(VduseDev *dev, int index);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_get_fd:
 | |
|  * @dev: VDUSE device
 | |
|  *
 | |
|  * Get the control message fd for the VDUSE device.
 | |
|  *
 | |
|  * Returns: file descriptor on success, -1 on failure.
 | |
|  */
 | |
| int vduse_dev_get_fd(VduseDev *dev);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_handler:
 | |
|  * @dev: VDUSE device
 | |
|  *
 | |
|  * Used to process the control message.
 | |
|  *
 | |
|  * Returns: file descriptor on success, -errno on failure.
 | |
|  */
 | |
| int vduse_dev_handler(VduseDev *dev);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_update_config:
 | |
|  * @dev: VDUSE device
 | |
|  * @size: the size to write to configuration space
 | |
|  * @offset: the offset from the beginning of configuration space
 | |
|  * @buffer: the buffer used to write from
 | |
|  *
 | |
|  * Update device configuration space and inject a config interrupt.
 | |
|  *
 | |
|  * Returns: 0 on success, -errno on failure.
 | |
|  */
 | |
| int vduse_dev_update_config(VduseDev *dev, uint32_t size,
 | |
|                             uint32_t offset, char *buffer);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_setup_queue:
 | |
|  * @dev: VDUSE device
 | |
|  * @index: virtqueue index
 | |
|  * @max_size: the max size of virtqueue
 | |
|  *
 | |
|  * Setup the specified virtqueue.
 | |
|  *
 | |
|  * Returns: 0 on success, -errno on failure.
 | |
|  */
 | |
| int vduse_dev_setup_queue(VduseDev *dev, int index, int max_size);
 | |
| 
 | |
| /**
 | |
|  * vduse_set_reconnect_log_file:
 | |
|  * @dev: VDUSE device
 | |
|  * @file: filename of reconnect log
 | |
|  *
 | |
|  * Specify the file to store log for reconnecting. It should
 | |
|  * be called before vduse_dev_setup_queue().
 | |
|  *
 | |
|  * Returns: 0 on success, -errno on failure.
 | |
|  */
 | |
| int vduse_set_reconnect_log_file(VduseDev *dev, const char *filename);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_create_by_fd:
 | |
|  * @fd: passed file descriptor
 | |
|  * @num_queues: the number of virtqueues
 | |
|  * @ops: the operation of VDUSE backend
 | |
|  * @priv: private pointer
 | |
|  *
 | |
|  * Create VDUSE device from a passed file descriptor.
 | |
|  *
 | |
|  * Returns: pointer to VDUSE device on success, NULL on failure.
 | |
|  */
 | |
| VduseDev *vduse_dev_create_by_fd(int fd, uint16_t num_queues,
 | |
|                                  const VduseOps *ops, void *priv);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_create_by_name:
 | |
|  * @name: VDUSE device name
 | |
|  * @num_queues: the number of virtqueues
 | |
|  * @ops: the operation of VDUSE backend
 | |
|  * @priv: private pointer
 | |
|  *
 | |
|  * Create VDUSE device on /dev/vduse/$NAME.
 | |
|  *
 | |
|  * Returns: pointer to VDUSE device on success, NULL on failure.
 | |
|  */
 | |
| VduseDev *vduse_dev_create_by_name(const char *name, uint16_t num_queues,
 | |
|                                    const VduseOps *ops, void *priv);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_create:
 | |
|  * @name: VDUSE device name
 | |
|  * @device_id: virtio device id
 | |
|  * @vendor_id: virtio vendor id
 | |
|  * @features: virtio features
 | |
|  * @num_queues: the number of virtqueues
 | |
|  * @config_size: the size of the configuration space
 | |
|  * @config: the buffer of the configuration space
 | |
|  * @ops: the operation of VDUSE backend
 | |
|  * @priv: private pointer
 | |
|  *
 | |
|  * Create VDUSE device.
 | |
|  *
 | |
|  * Returns: pointer to VDUSE device on success, NULL on failure.
 | |
|  */
 | |
| VduseDev *vduse_dev_create(const char *name, uint32_t device_id,
 | |
|                            uint32_t vendor_id, uint64_t features,
 | |
|                            uint16_t num_queues, uint32_t config_size,
 | |
|                            char *config, const VduseOps *ops, void *priv);
 | |
| 
 | |
| /**
 | |
|  * vduse_dev_destroy:
 | |
|  * @dev: VDUSE device
 | |
|  *
 | |
|  * Destroy the VDUSE device.
 | |
|  *
 | |
|  * Returns: 0 on success, -errno on failure.
 | |
|  */
 | |
| int vduse_dev_destroy(VduseDev *dev);
 | |
| 
 | |
| #endif
 |