Skip to content

Commit af22bbe

Browse files
Jiri Pirkomstsirkin
authored andcommitted
virtio: create admin queues alongside other virtqueues
Admin virtqueue is just another virtqueue nothing that special about it. The current implementation treats it somehow separate though in terms of creation and deletion. Unify the admin virtqueue creation and deletion flows to be aligned with the rest of virtqueues, creating it from vp_find_vqs_*() helpers. Let the admin virtqueue to be deleted by vp_del_vqs() as the rest. Call vp_find_one_vq_msix() with slow_path argument being "true" to make sure that in case of limited interrupt vectors the config vector is used for admin queue. Signed-off-by: Jiri Pirko <jiri@nvidia.com> Message-Id: <20240716113552.80599-10-jiri@resnulli.us> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
1 parent 89a1c43 commit af22bbe

File tree

5 files changed

+46
-96
lines changed

5 files changed

+46
-96
lines changed

drivers/virtio/virtio.c

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -305,15 +305,9 @@ static int virtio_dev_probe(struct device *_d)
305305
if (err)
306306
goto err;
307307

308-
if (dev->config->create_avq) {
309-
err = dev->config->create_avq(dev);
310-
if (err)
311-
goto err;
312-
}
313-
314308
err = drv->probe(dev);
315309
if (err)
316-
goto err_probe;
310+
goto err;
317311

318312
/* If probe didn't do it, mark device DRIVER_OK ourselves. */
319313
if (!(dev->config->get_status(dev) & VIRTIO_CONFIG_S_DRIVER_OK))
@@ -326,9 +320,6 @@ static int virtio_dev_probe(struct device *_d)
326320

327321
return 0;
328322

329-
err_probe:
330-
if (dev->config->destroy_avq)
331-
dev->config->destroy_avq(dev);
332323
err:
333324
virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
334325
return err;
@@ -344,9 +335,6 @@ static void virtio_dev_remove(struct device *_d)
344335

345336
drv->remove(dev);
346337

347-
if (dev->config->destroy_avq)
348-
dev->config->destroy_avq(dev);
349-
350338
/* Driver should have reset device. */
351339
WARN_ON_ONCE(dev->config->get_status(dev));
352340

@@ -524,9 +512,6 @@ int virtio_device_freeze(struct virtio_device *dev)
524512
}
525513
}
526514

527-
if (dev->config->destroy_avq)
528-
dev->config->destroy_avq(dev);
529-
530515
return 0;
531516
}
532517
EXPORT_SYMBOL_GPL(virtio_device_freeze);
@@ -562,16 +547,10 @@ int virtio_device_restore(struct virtio_device *dev)
562547
if (ret)
563548
goto err;
564549

565-
if (dev->config->create_avq) {
566-
ret = dev->config->create_avq(dev);
567-
if (ret)
568-
goto err;
569-
}
570-
571550
if (drv->restore) {
572551
ret = drv->restore(dev);
573552
if (ret)
574-
goto err_restore;
553+
goto err;
575554
}
576555

577556
/* If restore didn't do it, mark device DRIVER_OK ourselves. */
@@ -582,9 +561,6 @@ int virtio_device_restore(struct virtio_device *dev)
582561

583562
return 0;
584563

585-
err_restore:
586-
if (dev->config->destroy_avq)
587-
dev->config->destroy_avq(dev);
588564
err:
589565
virtio_add_status(dev, VIRTIO_CONFIG_S_FAILED);
590566
return ret;

drivers/virtio/virtio_pci_common.c

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,9 +262,6 @@ void vp_del_vqs(struct virtio_device *vdev)
262262
int i;
263263

264264
list_for_each_entry_safe(vq, n, &vdev->vqs, list) {
265-
if (vp_dev->is_avq && vp_dev->is_avq(vdev, vq->index))
266-
continue;
267-
268265
if (vp_dev->per_vq_vectors) {
269266
int v = vp_dev->vqs[vq->index]->msix_vector;
270267

@@ -371,14 +368,23 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
371368
struct irq_affinity *desc)
372369
{
373370
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
371+
struct virtio_pci_admin_vq *avq = &vp_dev->admin_vq;
374372
struct virtqueue_info *vqi;
375373
int i, err, nvectors, allocated_vectors, queue_idx = 0;
374+
struct virtqueue *vq;
376375
bool per_vq_vectors;
376+
u16 avq_num = 0;
377377

378378
vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
379379
if (!vp_dev->vqs)
380380
return -ENOMEM;
381381

382+
if (vp_dev->avq_index) {
383+
err = vp_dev->avq_index(vdev, &avq->vq_index, &avq_num);
384+
if (err)
385+
goto error_find;
386+
}
387+
382388
per_vq_vectors = vector_policy != VP_VQ_VECTOR_POLICY_SHARED;
383389

384390
if (per_vq_vectors) {
@@ -415,6 +421,18 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned int nvqs,
415421
goto error_find;
416422
}
417423
}
424+
425+
if (!avq_num)
426+
return 0;
427+
sprintf(avq->name, "avq.%u", avq->vq_index);
428+
vq = vp_find_one_vq_msix(vdev, avq->vq_index, NULL, avq->name, false,
429+
true, &allocated_vectors, vector_policy,
430+
&vp_dev->admin_vq.info);
431+
if (IS_ERR(vq)) {
432+
err = PTR_ERR(vq);
433+
goto error_find;
434+
}
435+
418436
return 0;
419437

420438
error_find:
@@ -427,12 +445,21 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
427445
struct virtqueue_info vqs_info[])
428446
{
429447
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
448+
struct virtio_pci_admin_vq *avq = &vp_dev->admin_vq;
430449
int i, err, queue_idx = 0;
450+
struct virtqueue *vq;
451+
u16 avq_num = 0;
431452

432453
vp_dev->vqs = kcalloc(nvqs, sizeof(*vp_dev->vqs), GFP_KERNEL);
433454
if (!vp_dev->vqs)
434455
return -ENOMEM;
435456

457+
if (vp_dev->avq_index) {
458+
err = vp_dev->avq_index(vdev, &avq->vq_index, &avq_num);
459+
if (err)
460+
goto out_del_vqs;
461+
}
462+
436463
err = request_irq(vp_dev->pci_dev->irq, vp_interrupt, IRQF_SHARED,
437464
dev_name(&vdev->dev), vp_dev);
438465
if (err)
@@ -456,6 +483,16 @@ static int vp_find_vqs_intx(struct virtio_device *vdev, unsigned int nvqs,
456483
}
457484
}
458485

486+
if (!avq_num)
487+
return 0;
488+
sprintf(avq->name, "avq.%u", avq->vq_index);
489+
vq = vp_setup_vq(vdev, queue_idx++, NULL, avq->name, false,
490+
VIRTIO_MSI_NO_VECTOR, &vp_dev->admin_vq.info);
491+
if (IS_ERR(vq)) {
492+
err = PTR_ERR(vq);
493+
goto out_del_vqs;
494+
}
495+
459496
return 0;
460497
out_del_vqs:
461498
vp_del_vqs(vdev);

drivers/virtio/virtio_pci_common.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ struct virtio_pci_vq_info {
4444

4545
struct virtio_pci_admin_vq {
4646
/* Virtqueue info associated with this admin queue. */
47-
struct virtio_pci_vq_info info;
47+
struct virtio_pci_vq_info *info;
4848
/* serializing admin commands execution. */
4949
struct mutex cmd_lock;
5050
u64 supported_cmds;
@@ -105,7 +105,7 @@ struct virtio_pci_device {
105105
void (*del_vq)(struct virtio_pci_vq_info *info);
106106

107107
u16 (*config_vector)(struct virtio_pci_device *vp_dev, u16 vector);
108-
bool (*is_avq)(struct virtio_device *vdev, unsigned int index);
108+
int (*avq_index)(struct virtio_device *vdev, u16 *index, u16 *num);
109109
};
110110

111111
/* Constants for MSI-X */

drivers/virtio/virtio_pci_modern.c

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static int virtqueue_exec_admin_cmd(struct virtio_pci_admin_vq *admin_vq,
6363
struct virtqueue *vq;
6464
int ret, len;
6565

66-
vq = admin_vq->info.vq;
66+
vq = admin_vq->info->vq;
6767
if (!vq)
6868
return -EIO;
6969

@@ -203,27 +203,12 @@ static void virtio_pci_admin_cmd_list_init(struct virtio_device *virtio_dev)
203203

204204
static void vp_modern_avq_activate(struct virtio_device *vdev)
205205
{
206-
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
207-
struct virtio_pci_admin_vq *admin_vq = &vp_dev->admin_vq;
208-
209206
if (!virtio_has_feature(vdev, VIRTIO_F_ADMIN_VQ))
210207
return;
211208

212-
__virtqueue_unbreak(admin_vq->info.vq);
213209
virtio_pci_admin_cmd_list_init(vdev);
214210
}
215211

216-
static void vp_modern_avq_deactivate(struct virtio_device *vdev)
217-
{
218-
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
219-
struct virtio_pci_admin_vq *admin_vq = &vp_dev->admin_vq;
220-
221-
if (!virtio_has_feature(vdev, VIRTIO_F_ADMIN_VQ))
222-
return;
223-
224-
__virtqueue_break(admin_vq->info.vq);
225-
}
226-
227212
static void vp_transport_features(struct virtio_device *vdev, u64 features)
228213
{
229214
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
@@ -418,8 +403,6 @@ static void vp_reset(struct virtio_device *vdev)
418403
while (vp_modern_get_status(mdev))
419404
msleep(1);
420405

421-
vp_modern_avq_deactivate(vdev);
422-
423406
/* Flush pending VQ/configuration callbacks. */
424407
vp_synchronize_vectors(vdev);
425408
}
@@ -595,9 +578,6 @@ static struct virtqueue *setup_vq(struct virtio_pci_device *vp_dev,
595578
goto err;
596579
}
597580

598-
if (is_avq)
599-
vp_dev->admin_vq.info.vq = vq;
600-
601581
return vq;
602582

603583
err:
@@ -741,41 +721,6 @@ static bool vp_get_shm_region(struct virtio_device *vdev,
741721
return true;
742722
}
743723

744-
static int vp_modern_create_avq(struct virtio_device *vdev)
745-
{
746-
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
747-
struct virtio_pci_admin_vq *avq = &vp_dev->admin_vq;
748-
struct virtqueue *vq;
749-
u16 num;
750-
int err;
751-
752-
err = vp_avq_index(vdev, &avq->vq_index, &num);
753-
if (err || !num)
754-
return err;
755-
756-
sprintf(avq->name, "avq.%u", avq->vq_index);
757-
vq = vp_dev->setup_vq(vp_dev, &vp_dev->admin_vq.info, avq->vq_index, NULL,
758-
avq->name, NULL, VIRTIO_MSI_NO_VECTOR);
759-
if (IS_ERR(vq)) {
760-
dev_err(&vdev->dev, "failed to setup admin virtqueue, err=%ld",
761-
PTR_ERR(vq));
762-
return PTR_ERR(vq);
763-
}
764-
765-
vp_modern_set_queue_enable(&vp_dev->mdev, avq->info.vq->index, true);
766-
return 0;
767-
}
768-
769-
static void vp_modern_destroy_avq(struct virtio_device *vdev)
770-
{
771-
struct virtio_pci_device *vp_dev = to_vp_device(vdev);
772-
773-
if (!virtio_has_feature(vdev, VIRTIO_F_ADMIN_VQ))
774-
return;
775-
776-
vp_dev->del_vq(&vp_dev->admin_vq.info);
777-
}
778-
779724
static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
780725
.get = NULL,
781726
.set = NULL,
@@ -794,8 +739,6 @@ static const struct virtio_config_ops virtio_pci_config_nodev_ops = {
794739
.get_shm_region = vp_get_shm_region,
795740
.disable_vq_and_reset = vp_modern_disable_vq_and_reset,
796741
.enable_vq_after_reset = vp_modern_enable_vq_after_reset,
797-
.create_avq = vp_modern_create_avq,
798-
.destroy_avq = vp_modern_destroy_avq,
799742
};
800743

801744
static const struct virtio_config_ops virtio_pci_config_ops = {
@@ -816,8 +759,6 @@ static const struct virtio_config_ops virtio_pci_config_ops = {
816759
.get_shm_region = vp_get_shm_region,
817760
.disable_vq_and_reset = vp_modern_disable_vq_and_reset,
818761
.enable_vq_after_reset = vp_modern_enable_vq_after_reset,
819-
.create_avq = vp_modern_create_avq,
820-
.destroy_avq = vp_modern_destroy_avq,
821762
};
822763

823764
/* the PCI probing function */
@@ -841,7 +782,7 @@ int virtio_pci_modern_probe(struct virtio_pci_device *vp_dev)
841782
vp_dev->config_vector = vp_config_vector;
842783
vp_dev->setup_vq = setup_vq;
843784
vp_dev->del_vq = del_vq;
844-
vp_dev->is_avq = vp_is_avq;
785+
vp_dev->avq_index = vp_avq_index;
845786
vp_dev->isr = mdev->isr;
846787
vp_dev->vdev.id = mdev->id;
847788

include/linux/virtio_config.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,6 @@ struct virtqueue_info {
104104
* Returns 0 on success or error status
105105
* If disable_vq_and_reset is set, then enable_vq_after_reset must also be
106106
* set.
107-
* @create_avq: create admin virtqueue resource.
108-
* @destroy_avq: destroy admin virtqueue resource.
109107
*/
110108
struct virtio_config_ops {
111109
void (*get)(struct virtio_device *vdev, unsigned offset,
@@ -133,8 +131,6 @@ struct virtio_config_ops {
133131
struct virtio_shm_region *region, u8 id);
134132
int (*disable_vq_and_reset)(struct virtqueue *vq);
135133
int (*enable_vq_after_reset)(struct virtqueue *vq);
136-
int (*create_avq)(struct virtio_device *vdev);
137-
void (*destroy_avq)(struct virtio_device *vdev);
138134
};
139135

140136
/* If driver didn't advertise the feature, it will never appear. */

0 commit comments

Comments
 (0)