[systemd-devel] [PATCH 6/7] bus: call __kdbus_domain_user_account() and avoid an extra domain lock
Djalal Harouni
tixxdz at opendz.org
Wed Jul 23 14:19:10 PDT 2014
kdbus_bus_new() worst case will take the domain lock 3 times:
kdbus_bus_new()
=> kdbus_domain_user_find_or_new(): will take it 2 times
+
kdbus_bus_new(): will take it an extra time to account the user and
link the bus into the domain bus_list.
We can reduce the worst case to take the domain lock 2 times by
replacing the kdbus_domain_user_find_or_new() with
kdbus_domain_user_find(): take the lock 1 time
kdbus_domain_user_new()
+
kdbus_bus_new(): take the lock 1 time and use the unlocked version
__kdbus_domain_user_account() to account the user.
Signed-off-by: Djalal Harouni <tixxdz at opendz.org>
---
bus.c | 21 +++++++++++++++++----
domain.h | 12 ++++++++++++
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/bus.c b/bus.c
index c329bef..77adf25 100644
--- a/bus.c
+++ b/bus.c
@@ -219,6 +219,7 @@ int kdbus_bus_new(struct kdbus_domain *domain,
struct kdbus_bus *b;
char prefix[16];
int ret;
+ bool new_user = false;
BUG_ON(*bus);
@@ -269,10 +270,15 @@ 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 (IS_ERR(b->user)) {
- ret = PTR_ERR(b->user);
+ /* account the bus against the user or create a new one */
+ b->user = kdbus_domain_user_find(domain, uid);
+ if (!b->user) {
+ b->user = kdbus_domain_user_new(domain, uid);
+ new_user = true;
+ }
+
+ if (!b->user) {
+ ret = -ENOMEM;
goto exit_ep_unref;
}
@@ -283,6 +289,13 @@ int kdbus_bus_new(struct kdbus_domain *domain,
goto exit_unref_user_unlock;
}
+ /* New user: account the bus against the user */
+ if (new_user) {
+ ret = __kdbus_domain_user_account(domain, 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);
diff --git a/domain.h b/domain.h
index 9c477db..b17e023 100644
--- a/domain.h
+++ b/domain.h
@@ -99,6 +99,18 @@ int kdbus_domain_new(struct kdbus_domain *parent, const char *name,
int kdbus_domain_make_user(struct kdbus_cmd_make *cmd, char **name);
struct kdbus_domain *kdbus_domain_find_by_major(unsigned int major);
+struct kdbus_domain_user *
+kdbus_domain_user_new(struct kdbus_domain *domain, kuid_t uid);
+
+struct kdbus_domain_user *
+kdbus_domain_user_find(struct kdbus_domain *domain, kuid_t uid);
+
+int __kdbus_domain_user_account(struct kdbus_domain *domain,
+ struct kdbus_domain_user *user);
+
+int kdbus_domain_user_account(struct kdbus_domain *domain,
+ struct kdbus_domain_user *user);
+
struct kdbus_domain_user
*kdbus_domain_user_find_or_new(struct kdbus_domain *domain, kuid_t uid);
struct kdbus_domain_user *kdbus_domain_user_ref(struct kdbus_domain_user *u);
--
1.9.3
More information about the systemd-devel
mailing list