xen/arm: io: Use binary search for mmio handler lookup

As the number of I/O handlers increase, the overhead associated with
linear lookup also increases. The system might have maximum of 144
(assuming CONFIG_NR_CPUS=128) mmio handlers. In worst case scenario,
it would require 144 iterations for finding a matching handler. Now
it is time for us to change from linear (complexity O(n)) to a binary
search (complexity O(log n) for reducing mmio handler lookup overhead.

Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org>
Acked-by: Julien Grall <julien.grall@arm.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Shanker Donthineni authored and Stefano Stabellini committed 2016-07-26 15:12:27 -07:00
1 parent e3eb84e33c
commit 8047e090f4
1 file changed
+24 -15
+24 -15
View File
@@ -20,6 +20,7 @@
#include <xen/lib.h>
#include <xen/spinlock.h>
#include <xen/sched.h>
#include <xen/sort.h>
#include <asm/current.h>
#include <asm/mmio.h>
@@ -70,27 +71,31 @@ static int handle_write(const struct mmio_handler *handler, struct vcpu *v,
handler->priv);
}
/* This function assumes that mmio regions are not overlapped */
static int cmp_mmio_handler(const void *key, const void *elem)
{
const struct mmio_handler *handler0 = key;
const struct mmio_handler *handler1 = elem;
if ( handler0->addr < handler1->addr )
return -1;
if ( handler0->addr > (handler1->addr + handler1->size) )
return 1;
return 0;
}
static const struct mmio_handler *find_mmio_handler(struct domain *d,
paddr_t gpa)
{
const struct mmio_handler *handler;
unsigned int i;
struct vmmio *vmmio = &d->arch.vmmio;
struct mmio_handler key = {.addr = gpa};
const struct mmio_handler *handler;
read_lock(&vmmio->lock);
for ( i = 0; i < vmmio->num_entries; i++ )
{
handler = &vmmio->handlers[i];
if ( (gpa >= handler->addr) &&
(gpa < (handler->addr + handler->size)) )
break;
}
if ( i == vmmio->num_entries )
handler = NULL;
handler = bsearch(&key, vmmio->handlers, vmmio->num_entries,
sizeof(*handler), cmp_mmio_handler);
read_unlock(&vmmio->lock);
return handler;
@@ -131,6 +136,10 @@ void register_mmio_handler(struct domain *d,
vmmio->num_entries++;
/* Sort mmio handlers in ascending order based on base address */
sort(vmmio->handlers, vmmio->num_entries, sizeof(struct mmio_handler),
cmp_mmio_handler, NULL);
write_unlock(&vmmio->lock);
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.