break;
}
+ /* take reference, release lock, disconnect without lock */
kdbus_ep_ref(ep);
mutex_unlock(&bus->lock);
bus = kdbus_bus_ref(b);
break;
}
-
mutex_unlock(&domain->lock);
+
return bus;
}
if (atomic_read(&conn->reply_count) == 0)
return -ENOENT;
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
hash_for_each(conn->bus->conn_hash, i, c, hentry) {
if (c == conn)
cancel_delayed_work_sync(&conn->work);
- /* remove from bus and endpoint */
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
mutex_lock(&conn->ep->lock);
+
+ /* remove from bus and endpoint */
hash_del(&conn->hentry);
list_del(&conn->monitor_entry);
list_del(&conn->ep_entry);
+
mutex_unlock(&conn->ep->lock);
mutex_unlock(&conn->bus->lock);
goto exit_unref_user;
}
- /* link into bus and endpoint */
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&bus->lock);
mutex_lock(&ep->lock);
+
if (bus->disconnected || ep->disconnected) {
mutex_unlock(&ep->lock);
mutex_unlock(&bus->lock);
ret = -ESHUTDOWN;
goto exit_unref_user;
}
+
+ /* link into bus and endpoint */
list_add_tail(&conn->ep_entry, &ep->conn_list);
hash_add(bus->conn_hash, &conn->hentry, conn->id);
+
mutex_unlock(&ep->lock);
mutex_unlock(&bus->lock);
break;
}
+ /* take reference, release lock, disconnect without lock */
kdbus_domain_ref(dom);
mutex_unlock(&domain->lock);
break;
}
+ /* take reference, release lock, disconnect without lock */
kdbus_bus_ref(bus);
mutex_unlock(&domain->lock);
atomic64_set(&d->msg_seq_last, 0);
idr_init(&d->user_idr);
+ /* lock order: parent domain -> domain -> subsys_lock */
if (parent) {
mutex_lock(&parent->lock);
if (parent->disconnected) {
idr_remove(&user->domain->user_idr, user->idr);
hash_del(&user->hentry);
mutex_unlock(&user->domain->lock);
+
kdbus_domain_unref(user->domain);
kfree(user);
}
break;
}
+ /* take reference, release lock, disconnect without lock */
kdbus_conn_ref(conn);
mutex_unlock(&ep->lock);
list_splice_init(&conn->names_queue_list, &names_queue_list);
mutex_unlock(&conn->lock);
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
mutex_lock(®->lock);
if (conn->flags & KDBUS_HELLO_ACTIVATOR) {
u32 hash;
int ret = 0;
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
mutex_lock(®->lock);
struct kdbus_bus *bus = conn->bus;
struct kdbus_name_entry *e;
LIST_HEAD(notify_list);
- int ret = 0;
u32 hash;
+ int ret = 0;
if (!kdbus_name_is_valid(cmd->name, false))
return -EINVAL;
hash = kdbus_str_hash(cmd->name);
+ /* lock order: domain -> bus -> ep -> names -> connection */
mutex_lock(&bus->lock);
mutex_lock(®->lock);
+
e = __kdbus_name_lookup(reg, hash, cmd->name);
if (!e) {
ret = -ESRCH;
policy_db = conn->ep->policy_db;
+ /* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
mutex_lock(®->lock);