bus: make conn_rwlock a low-level lock
authorDavid Herrmann <dh.herrmann@gmail.com>
Mon, 20 Oct 2014 13:24:15 +0000 (15:24 +0200)
committerDavid Herrmann <dh.herrmann@gmail.com>
Mon, 20 Oct 2014 13:24:15 +0000 (15:24 +0200)
commit9525de196e533b76e5f7d935a60e1b6481269d45
tree9fca17d525f6c940e4908b41f4cf8a322ba04c2e
parent58b0dc305d25f0c18a5f4199c740b8ae550f4294
bus: make conn_rwlock a low-level lock

conn_rwlock protects the connection lists on a bus. Those lists are
usually only accessed deep down in our call-paths, so we can safely order
conn_rwlock _after_ bus->lock and ep->lock. We can even order it after
registry->lock and thus fix a dead-lock in list_names where we used to
have:
    down_read(&bus->conn_rwlock);
    down_read(&reg->rwlock);

.. which dead-locks against kmsg_send():
    kdbus_name_lock(reg); (=> down_read(&reg->rwlock))
    down_read(&bus->conn_rwlock);

The new lock-order isn't particularly beautiful, but there's currently no
way around it. We have to lock destination names on kmsg_send() to make
sure an activator does not get activated concurrently. We could lock
conn_rwlock in kmsg_send() early, but this is kinda ugly regarding
kdbus_conn_wait_reply(). Therefore, for now, lock conn_rwlock late. We can
always change the lock order again later.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
connection.c
names.c