drm/i915/cmdparser: Use binary search for faster register lookup
A significant proportion of the cmdparsing time for some batches is the cost to find the register in the mmiotable. We ensure that those tables are in ascending order such that we could do a binary search if it was ever merited. It is. Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Reviewed-by: Matthew Auld <matthew.auld@intel.com> Link: http://patchwork.freedesktop.org/patch/msgid/20160818161718.27187-38-chris@chris-wilson.co.uk
This commit is contained in:
parent
ea884f09e5
commit
76ff480ec9
|
@ -921,36 +921,37 @@ find_cmd(struct intel_engine_cs *engine,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_i915_reg_descriptor *
|
static const struct drm_i915_reg_descriptor *
|
||||||
find_reg(const struct drm_i915_reg_descriptor *table,
|
__find_reg(const struct drm_i915_reg_descriptor *table, int count, u32 addr)
|
||||||
int count, u32 addr)
|
|
||||||
{
|
{
|
||||||
int i;
|
int start = 0, end = count;
|
||||||
|
while (start < end) {
|
||||||
for (i = 0; i < count; i++) {
|
int mid = start + (end - start) / 2;
|
||||||
if (i915_mmio_reg_offset(table[i].addr) == addr)
|
int ret = addr - i915_mmio_reg_offset(table[mid].addr);
|
||||||
return &table[i];
|
if (ret < 0)
|
||||||
|
end = mid;
|
||||||
|
else if (ret > 0)
|
||||||
|
start = mid + 1;
|
||||||
|
else
|
||||||
|
return &table[mid];
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct drm_i915_reg_descriptor *
|
static const struct drm_i915_reg_descriptor *
|
||||||
find_reg_in_tables(const struct drm_i915_reg_table *tables,
|
find_reg(const struct intel_engine_cs *engine, bool is_master, u32 addr)
|
||||||
int count, bool is_master, u32 addr)
|
|
||||||
{
|
{
|
||||||
int i;
|
const struct drm_i915_reg_table *table = engine->reg_tables;
|
||||||
const struct drm_i915_reg_table *table;
|
int count = engine->reg_table_count;
|
||||||
const struct drm_i915_reg_descriptor *reg;
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
do {
|
||||||
table = &tables[i];
|
|
||||||
if (!table->master || is_master) {
|
if (!table->master || is_master) {
|
||||||
reg = find_reg(table->regs, table->num_regs,
|
const struct drm_i915_reg_descriptor *reg;
|
||||||
addr);
|
|
||||||
|
reg = __find_reg(table->regs, table->num_regs, addr);
|
||||||
if (reg != NULL)
|
if (reg != NULL)
|
||||||
return reg;
|
return reg;
|
||||||
}
|
}
|
||||||
}
|
} while (table++, --count);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1073,10 +1074,7 @@ static bool check_cmd(const struct intel_engine_cs *engine,
|
||||||
offset += step) {
|
offset += step) {
|
||||||
const u32 reg_addr = cmd[offset] & desc->reg.mask;
|
const u32 reg_addr = cmd[offset] & desc->reg.mask;
|
||||||
const struct drm_i915_reg_descriptor *reg =
|
const struct drm_i915_reg_descriptor *reg =
|
||||||
find_reg_in_tables(engine->reg_tables,
|
find_reg(engine, is_master, reg_addr);
|
||||||
engine->reg_table_count,
|
|
||||||
is_master,
|
|
||||||
reg_addr);
|
|
||||||
|
|
||||||
if (!reg) {
|
if (!reg) {
|
||||||
DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (exec_id=%d)\n",
|
DRM_DEBUG_DRIVER("CMD: Rejected register 0x%08X in command: 0x%08X (exec_id=%d)\n",
|
||||||
|
|
Loading…
Reference in New Issue