cancel_delayed_work_sync(&conn->work);
/* lock order: domain -> bus -> ep -> names -> conn */
- down_write(&conn->bus->conn_rwlock);
mutex_lock(&conn->ep->lock);
+ down_write(&conn->bus->conn_rwlock);
/* remove from bus and endpoint */
hash_del(&conn->hentry);
list_del(&conn->monitor_entry);
list_del(&conn->ep_entry);
- mutex_unlock(&conn->ep->lock);
up_write(&conn->bus->conn_rwlock);
+ mutex_unlock(&conn->ep->lock);
/*
* Remove all names associated with this connection; this possibly
}
/* lock order: domain -> bus -> ep -> names -> conn */
- down_write(&bus->conn_rwlock);
mutex_lock(&bus->lock);
mutex_lock(&ep->lock);
+ down_write(&bus->conn_rwlock);
if (bus->disconnected || ep->disconnected) {
ret = -ESHUTDOWN;
list_add_tail(&conn->ep_entry, &ep->conn_list);
hash_add(bus->conn_hash, &conn->hentry, conn->id);
+ up_write(&bus->conn_rwlock);
mutex_unlock(&ep->lock);
mutex_unlock(&bus->lock);
- up_write(&bus->conn_rwlock);
/* notify subscribers about the new active connection */
ret = kdbus_notify_id_change(conn->bus, KDBUS_ITEM_ID_ADD,
return 0;
exit_unref_user_unlock:
+ up_write(&bus->conn_rwlock);
mutex_unlock(&ep->lock);
mutex_unlock(&bus->lock);
- up_write(&bus->conn_rwlock);
exit_domain_user_unref:
kdbus_domain_user_unref(conn->user);
exit_free_meta:
policy_db = &conn->ep->policy_db;
/* lock order: domain -> bus -> ep -> names -> conn */
- down_read(&conn->bus->conn_rwlock);
down_read(®->rwlock);
+ down_read(&conn->bus->conn_rwlock);
down_read(&policy_db->entries_rwlock);
/* size of header + records */
kdbus_pool_slice_free(slice);
exit_unlock:
up_read(&policy_db->entries_rwlock);
- up_read(®->rwlock);
up_read(&conn->bus->conn_rwlock);
+ up_read(®->rwlock);
return ret;
}