[systemd-devel] [PATCH v2 5/7] bus: improve user quota accounting and domain locking

Djalal Harouni tixxdz at opendz.org
Wed Jul 30 13:11:56 PDT 2014


Currently kdbus_bus_new() execution path might take the domain lock
three times on success, four times on failure.

kdbus_bus_new():
  => kdbus_domain_user_find_or_new(): takes it 2 times (and it is racy)
  +
  kdbus_bus_new(): take it an extra time to account the user and link
  the bus into the domain bus_list.

And as discussed in the previous patch kdbus_domain_user_find_or_new()
is racy, so convert to __kdbus_domain_user_account()

This allows also to improve the execution path to take the domain lock
only one time in case of success. On failure the domain lock will be
taken two times.

kdbus_bus_new():
  => take domain lock
  => check if domain is still active/connected
     => __kdbus_domain_user_account()
  ...

Signed-off-by: Djalal Harouni <tixxdz at opendz.org>
---
 bus.c | 13 +++++--------
 1 file changed, 5 insertions(+), 8 deletions(-)

diff --git a/bus.c b/bus.c
index d09e3c6..9e2f41b 100644
--- a/bus.c
+++ b/bus.c
@@ -269,13 +269,6 @@ int kdbus_bus_new(struct kdbus_domain *domain,
 	if (ret < 0)
 		goto exit_free_reg;
 
-	/* account the bus against the user */
-	b->user = kdbus_domain_user_find_or_new(domain, uid);
-	if (!b->user) {
-		ret = -ENOMEM;
-		goto exit_ep_unref;
-	}
-
 	/* link into domain */
 	mutex_lock(&domain->lock);
 	if (domain->disconnected) {
@@ -283,6 +276,11 @@ int kdbus_bus_new(struct kdbus_domain *domain,
 		goto exit_unref_user_unlock;
 	}
 
+	/* account the bus against the user */
+	ret = __kdbus_domain_user_account(domain, uid, &b->user);
+	if (ret < 0)
+		goto exit_unref_user_unlock;
+
 	if (!capable(CAP_IPC_OWNER) &&
 	    atomic_inc_return(&b->user->buses) > KDBUS_USER_MAX_BUSES) {
 		atomic_dec(&b->user->buses);
@@ -300,7 +298,6 @@ int kdbus_bus_new(struct kdbus_domain *domain,
 exit_unref_user_unlock:
 	mutex_unlock(&domain->lock);
 	kdbus_domain_user_unref(b->user);
-exit_ep_unref:
 	kdbus_ep_unref(b->ep);
 exit_free_reg:
 	kdbus_name_registry_free(b->name_registry);
-- 
1.9.3



More information about the systemd-devel mailing list