Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

virtio: provide a method to get the IRQ affinity mask for a virtqueue

This basically passed up the pci_irq_get_affinity information through
virtio through an optional get_vq_affinity method. It is only implemented
by the PCI backend for now, and only when we use per-virtqueue IRQs.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Christoph Hellwig and committed by
Michael S. Tsirkin
bbaba479 fb5e31d9

+19
+11
drivers/virtio/virtio_pci_common.c
··· 361 361 return 0; 362 362 } 363 363 364 + const struct cpumask *vp_get_vq_affinity(struct virtio_device *vdev, int index) 365 + { 366 + struct virtio_pci_device *vp_dev = to_vp_device(vdev); 367 + unsigned int *map = vp_dev->msix_vector_map; 368 + 369 + if (!map || map[index] == VIRTIO_MSI_NO_VECTOR) 370 + return NULL; 371 + 372 + return pci_irq_get_affinity(vp_dev->pci_dev, map[index]); 373 + } 374 + 364 375 #ifdef CONFIG_PM_SLEEP 365 376 static int virtio_pci_freeze(struct device *dev) 366 377 {
+2
drivers/virtio/virtio_pci_common.h
··· 108 108 */ 109 109 int vp_set_vq_affinity(struct virtqueue *vq, int cpu); 110 110 111 + const struct cpumask *vp_get_vq_affinity(struct virtio_device *vdev, int index); 112 + 111 113 #if IS_ENABLED(CONFIG_VIRTIO_PCI_LEGACY) 112 114 int virtio_pci_legacy_probe(struct virtio_pci_device *); 113 115 void virtio_pci_legacy_remove(struct virtio_pci_device *);
+1
drivers/virtio/virtio_pci_legacy.c
··· 190 190 .finalize_features = vp_finalize_features, 191 191 .bus_name = vp_bus_name, 192 192 .set_vq_affinity = vp_set_vq_affinity, 193 + .get_vq_affinity = vp_get_vq_affinity, 193 194 }; 194 195 195 196 /* the PCI probing function */
+2
drivers/virtio/virtio_pci_modern.c
··· 437 437 .finalize_features = vp_finalize_features, 438 438 .bus_name = vp_bus_name, 439 439 .set_vq_affinity = vp_set_vq_affinity, 440 + .get_vq_affinity = vp_get_vq_affinity, 440 441 }; 441 442 442 443 static const struct virtio_config_ops virtio_pci_config_ops = { ··· 453 452 .finalize_features = vp_finalize_features, 454 453 .bus_name = vp_bus_name, 455 454 .set_vq_affinity = vp_set_vq_affinity, 455 + .get_vq_affinity = vp_get_vq_affinity, 456 456 }; 457 457 458 458 /**
+3
include/linux/virtio_config.h
··· 58 58 * This returns a pointer to the bus name a la pci_name from which 59 59 * the caller can then copy. 60 60 * @set_vq_affinity: set the affinity for a virtqueue. 61 + * @get_vq_affinity: get the affinity for a virtqueue (optional). 61 62 */ 62 63 typedef void vq_callback_t(struct virtqueue *); 63 64 struct virtio_config_ops { ··· 78 77 int (*finalize_features)(struct virtio_device *vdev); 79 78 const char *(*bus_name)(struct virtio_device *vdev); 80 79 int (*set_vq_affinity)(struct virtqueue *vq, int cpu); 80 + const struct cpumask *(*get_vq_affinity)(struct virtio_device *vdev, 81 + int index); 81 82 }; 82 83 83 84 /* If driver didn't advertise the feature, it will never appear. */