diff --git a/arch/arm64/configs/generic_vm_defconfig b/arch/arm64/configs/generic_vm_defconfig index 892bff87672b..f39086fe013e 100644 --- a/arch/arm64/configs/generic_vm_defconfig +++ b/arch/arm64/configs/generic_vm_defconfig @@ -121,6 +121,7 @@ CONFIG_DMABUF_HEAPS=y CONFIG_UIO=y CONFIG_VIRTIO_MMIO=y CONFIG_VIRTIO_MMIO_SWIOTLB=y +CONFIG_GH_VIRTIO_DEBUG=y CONFIG_ANDROID_VENDOR_HOOKS=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index dd9a05174726..2b74631a9566 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -16,6 +16,9 @@ #include #include #include +#ifdef CONFIG_GH_VIRTIO_DEBUG +#include +#endif #define PART_BITS 4 #define VQ_NAME_LEN 16 @@ -285,6 +288,9 @@ static void virtblk_done(struct virtqueue *vq) if (likely(!blk_should_fake_timeout(req->q))) blk_mq_complete_request(req); +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_block_done(vq->vdev->index, req_op(req), blk_rq_pos(req)); +#endif req_done = true; } if (unlikely(virtqueue_is_broken(vq))) @@ -351,6 +357,10 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx, spin_lock_irqsave(&vblk->vqs[qid].lock, flags); err = virtblk_add_req(vblk->vqs[qid].vq, vbr); +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_block_submit(vblk->vqs[qid].vq->vdev->index, + vbr->out_hdr.type, vbr->out_hdr.sector, vbr->out_hdr.ioprio, err); +#endif if (err) { virtqueue_kick(vblk->vqs[qid].vq); /* Don't stop the queue if -ENOMEM: we may have failed to diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig index f0db84b4137c..f6a22e108f94 100644 --- a/drivers/virtio/Kconfig +++ b/drivers/virtio/Kconfig @@ -167,6 +167,15 @@ config VIRTIO_MMIO_SWIOTLB shared with another virtual machine which is hosting virtio backend drivers. +config GH_VIRTIO_DEBUG + bool "Enable debug features for virtio front-end drivers on Gunyah Hypervisor" + depends on VIRTIO_MMIO + help + Activating this feature provides additional tracepoints in various + virtio drivers that will be useful to debug virtio transactions. + Currently virtio block driver and mmio transport provide few + tracepoints when this feature is enabled. + config VIRTIO_MMIO_CMDLINE_DEVICES bool "Memory mapped virtio devices parameter parsing" depends on VIRTIO_MMIO diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 01b96c3e987b..21f35cdc865e 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c @@ -70,6 +70,13 @@ #include #include #include + +#ifdef CONFIG_GH_VIRTIO_DEBUG +#define CREATE_TRACE_POINTS +#include +#undef CREATE_TRACE_POINTS +#endif + #ifdef CONFIG_VIRTIO_MMIO_SWIOTLB #include #include @@ -296,6 +303,9 @@ static bool vm_notify(struct virtqueue *vq) { struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vq->vdev); +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_mmio_vm_notify(vq->vdev->index, vq->index); +#endif /* We write the queue's selector into the notification register to * signal the other end */ writel(vq->index, vm_dev->base + VIRTIO_MMIO_QUEUE_NOTIFY); @@ -313,6 +323,10 @@ static irqreturn_t vm_interrupt(int irq, void *opaque) /* Read and acknowledge interrupts */ status = readl(vm_dev->base + VIRTIO_MMIO_INTERRUPT_STATUS); +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_mmio_vm_interrupt(vm_dev->vdev.index, status); +#endif + writel(status, vm_dev->base + VIRTIO_MMIO_INTERRUPT_ACK); if (unlikely(status & VIRTIO_MMIO_INT_CONFIG)) { diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 4620e9d79dde..e2016001db3e 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -12,6 +12,9 @@ #include #include #include +#ifdef CONFIG_GH_VIRTIO_DEBUG +#include +#endif #include #ifdef DEBUG @@ -656,6 +659,11 @@ static inline int virtqueue_add_split(struct virtqueue *_vq, pr_debug("Added buffer head %i to %p\n", head, vq); END_USE(vq); +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_vring_split_add(_vq->vdev->index, head, + vq->split.avail_idx_shadow-1, descs_used, vq->vq.num_free); +#endif + /* This is very unlikely, but theoretically possible. Kick * just in case. */ @@ -745,6 +753,10 @@ static void detach_buf_split(struct vring_virtqueue *vq, unsigned int head, /* Plus final descriptor */ vq->vq.num_free++; +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_detach_buf(vq->vq.vdev->index, vq->free_head, vq->vq.num_free); +#endif + if (vq->indirect) { struct vring_desc *indir_desc = vq->split.desc_state[head].indir_desc; @@ -792,6 +804,11 @@ static void *virtqueue_get_buf_ctx_split(struct virtqueue *_vq, return NULL; } +#ifdef CONFIG_GH_VIRTIO_DEBUG + trace_virtio_get_buf_ctx_split(_vq->vdev->index, vq->last_used_idx, + virtio16_to_cpu(vq->vq.vdev, vq->split.vring.used->idx)); +#endif + if (!more_used_split(vq)) { pr_debug("No more buffers in queue\n"); END_USE(vq); diff --git a/include/trace/events/gh_virtio_frontend.h b/include/trace/events/gh_virtio_frontend.h index 0e48e124220a..d1f981708a6e 100644 --- a/include/trace/events/gh_virtio_frontend.h +++ b/include/trace/events/gh_virtio_frontend.h @@ -146,9 +146,9 @@ TRACE_EVENT(virtio_block_done, TRACE_EVENT(virtio_block_submit, TP_PROTO(unsigned int dev_index, unsigned int type, unsigned int sector, - unsigned int ioprio, int err, unsigned int num), + unsigned int ioprio, int err), - TP_ARGS(dev_index, type, sector, ioprio, err, num), + TP_ARGS(dev_index, type, sector, ioprio, err), TP_STRUCT__entry( __field(unsigned int, dev_index) @@ -156,7 +156,6 @@ TRACE_EVENT(virtio_block_submit, __field(unsigned int, sector) __field(unsigned int, ioprio) __field(int, err) - __field(unsigned int, num) ), TP_fast_assign( @@ -165,12 +164,10 @@ TRACE_EVENT(virtio_block_submit, __entry->sector = sector; __entry->ioprio = ioprio; __entry->err = err; - __entry->num = num; ), - TP_printk("virtio%u type %x sector %u ioprio %u num %d err %d", - __entry->dev_index, __entry->type, __entry->sector, - __entry->ioprio, __entry->num, __entry->err) + TP_printk("virtio%u type %x sector %u ioprio %u err %d", __entry->dev_index, + __entry->type, __entry->sector, __entry->ioprio, __entry->err) ); #endif /* _TRACE_GH_VIRTIO_FRONTEND_H */