1
0
Fork 0

greybus: use a simple list of hd connections

First of all, there's a bug in _gb_hd_connection_insert, which
Viresh found.  But pointing out that problem just called attention
to the fact that I have planning to to remove the affected block of
code.

The set of connections associated with a host device is currently
maintained in a red-black tree.  The number of connections we're
likely to have is on the order of a hundred, and at least for now
isn't even going to approach that.  When this code first went in,
Greg asserted that using a list is speedier than a red-black tree
for smallish numbers of elements (maybe up to a few hundred?).

So this patch just removes the host device's red-black tree of
connections, using a simple list instead.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
hifive-unleashed-5.1
Alex Elder 2014-11-17 08:08:44 -06:00 committed by Greg Kroah-Hartman
parent ba99346828
commit 2c43ce4967
4 changed files with 7 additions and 43 deletions

View File

@ -13,51 +13,15 @@
static DEFINE_SPINLOCK(gb_connections_lock);
static void _gb_hd_connection_insert(struct greybus_host_device *hd,
struct gb_connection *connection)
{
struct rb_root *root = &hd->connections;
struct rb_node *node = &connection->hd_node;
struct rb_node **link = &root->rb_node;
struct rb_node *above = NULL;
u16 cport_id = connection->hd_cport_id;
while (*link) {
struct gb_connection *_connection;
above = *link;
_connection = rb_entry(above, struct gb_connection, hd_node);
if (_connection->hd_cport_id > cport_id)
link = &above->rb_left;
else if (_connection->hd_cport_id < cport_id)
link = &above->rb_right;
}
rb_link_node(node, above, link);
rb_insert_color(node, root);
}
static void _gb_hd_connection_remove(struct gb_connection *connection)
{
rb_erase(&connection->hd_node, &connection->hd->connections);
}
struct gb_connection *gb_hd_connection_find(struct greybus_host_device *hd,
u16 cport_id)
{
struct gb_connection *connection = NULL;
struct rb_node *node;
spin_lock_irq(&gb_connections_lock);
node = hd->connections.rb_node;
while (node) {
connection = rb_entry(node, struct gb_connection, hd_node);
if (connection->hd_cport_id > cport_id)
node = node->rb_left;
else if (connection->hd_cport_id < cport_id)
node = node->rb_right;
else
list_for_each_entry(connection, &hd->connections, hd_links)
if (connection->hd_cport_id == cport_id)
goto found;
}
connection = NULL;
found:
spin_unlock_irq(&gb_connections_lock);
@ -204,7 +168,7 @@ struct gb_connection *gb_connection_create(struct gb_interface *interface,
}
spin_lock_irq(&gb_connections_lock);
_gb_hd_connection_insert(hd, connection);
list_add_tail(&connection->hd_links, &hd->connections);
list_add_tail(&connection->interface_links, &interface->connections);
spin_unlock_irq(&gb_connections_lock);
@ -233,7 +197,7 @@ void gb_connection_destroy(struct gb_connection *connection)
}
spin_lock_irq(&gb_connections_lock);
list_del(&connection->interface_links);
_gb_hd_connection_remove(connection);
list_del(&connection->hd_links);
spin_unlock_irq(&gb_connections_lock);
gb_connection_hd_cport_id_free(connection);

View File

@ -28,7 +28,7 @@ struct gb_connection {
u16 hd_cport_id;
u16 interface_cport_id;
struct rb_node hd_node;
struct list_head hd_links;
struct list_head interface_links;
struct gb_protocol *protocol;

View File

@ -186,7 +186,7 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
hd->parent = parent;
hd->driver = driver;
INIT_LIST_HEAD(&hd->modules);
hd->connections = RB_ROOT;
INIT_LIST_HEAD(&hd->connections);
ida_init(&hd->cport_id_map);
spin_lock_init(&hd->cport_id_map_lock);

View File

@ -166,7 +166,7 @@ struct greybus_host_device {
const struct greybus_host_driver *driver;
struct list_head modules;
struct rb_root connections;
struct list_head connections;
struct ida cport_id_map;
spinlock_t cport_id_map_lock;
u8 device_id;