| From 8fae5c2a8c13ec23ebf9235e1ae86d380ba3719f Mon Sep 17 00:00:00 2001 |
| From: Amol Grover <frextrite@gmail.com> |
| Date: Sun, 23 Feb 2020 22:25:39 +0530 |
| Subject: [PATCH] iommu/vt-d: Fix RCU list debugging warnings |
| |
| commit 02d715b4a8182f4887d82df82a7b83aced647760 upstream. |
| |
| dmar_drhd_units is traversed using list_for_each_entry_rcu() |
| outside of an RCU read side critical section but under the |
| protection of dmar_global_lock. Hence add corresponding lockdep |
| expression to silence the following false-positive warnings: |
| |
| [ 1.603975] ============================= |
| [ 1.603976] WARNING: suspicious RCU usage |
| [ 1.603977] 5.5.4-stable #17 Not tainted |
| [ 1.603978] ----------------------------- |
| [ 1.603980] drivers/iommu/intel-iommu.c:4769 RCU-list traversed in non-reader section!! |
| |
| [ 1.603869] ============================= |
| [ 1.603870] WARNING: suspicious RCU usage |
| [ 1.603872] 5.5.4-stable #17 Not tainted |
| [ 1.603874] ----------------------------- |
| [ 1.603875] drivers/iommu/dmar.c:293 RCU-list traversed in non-reader section!! |
| |
| Tested-by: Madhuparna Bhowmik <madhuparnabhowmik10@gmail.com> |
| Signed-off-by: Amol Grover <frextrite@gmail.com> |
| Cc: stable@vger.kernel.org |
| Acked-by: Lu Baolu <baolu.lu@linux.intel.com> |
| Signed-off-by: Joerg Roedel <jroedel@suse.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/include/linux/dmar.h b/include/linux/dmar.h |
| index 28813c6f44b6..7aa581cfe723 100644 |
| --- a/include/linux/dmar.h |
| +++ b/include/linux/dmar.h |
| @@ -69,8 +69,9 @@ struct dmar_pci_notify_info { |
| extern struct rw_semaphore dmar_global_lock; |
| extern struct list_head dmar_drhd_units; |
| |
| -#define for_each_drhd_unit(drhd) \ |
| - list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) |
| +#define for_each_drhd_unit(drhd) \ |
| + list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| + dmar_rcu_check()) |
| |
| #define for_each_active_drhd_unit(drhd) \ |
| list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ |
| @@ -81,7 +82,8 @@ extern struct list_head dmar_drhd_units; |
| if (i=drhd->iommu, drhd->ignored) {} else |
| |
| #define for_each_iommu(i, drhd) \ |
| - list_for_each_entry_rcu(drhd, &dmar_drhd_units, list) \ |
| + list_for_each_entry_rcu(drhd, &dmar_drhd_units, list, \ |
| + dmar_rcu_check()) \ |
| if (i=drhd->iommu, 0) {} else |
| |
| static inline bool dmar_rcu_check(void) |
| -- |
| 2.7.4 |
| |