Re: [PATCH v4 2/5] iommu/vt-d: debugfs: Add support to show inv queue internals

2020-05-07 Thread Lu Baolu

Hi Jacob,

On 5/8/20 12:47 AM, Jacob Pan wrote:

Hi Baolu,

Very helpful feature, thanks for doing this. Just a small suggestion.


Thanks a lot for reviewing my patch.



On Thu,  7 May 2020 08:55:31 +0800
Lu Baolu  wrote:


Export invalidation queue internals of each iommu device through the
debugfs.

Example of such dump on a Skylake machine:

$ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue
Invalidation queue on IOMMU: dmar1
  Base: 0x1672c9000  Head: 80Tail: 80
Index   qw0 qw1 status
 0   0004
 1   000200250001672be804
 2   0011
 3   000200250001672be80c
 4   00d2
 5   000200250001672be814
 6   0014
 7   000200250001672be81c
 8   0014
 9   000200250001672be824



Head and Tail shows the offset, and queue is dump with index. Would it
be nice to mark where the Head and Tail is in the list?


The Head and Tail actually show the index. I will mark it clearly in the
dump to avoid any confusion. Thanks for the reminding.


In your example, the queue is empty (H=T), would be nice to see where
the previous entry is if there were any faults.



The qi_check_fault() has already cleared the faults and moved ahead the
HEAD register. So probably the developers have to check the kernel log
and locate the fault descriptor by themselves.

Best regards,
baolu


Re: [PATCH v4 2/5] iommu/vt-d: debugfs: Add support to show inv queue internals

2020-05-07 Thread Jacob Pan
Hi Baolu,

Very helpful feature, thanks for doing this. Just a small suggestion.

On Thu,  7 May 2020 08:55:31 +0800
Lu Baolu  wrote:

> Export invalidation queue internals of each iommu device through the
> debugfs.
> 
> Example of such dump on a Skylake machine:
> 
> $ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue
> Invalidation queue on IOMMU: dmar1
>  Base: 0x1672c9000  Head: 80Tail: 80
> Index   qw0 qw1 status
> 0   0004
>  1   000200250001672be804
>  2   0011
>  3   000200250001672be80c
>  4   00d2
>  5   000200250001672be814
>  6   0014
>  7   000200250001672be81c
>  8   0014
>  9   000200250001672be824
> 
> 
Head and Tail shows the offset, and queue is dump with index. Would it
be nice to mark where the Head and Tail is in the list?
In your example, the queue is empty (H=T), would be nice to see where
the previous entry is if there were any faults.

> Signed-off-by: Lu Baolu 
> ---
>  drivers/iommu/intel-iommu-debugfs.c | 62
> + 1 file changed, 62 insertions(+)
> 
> diff --git a/drivers/iommu/intel-iommu-debugfs.c
> b/drivers/iommu/intel-iommu-debugfs.c index
> 3eb1fe240fb0..e3089865b8f3 100644 ---
> a/drivers/iommu/intel-iommu-debugfs.c +++
> b/drivers/iommu/intel-iommu-debugfs.c @@ -372,6 +372,66 @@ static int
> domain_translation_struct_show(struct seq_file *m, void *unused) }
>  DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
>  
> +static void invalidation_queue_entry_show(struct seq_file *m,
> +   struct intel_iommu *iommu)
> +{
> + int index, shift = qi_shift(iommu);
> + struct qi_desc *desc;
> + int offset;
> +
> + if (ecap_smts(iommu->ecap))
> + seq_puts(m,
> "Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
> + else
> + seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
> +
> + for (index = 0; index < QI_LENGTH; index++) {
> + offset = index << shift;
> + desc = iommu->qi->desc + offset;
> + if (ecap_smts(iommu->ecap))
> + seq_printf(m,
> "%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
> +index, desc->qw0, desc->qw1,
> +desc->qw2, desc->qw3,
> +iommu->qi->desc_status[index]);
> + else
> + seq_printf(m,
> "%5d\t%016llx\t%016llx\t%016x\n",
> +index, desc->qw0, desc->qw1,
> +iommu->qi->desc_status[index]);
> + }
> +}
> +
> +static int invalidation_queue_show(struct seq_file *m, void *unused)
> +{
> + struct dmar_drhd_unit *drhd;
> + struct intel_iommu *iommu;
> + unsigned long flags;
> + struct q_inval *qi;
> + int shift;
> +
> + rcu_read_lock();
> + for_each_active_iommu(iommu, drhd) {
> + qi = iommu->qi;
> + shift = qi_shift(iommu);
> +
> + if (!qi || !ecap_qis(iommu->ecap))
> + continue;
> +
> + seq_printf(m, "Invalidation queue on IOMMU: %s\n",
> iommu->name); +
> + raw_spin_lock_irqsave(>q_lock, flags);
> + seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail:
> %lld\n",
> +virt_to_phys(qi->desc),
> +dmar_readq(iommu->reg + DMAR_IQH_REG) >>
> shift,
> +dmar_readq(iommu->reg + DMAR_IQT_REG) >>
> shift);
> + invalidation_queue_entry_show(m, iommu);
> + raw_spin_unlock_irqrestore(>q_lock, flags);
> + seq_putc(m, '\n');
> + }
> + rcu_read_unlock();
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
> +
>  #ifdef CONFIG_IRQ_REMAP
>  static void ir_tbl_remap_entry_show(struct seq_file *m,
>   struct intel_iommu *iommu)
> @@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
>   debugfs_create_file("domain_translation_struct", 0444,
>   intel_iommu_debug, NULL,
>   _translation_struct_fops);
> + debugfs_create_file("invalidation_queue", 0444,
> intel_iommu_debug,
> + NULL, _queue_fops);
>  #ifdef CONFIG_IRQ_REMAP
>   debugfs_create_file("ir_translation_struct", 0444,
> intel_iommu_debug, NULL, _translation_struct_fops);

[Jacob Pan]


RE: [PATCH v4 2/5] iommu/vt-d: debugfs: Add support to show inv queue internals

2020-05-06 Thread Tian, Kevin
> From: Lu Baolu 
> Sent: Thursday, May 7, 2020 8:56 AM
> 
> Export invalidation queue internals of each iommu device through the
> debugfs.
> 
> Example of such dump on a Skylake machine:
> 
> $ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue
> Invalidation queue on IOMMU: dmar1
>  Base: 0x1672c9000  Head: 80Tail: 80
> Index   qw0 qw1 status
> 0   0004
> 1   000200250001672be804
> 2   0011
> 3   000200250001672be80c
> 4   00d2
> 5   000200250001672be814
> 6   0014
> 7   000200250001672be81c
> 8   0014
> 9   000200250001672be824
> 
> Signed-off-by: Lu Baolu 
> ---
>  drivers/iommu/intel-iommu-debugfs.c | 62
> +
>  1 file changed, 62 insertions(+)
> 
> diff --git a/drivers/iommu/intel-iommu-debugfs.c b/drivers/iommu/intel-
> iommu-debugfs.c
> index 3eb1fe240fb0..e3089865b8f3 100644
> --- a/drivers/iommu/intel-iommu-debugfs.c
> +++ b/drivers/iommu/intel-iommu-debugfs.c
> @@ -372,6 +372,66 @@ static int domain_translation_struct_show(struct
> seq_file *m, void *unused)
>  }
>  DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
> 
> +static void invalidation_queue_entry_show(struct seq_file *m,
> +   struct intel_iommu *iommu)
> +{
> + int index, shift = qi_shift(iommu);
> + struct qi_desc *desc;
> + int offset;
> +
> + if (ecap_smts(iommu->ecap))
> + seq_puts(m,
> "Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
> + else
> + seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
> +
> + for (index = 0; index < QI_LENGTH; index++) {
> + offset = index << shift;
> + desc = iommu->qi->desc + offset;
> + if (ecap_smts(iommu->ecap))
> + seq_printf(m,
> "%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
> +index, desc->qw0, desc->qw1,
> +desc->qw2, desc->qw3,
> +iommu->qi->desc_status[index]);
> + else
> + seq_printf(m, "%5d\t%016llx\t%016llx\t%016x\n",
> +index, desc->qw0, desc->qw1,
> +iommu->qi->desc_status[index]);
> + }
> +}
> +
> +static int invalidation_queue_show(struct seq_file *m, void *unused)
> +{
> + struct dmar_drhd_unit *drhd;
> + struct intel_iommu *iommu;
> + unsigned long flags;
> + struct q_inval *qi;
> + int shift;
> +
> + rcu_read_lock();
> + for_each_active_iommu(iommu, drhd) {
> + qi = iommu->qi;
> + shift = qi_shift(iommu);
> +
> + if (!qi || !ecap_qis(iommu->ecap))
> + continue;
> +
> + seq_printf(m, "Invalidation queue on IOMMU: %s\n",
> iommu->name);
> +
> + raw_spin_lock_irqsave(>q_lock, flags);
> + seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail: %lld\n",
> +virt_to_phys(qi->desc),
> +dmar_readq(iommu->reg + DMAR_IQH_REG) >>
> shift,
> +dmar_readq(iommu->reg + DMAR_IQT_REG) >>
> shift);
> + invalidation_queue_entry_show(m, iommu);
> + raw_spin_unlock_irqrestore(>q_lock, flags);
> + seq_putc(m, '\n');
> + }
> + rcu_read_unlock();
> +
> + return 0;
> +}
> +DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
> +
>  #ifdef CONFIG_IRQ_REMAP
>  static void ir_tbl_remap_entry_show(struct seq_file *m,
>   struct intel_iommu *iommu)
> @@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
>   debugfs_create_file("domain_translation_struct", 0444,
>   intel_iommu_debug, NULL,
>   _translation_struct_fops);
> + debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
> + NULL, _queue_fops);
>  #ifdef CONFIG_IRQ_REMAP
>   debugfs_create_file("ir_translation_struct", 0444,
> intel_iommu_debug,
>   NULL, _translation_struct_fops);
> --
> 2.17.1

Reviewed-by: Kevin Tian 


[PATCH v4 2/5] iommu/vt-d: debugfs: Add support to show inv queue internals

2020-05-06 Thread Lu Baolu
Export invalidation queue internals of each iommu device through the
debugfs.

Example of such dump on a Skylake machine:

$ sudo cat /sys/kernel/debug/iommu/intel/invalidation_queue
Invalidation queue on IOMMU: dmar1
 Base: 0x1672c9000  Head: 80Tail: 80
Index   qw0 qw1 status
0   0004
1   000200250001672be804
2   0011
3   000200250001672be80c
4   00d2
5   000200250001672be814
6   0014
7   000200250001672be81c
8   0014
9   000200250001672be824

Signed-off-by: Lu Baolu 
---
 drivers/iommu/intel-iommu-debugfs.c | 62 +
 1 file changed, 62 insertions(+)

diff --git a/drivers/iommu/intel-iommu-debugfs.c 
b/drivers/iommu/intel-iommu-debugfs.c
index 3eb1fe240fb0..e3089865b8f3 100644
--- a/drivers/iommu/intel-iommu-debugfs.c
+++ b/drivers/iommu/intel-iommu-debugfs.c
@@ -372,6 +372,66 @@ static int domain_translation_struct_show(struct seq_file 
*m, void *unused)
 }
 DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
 
+static void invalidation_queue_entry_show(struct seq_file *m,
+ struct intel_iommu *iommu)
+{
+   int index, shift = qi_shift(iommu);
+   struct qi_desc *desc;
+   int offset;
+
+   if (ecap_smts(iommu->ecap))
+   seq_puts(m, 
"Index\t\tqw0\t\t\tqw1\t\t\tqw2\t\t\tqw3\t\t\tstatus\n");
+   else
+   seq_puts(m, "Index\t\tqw0\t\t\tqw1\t\t\tstatus\n");
+
+   for (index = 0; index < QI_LENGTH; index++) {
+   offset = index << shift;
+   desc = iommu->qi->desc + offset;
+   if (ecap_smts(iommu->ecap))
+   seq_printf(m, 
"%5d\t%016llx\t%016llx\t%016llx\t%016llx\t%016x\n",
+  index, desc->qw0, desc->qw1,
+  desc->qw2, desc->qw3,
+  iommu->qi->desc_status[index]);
+   else
+   seq_printf(m, "%5d\t%016llx\t%016llx\t%016x\n",
+  index, desc->qw0, desc->qw1,
+  iommu->qi->desc_status[index]);
+   }
+}
+
+static int invalidation_queue_show(struct seq_file *m, void *unused)
+{
+   struct dmar_drhd_unit *drhd;
+   struct intel_iommu *iommu;
+   unsigned long flags;
+   struct q_inval *qi;
+   int shift;
+
+   rcu_read_lock();
+   for_each_active_iommu(iommu, drhd) {
+   qi = iommu->qi;
+   shift = qi_shift(iommu);
+
+   if (!qi || !ecap_qis(iommu->ecap))
+   continue;
+
+   seq_printf(m, "Invalidation queue on IOMMU: %s\n", iommu->name);
+
+   raw_spin_lock_irqsave(>q_lock, flags);
+   seq_printf(m, " Base: 0x%llx\tHead: %lld\tTail: %lld\n",
+  virt_to_phys(qi->desc),
+  dmar_readq(iommu->reg + DMAR_IQH_REG) >> shift,
+  dmar_readq(iommu->reg + DMAR_IQT_REG) >> shift);
+   invalidation_queue_entry_show(m, iommu);
+   raw_spin_unlock_irqrestore(>q_lock, flags);
+   seq_putc(m, '\n');
+   }
+   rcu_read_unlock();
+
+   return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(invalidation_queue);
+
 #ifdef CONFIG_IRQ_REMAP
 static void ir_tbl_remap_entry_show(struct seq_file *m,
struct intel_iommu *iommu)
@@ -490,6 +550,8 @@ void __init intel_iommu_debugfs_init(void)
debugfs_create_file("domain_translation_struct", 0444,
intel_iommu_debug, NULL,
_translation_struct_fops);
+   debugfs_create_file("invalidation_queue", 0444, intel_iommu_debug,
+   NULL, _queue_fops);
 #ifdef CONFIG_IRQ_REMAP
debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
NULL, _translation_struct_fops);
-- 
2.17.1