svn commit: r298144 - head/sys/x86/iommu

Konstantin Belousov kib at FreeBSD.org
Sun Apr 17 10:56:57 UTC 2016


Author: kib
Date: Sun Apr 17 10:56:56 2016
New Revision: 298144
URL: https://svnweb.freebsd.org/changeset/base/298144

Log:
  Add hw.dmar.batch_coalesce tunable/sysctl, which specifies rate at
  which queued invalidation completion interrupt is requested with
  regard to the queued invalidation requests.  In other words, setting
  the value of the knob to N requests completion interrupt after N items
  are processed.  Existing behaviour is restored by setting
  hw.dmar.batch_coalesce=1.
  
  The knob significantly decreases the DMAR qi interrupt rate at the
  cost of slightly longer DMAR map entries recycling.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  head/sys/x86/iommu/intel_ctx.c
  head/sys/x86/iommu/intel_dmar.h
  head/sys/x86/iommu/intel_utils.c

Modified: head/sys/x86/iommu/intel_ctx.c
==============================================================================
--- head/sys/x86/iommu/intel_ctx.c	Sun Apr 17 05:24:36 2016	(r298143)
+++ head/sys/x86/iommu/intel_ctx.c	Sun Apr 17 10:56:56 2016	(r298144)
@@ -711,6 +711,18 @@ dmar_domain_unload_entry(struct dmar_map
 	}
 }
 
+static struct dmar_qi_genseq *
+dmar_domain_unload_gseq(struct dmar_domain *domain,
+    struct dmar_map_entry *entry, struct dmar_qi_genseq *gseq)
+{
+
+	if (TAILQ_NEXT(entry, dmamap_link) != NULL)
+		return (NULL);
+	if (domain->batch_no++ % dmar_batch_coalesce != 0)
+		return (NULL);
+	return (gseq);
+}
+
 void
 dmar_domain_unload(struct dmar_domain *domain,
     struct dmar_map_entries_tailq *entries, bool cansleep)
@@ -744,8 +756,8 @@ dmar_domain_unload(struct dmar_domain *d
 		entry->gseq.gen = 0;
 		entry->gseq.seq = 0;
 		dmar_qi_invalidate_locked(domain, entry->start, entry->end -
-		    entry->start, TAILQ_NEXT(entry, dmamap_link) == NULL ?
-		    &gseq : NULL);
+		    entry->start, dmar_domain_unload_gseq(domain, entry,
+		    &gseq));
 	}
 	TAILQ_FOREACH_SAFE(entry, entries, dmamap_link, entry1) {
 		entry->gseq = gseq;

Modified: head/sys/x86/iommu/intel_dmar.h
==============================================================================
--- head/sys/x86/iommu/intel_dmar.h	Sun Apr 17 05:24:36 2016	(r298143)
+++ head/sys/x86/iommu/intel_dmar.h	Sun Apr 17 10:56:56 2016	(r298144)
@@ -114,6 +114,7 @@ struct dmar_domain {
 							 unload */
 	struct dmar_map_entry *first_place, *last_place; /* (d) */
 	struct task unload_task;	/* (c) */
+	u_int batch_no;
 };
 
 struct dmar_ctx {
@@ -378,6 +379,7 @@ extern dmar_haddr_t dmar_high;
 extern int haw;
 extern int dmar_tbl_pagecnt;
 extern int dmar_match_verbose;
+extern int dmar_batch_coalesce;
 extern int dmar_check_free;
 
 static inline uint32_t

Modified: head/sys/x86/iommu/intel_utils.c
==============================================================================
--- head/sys/x86/iommu/intel_utils.c	Sun Apr 17 05:24:36 2016	(r298143)
+++ head/sys/x86/iommu/intel_utils.c	Sun Apr 17 10:56:56 2016	(r298144)
@@ -618,6 +618,7 @@ dmar_barrier_exit(struct dmar_unit *dmar
 }
 
 int dmar_match_verbose;
+int dmar_batch_coalesce = 100;
 
 static SYSCTL_NODE(_hw, OID_AUTO, dmar, CTLFLAG_RD, NULL, "");
 SYSCTL_INT(_hw_dmar, OID_AUTO, tbl_pagecnt, CTLFLAG_RD,
@@ -626,6 +627,9 @@ SYSCTL_INT(_hw_dmar, OID_AUTO, tbl_pagec
 SYSCTL_INT(_hw_dmar, OID_AUTO, match_verbose, CTLFLAG_RWTUN,
     &dmar_match_verbose, 0,
     "Verbose matching of the PCI devices to DMAR paths");
+SYSCTL_INT(_hw_dmar, OID_AUTO, batch_coalesce, CTLFLAG_RWTUN,
+    &dmar_batch_coalesce, 0,
+    "Number of qi batches between interrupt");
 #ifdef INVARIANTS
 int dmar_check_free;
 SYSCTL_INT(_hw_dmar, OID_AUTO, check_free, CTLFLAG_RWTUN,


More information about the svn-src-head mailing list