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
This commit is contained in:
parent
916d57dfc5
commit
e164cafc69
@ -711,6 +711,18 @@ dmar_domain_unload_entry(struct dmar_map_entry *entry, bool free)
|
||||
}
|
||||
}
|
||||
|
||||
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 *domain,
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -618,6 +618,7 @@ dmar_barrier_exit(struct dmar_unit *dmar, u_int barrier_id)
|
||||
}
|
||||
|
||||
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_pagecnt, CTLFLAG_RD,
|
||||
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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user