Date: Sun, 17 Apr 2016 10:56:56 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r298144 - head/sys/x86/iommu Message-ID: <201604171056.u3HAuuha082988@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201604171056.u3HAuuha082988>