virtio: fatures, fixes
A huge patchset supporting vq resize using the new vq reset capability. Features, fixes, cleanups all over the place. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> -----BEGIN PGP SIGNATURE----- iQFDBAABCAAtFiEEXQn9CHHI+FuUyooNKB8NuNKNVGkFAmL2F9APHG1zdEByZWRo YXQuY29tAAoJECgfDbjSjVRp00QIAKpxyu+zCtrdDuh68DsNn1Cu0y0PXG336ySy MA1ck/bv94MZBIbI/Bnn3T1jDmUqTFHJiwaGz/aZ5gGAplZiejhH5Ds3SYjHckaa MKeJ4FTXin9RESP+bXhv4BgZ+ju3KHHkf1jw3TAdVKQ7Nma1u4E6f8nprYEi0TI0 7gLUYenqzS7X1+v9O3rEvPr7tSbAKXYGYpV82sSjHIb9YPQx5luX1JJIZade8A25 mTt5hG1dP1ugUm1NEBPQHjSvdrvO3L5Ahy0My2Bkd77+tOlNF4cuMPt2NS/6+Pgd n6oMt3GXqVvw5RxZyY8dpknH5kofZhjgFyZXH0l+aNItfHUs7t0= =rIo2 -----END PGP SIGNATURE----- Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost Pull virtio updates from Michael Tsirkin: - A huge patchset supporting vq resize using the new vq reset capability - Features, fixes, and cleanups all over the place * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (88 commits) vdpa/mlx5: Fix possible uninitialized return value vdpa_sim_blk: add support for discard and write-zeroes vdpa_sim_blk: add support for VIRTIO_BLK_T_FLUSH vdpa_sim_blk: make vdpasim_blk_check_range usable by other requests vdpa_sim_blk: check if sector is 0 for commands other than read or write vdpa_sim: Implement suspend vdpa op vhost-vdpa: uAPI to suspend the device vhost-vdpa: introduce SUSPEND backend feature bit vdpa: Add suspend operation virtio-blk: Avoid use-after-free on suspend/resume virtio_vdpa: support the arg sizes of find_vqs() vhost-vdpa: Call ida_simple_remove() when failed vDPA: fix 'cast to restricted le16' warnings in vdpa.c vDPA: !FEATURES_OK should not block querying device config space vDPA/ifcvf: support userspace to query features and MQ of a management device vDPA/ifcvf: get_config_size should return a value no greater than dev implementation vhost scsi: Allow user to control num virtqueues vhost-scsi: Fix max number of virtqueues vdpa/mlx5: Support different address spaces for control and data vdpa/mlx5: Implement susupend virtqueue callback ...
This commit is contained in:
commit
7a53e17acc
51 changed files with 2171 additions and 556 deletions
|
|
@ -150,6 +150,14 @@ enum {
|
|||
MLX5_VIRTIO_NET_Q_OBJECT_STATE_ERR = 0x3,
|
||||
};
|
||||
|
||||
/* This indicates that the object was not created or has already
|
||||
* been desroyed. It is very safe to assume that this object will never
|
||||
* have so many states
|
||||
*/
|
||||
enum {
|
||||
MLX5_VIRTIO_NET_Q_OBJECT_NONE = 0xffffffff
|
||||
};
|
||||
|
||||
enum {
|
||||
MLX5_RQTC_LIST_Q_TYPE_RQ = 0x0,
|
||||
MLX5_RQTC_LIST_Q_TYPE_VIRTIO_NET_Q = 0x1,
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ struct rproc_subdev {
|
|||
/**
|
||||
* struct rproc_vring - remoteproc vring state
|
||||
* @va: virtual address
|
||||
* @len: length, in bytes
|
||||
* @num: vring size
|
||||
* @da: device address
|
||||
* @align: vring alignment
|
||||
* @notifyid: rproc-specific unique vring index
|
||||
|
|
@ -606,7 +606,7 @@ struct rproc_subdev {
|
|||
*/
|
||||
struct rproc_vring {
|
||||
void *va;
|
||||
int len;
|
||||
int num;
|
||||
u32 da;
|
||||
u32 align;
|
||||
int notifyid;
|
||||
|
|
|
|||
|
|
@ -218,6 +218,9 @@ struct vdpa_map_file {
|
|||
* @reset: Reset device
|
||||
* @vdev: vdpa device
|
||||
* Returns integer: success (0) or error (< 0)
|
||||
* @suspend: Suspend or resume the device (optional)
|
||||
* @vdev: vdpa device
|
||||
* Returns integer: success (0) or error (< 0)
|
||||
* @get_config_size: Get the size of the configuration space includes
|
||||
* fields that are conditional on feature bits.
|
||||
* @vdev: vdpa device
|
||||
|
|
@ -319,6 +322,7 @@ struct vdpa_config_ops {
|
|||
u8 (*get_status)(struct vdpa_device *vdev);
|
||||
void (*set_status)(struct vdpa_device *vdev, u8 status);
|
||||
int (*reset)(struct vdpa_device *vdev);
|
||||
int (*suspend)(struct vdpa_device *vdev);
|
||||
size_t (*get_config_size)(struct vdpa_device *vdev);
|
||||
void (*get_config)(struct vdpa_device *vdev, unsigned int offset,
|
||||
void *buf, unsigned int len);
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
* @priv: a pointer for the virtqueue implementation to use.
|
||||
* @index: the zero-based ordinal number for this queue.
|
||||
* @num_free: number of elements we expect to be able to fit.
|
||||
* @num_max: the maximum number of elements supported by the device.
|
||||
* @reset: vq is in reset state or not.
|
||||
*
|
||||
* A note on @num_free: with indirect buffers, each buffer needs one
|
||||
* element in the queue, otherwise a buffer will need one element per
|
||||
|
|
@ -31,7 +33,9 @@ struct virtqueue {
|
|||
struct virtio_device *vdev;
|
||||
unsigned int index;
|
||||
unsigned int num_free;
|
||||
unsigned int num_max;
|
||||
void *priv;
|
||||
bool reset;
|
||||
};
|
||||
|
||||
int virtqueue_add_outbuf(struct virtqueue *vq,
|
||||
|
|
@ -89,6 +93,9 @@ dma_addr_t virtqueue_get_desc_addr(struct virtqueue *vq);
|
|||
dma_addr_t virtqueue_get_avail_addr(struct virtqueue *vq);
|
||||
dma_addr_t virtqueue_get_used_addr(struct virtqueue *vq);
|
||||
|
||||
int virtqueue_resize(struct virtqueue *vq, u32 num,
|
||||
void (*recycle)(struct virtqueue *vq, void *buf));
|
||||
|
||||
/**
|
||||
* virtio_device - representation of a device using virtio
|
||||
* @index: unique position on the virtio bus
|
||||
|
|
@ -133,6 +140,9 @@ bool is_virtio_device(struct device *dev);
|
|||
void virtio_break_device(struct virtio_device *dev);
|
||||
void __virtio_unbreak_device(struct virtio_device *dev);
|
||||
|
||||
void __virtqueue_break(struct virtqueue *_vq);
|
||||
void __virtqueue_unbreak(struct virtqueue *_vq);
|
||||
|
||||
void virtio_config_changed(struct virtio_device *dev);
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
int virtio_device_freeze(struct virtio_device *dev);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ struct virtio_shm_region {
|
|||
* include a NULL entry for vqs that do not need a callback
|
||||
* names: array of virtqueue names (mainly for debugging)
|
||||
* include a NULL entry for vqs unused by driver
|
||||
* sizes: array of virtqueue sizes
|
||||
* Returns 0 on success or error status
|
||||
* @del_vqs: free virtqueues found by find_vqs().
|
||||
* @synchronize_cbs: synchronize with the virtqueue callbacks (optional)
|
||||
|
|
@ -78,6 +79,18 @@ struct virtio_shm_region {
|
|||
* @set_vq_affinity: set the affinity for a virtqueue (optional).
|
||||
* @get_vq_affinity: get the affinity for a virtqueue (optional).
|
||||
* @get_shm_region: get a shared memory region based on the index.
|
||||
* @disable_vq_and_reset: reset a queue individually (optional).
|
||||
* vq: the virtqueue
|
||||
* Returns 0 on success or error status
|
||||
* disable_vq_and_reset will guarantee that the callbacks are disabled and
|
||||
* synchronized.
|
||||
* Except for the callback, the caller should guarantee that the vring is
|
||||
* not accessed by any functions of virtqueue.
|
||||
* @enable_vq_after_reset: enable a reset queue
|
||||
* vq: the virtqueue
|
||||
* Returns 0 on success or error status
|
||||
* If disable_vq_and_reset is set, then enable_vq_after_reset must also be
|
||||
* set.
|
||||
*/
|
||||
typedef void vq_callback_t(struct virtqueue *);
|
||||
struct virtio_config_ops {
|
||||
|
|
@ -91,7 +104,9 @@ struct virtio_config_ops {
|
|||
void (*reset)(struct virtio_device *vdev);
|
||||
int (*find_vqs)(struct virtio_device *, unsigned nvqs,
|
||||
struct virtqueue *vqs[], vq_callback_t *callbacks[],
|
||||
const char * const names[], const bool *ctx,
|
||||
const char * const names[],
|
||||
u32 sizes[],
|
||||
const bool *ctx,
|
||||
struct irq_affinity *desc);
|
||||
void (*del_vqs)(struct virtio_device *);
|
||||
void (*synchronize_cbs)(struct virtio_device *);
|
||||
|
|
@ -104,6 +119,8 @@ struct virtio_config_ops {
|
|||
int index);
|
||||
bool (*get_shm_region)(struct virtio_device *vdev,
|
||||
struct virtio_shm_region *region, u8 id);
|
||||
int (*disable_vq_and_reset)(struct virtqueue *vq);
|
||||
int (*enable_vq_after_reset)(struct virtqueue *vq);
|
||||
};
|
||||
|
||||
/* If driver didn't advertise the feature, it will never appear. */
|
||||
|
|
@ -198,7 +215,7 @@ struct virtqueue *virtio_find_single_vq(struct virtio_device *vdev,
|
|||
const char *names[] = { n };
|
||||
struct virtqueue *vq;
|
||||
int err = vdev->config->find_vqs(vdev, 1, &vq, callbacks, names, NULL,
|
||||
NULL);
|
||||
NULL, NULL);
|
||||
if (err < 0)
|
||||
return ERR_PTR(err);
|
||||
return vq;
|
||||
|
|
@ -210,7 +227,8 @@ int virtio_find_vqs(struct virtio_device *vdev, unsigned nvqs,
|
|||
const char * const names[],
|
||||
struct irq_affinity *desc)
|
||||
{
|
||||
return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL, desc);
|
||||
return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL,
|
||||
NULL, desc);
|
||||
}
|
||||
|
||||
static inline
|
||||
|
|
@ -219,8 +237,20 @@ int virtio_find_vqs_ctx(struct virtio_device *vdev, unsigned nvqs,
|
|||
const char * const names[], const bool *ctx,
|
||||
struct irq_affinity *desc)
|
||||
{
|
||||
return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, ctx,
|
||||
desc);
|
||||
return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, NULL,
|
||||
ctx, desc);
|
||||
}
|
||||
|
||||
static inline
|
||||
int virtio_find_vqs_ctx_size(struct virtio_device *vdev, u32 nvqs,
|
||||
struct virtqueue *vqs[],
|
||||
vq_callback_t *callbacks[],
|
||||
const char * const names[],
|
||||
u32 sizes[],
|
||||
const bool *ctx, struct irq_affinity *desc)
|
||||
{
|
||||
return vdev->config->find_vqs(vdev, nvqs, vqs, callbacks, names, sizes,
|
||||
ctx, desc);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -5,6 +5,13 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/virtio_pci.h>
|
||||
|
||||
struct virtio_pci_modern_common_cfg {
|
||||
struct virtio_pci_common_cfg cfg;
|
||||
|
||||
__le16 queue_notify_data; /* read-write */
|
||||
__le16 queue_reset; /* read-write */
|
||||
};
|
||||
|
||||
struct virtio_pci_modern_device {
|
||||
struct pci_dev *pci_dev;
|
||||
|
||||
|
|
@ -106,4 +113,6 @@ void __iomem * vp_modern_map_vq_notify(struct virtio_pci_modern_device *mdev,
|
|||
u16 index, resource_size_t *pa);
|
||||
int vp_modern_probe(struct virtio_pci_modern_device *mdev);
|
||||
void vp_modern_remove(struct virtio_pci_modern_device *mdev);
|
||||
int vp_modern_get_queue_reset(struct virtio_pci_modern_device *mdev, u16 index);
|
||||
void vp_modern_set_queue_reset(struct virtio_pci_modern_device *mdev, u16 index);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -76,16 +76,6 @@ struct virtqueue *vring_create_virtqueue(unsigned int index,
|
|||
void (*callback)(struct virtqueue *vq),
|
||||
const char *name);
|
||||
|
||||
/* Creates a virtqueue with a custom layout. */
|
||||
struct virtqueue *__vring_new_virtqueue(unsigned int index,
|
||||
struct vring vring,
|
||||
struct virtio_device *vdev,
|
||||
bool weak_barriers,
|
||||
bool ctx,
|
||||
bool (*notify)(struct virtqueue *),
|
||||
void (*callback)(struct virtqueue *),
|
||||
const char *name);
|
||||
|
||||
/*
|
||||
* Creates a virtqueue with a standard layout but a caller-allocated
|
||||
* ring.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue