[PATCH 2/2] drm/i915/gvt: Add new debugfs tool mmio_diff
Zhenyu Wang
zhenyuw at linux.intel.com
Fri Oct 20 09:08:08 UTC 2017
On 2017.10.17 10:00:41 +0800, changbin.du at intel.com wrote:
> From: Changbin Du <changbin.du at intel.com>
>
> This new debugfs entry is used to figure out which registers of vGPU
> is different to host. It is a useful tool for new platform enabling
> and debugging. When read this entry, all the diff mmio are recognized
> and sorted by mmio offset. Besides, the bit positions of different
> value are listed in 'Diff' column. Here is a show:
>
> $ sudo cat ./mmio_diff
> Offset HW vGPU Diff
> 00002030 000025f8 00000000 3-8,10,13
> 00002034 012025f8 00000000 3-8,10,13,21,24
> 00002038 027fb000 00000000 12-13,15-22,25
> 0000203c 00003000 00000000 12-13
> 00002054 0000000a 00000040 1,3,6
> 00002074 012025f8 00000000 3-8,10,13,21,24
> 00002080 fffe6000 00000000 13-14,17-31
> 000020a8 fffffeff ffffffff 8
> 000020d4 00000004 00000000 2
> ....
> 00145974 eb42718c 010c11b0 2-5,13-14,17-19,22,25,27,29-31
> 00145978 0000002f 0000002a 0,2
> 0014597c 0000002f 0000002a 0,2
> 00145980 0000002b 00000028 0-1
> 00145984 a5a87c9e b27d20c0 1-4,6,10-12,14,16,18,20,22-26,28
> 001459c0 88390000 883c0000 16,18
> 00146200 88350000 883a0000 16-19
> Total: 72432, Diff: 901
>
> Signed-off-by: Changbin Du <changbin.du at intel.com>
> ---
> drivers/gpu/drm/i915/gvt/debugfs.c | 113 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 113 insertions(+)
>
> diff --git a/drivers/gpu/drm/i915/gvt/debugfs.c b/drivers/gpu/drm/i915/gvt/debugfs.c
> index 02acd58..c8c09cc 100644
> --- a/drivers/gpu/drm/i915/gvt/debugfs.c
> +++ b/drivers/gpu/drm/i915/gvt/debugfs.c
> @@ -21,9 +21,117 @@
> * SOFTWARE.
> */
> #include <linux/debugfs.h>
> +#include <linux/list_sort.h>
> #include "i915_drv.h"
> #include "gvt.h"
>
> +struct mmio_diff_param {
> + struct intel_vgpu *vgpu;
> + int total;
> + int diff;
> + struct list_head diff_mmio_list;
> +};
> +
> +struct diff_mmio {
> + struct list_head node;
> + u32 offset;
> + u32 preg;
> + u32 vreg;
> +};
> +
> +/* Compare two diff_mmio items. */
> +static int mmio_offset_compare(void *priv,
> + struct list_head *a, struct list_head *b)
> +{
> + struct diff_mmio *ma;
> + struct diff_mmio *mb;
> +
> + ma = container_of(a, struct diff_mmio, node);
> + mb = container_of(b, struct diff_mmio, node);
> + if (ma->offset < mb->offset)
> + return -1;
> + else if (ma->offset > mb->offset)
> + return 1;
> + return 0;
> +}
> +
> +static inline int mmio_diff_handler(struct intel_gvt *gvt,
> + u32 offset, void *data)
> +{
> + struct drm_i915_private *dev_priv = gvt->dev_priv;
> + struct mmio_diff_param *param = data;
> + struct diff_mmio *node;
> + u32 preg, vreg;
> +
> + preg = I915_READ_NOTRACE(_MMIO(offset));
> + vreg = vgpu_vreg(param->vgpu, offset);
> +
> + if (preg != vreg) {
> + node = kmalloc(sizeof(*node), GFP_KERNEL);
> + if (!node)
> + return -ENOMEM;
> +
> + node->offset = offset;
> + node->preg = preg;
> + node->vreg = vreg;
> + list_add(&node->node, ¶m->diff_mmio_list);
> + param->diff++;
> + }
> + param->total++;
> + return 0;
> +}
> +
> +/* Show the all the different values of tracked mmio. */
> +static int vgpu_mmio_diff_show(struct seq_file *s, void *unused)
> +{
> + struct intel_vgpu *vgpu = s->private;
> + struct intel_gvt *gvt = vgpu->gvt;
> + struct mmio_diff_param param = {
> + .vgpu = vgpu,
> + .total = 0,
> + .diff = 0,
> + };
> + struct diff_mmio *node, *next;
> +
> + INIT_LIST_HEAD(¶m.diff_mmio_list);
> +
> + mutex_lock(&gvt->lock);
> + spin_lock_bh(&gvt->scheduler.mmio_context_lock);
> +
need mmio_hw_access_pre()/post() for runtime pm
> + /* Recognize all the diff mmios to list. */
> + intel_gvt_for_each_tracked_mmio(gvt, mmio_diff_handler, ¶m);
> +
> + spin_unlock_bh(&gvt->scheduler.mmio_context_lock);
> + mutex_unlock(&gvt->lock);
> +
> + /* In an ascending order by mmio offset. */
> + list_sort(NULL, ¶m.diff_mmio_list, mmio_offset_compare);
> +
> + seq_printf(s, "%-8s %-8s %-8s %-8s\n", "Offset", "HW", "vGPU", "Diff");
> + list_for_each_entry_safe(node, next, ¶m.diff_mmio_list, node) {
> + u32 diff = node->preg ^ node->vreg;
> +
> + seq_printf(s, "%08x %08x %08x %*pbl\n",
> + node->offset, node->preg, node->vreg,
> + 32, &diff);
> + list_del(&node->node);
> + kfree(node);
> + }
> + seq_printf(s, "Total: %d, Diff: %d\n", param.total, param.diff);
> + return 0;
> +}
> +
> +static int vgpu_mmio_diff_open(struct inode *inode, struct file *file)
> +{
> + return single_open(file, vgpu_mmio_diff_show, inode->i_private);
> +}
> +
> +static const struct file_operations vgpu_mmio_diff_fops = {
> + .open = vgpu_mmio_diff_open,
> + .read = seq_read,
> + .llseek = seq_lseek,
> + .release = single_release,
> +};
>
> /**
> * intel_gvt_debugfs_add_vgpu - register debugfs entries for a vGPU
> @@ -47,6 +155,11 @@ int intel_gvt_debugfs_add_vgpu(struct intel_vgpu *vgpu)
> if (!ent)
> return -ENOMEM;
>
> + ent = debugfs_create_file("mmio_diff", 0444, vgpu->debugfs,
> + vgpu, &vgpu_mmio_diff_fops);
> + if (!ent)
> + return -ENOMEM;
> +
> return 0;
> }
>
> --
> 2.7.4
>
> _______________________________________________
> intel-gvt-dev mailing list
> intel-gvt-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gvt-dev
--
Open Source Technology Center, Intel ltd.
$gpg --keyserver wwwkeys.pgp.net --recv-keys 4D781827
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/intel-gvt-dev/attachments/20171020/fb89992f/attachment.sig>
More information about the intel-gvt-dev
mailing list