102 lines
3.2 KiB
Diff
102 lines
3.2 KiB
Diff
|
From: David Herrmann <dh.herrmann@gmail.com>
|
||
|
Date: Sat, 18 Apr 2015 12:00:33 +0200
|
||
|
Subject: [PATCH] kdbus: turn kdbus_node_idr into an ida
|
||
|
|
||
|
We no longer use the node-idr for lookups. We're only interested in unique
|
||
|
ID allocation. Hence, turn the kdbus_node_idr into an ida and drop the now
|
||
|
redundant locking. This is also what kernfs does for ino allocations.
|
||
|
|
||
|
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
|
||
|
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
|
||
|
Acked-by: Daniel Mack <daniel@zonque.org>
|
||
|
---
|
||
|
ipc/kdbus/main.c | 1 +
|
||
|
ipc/kdbus/node.c | 23 +++++------------------
|
||
|
ipc/kdbus/node.h | 2 ++
|
||
|
3 files changed, 8 insertions(+), 18 deletions(-)
|
||
|
|
||
|
diff --git a/ipc/kdbus/main.c b/ipc/kdbus/main.c
|
||
|
index 785f529d98b7..f8eac78cace6 100644
|
||
|
--- a/ipc/kdbus/main.c
|
||
|
+++ b/ipc/kdbus/main.c
|
||
|
@@ -116,6 +116,7 @@ static void __exit kdbus_exit(void)
|
||
|
{
|
||
|
kdbus_fs_exit();
|
||
|
kobject_put(kdbus_dir);
|
||
|
+ ida_destroy(&kdbus_node_ida);
|
||
|
}
|
||
|
|
||
|
module_init(kdbus_init);
|
||
|
diff --git a/ipc/kdbus/node.c b/ipc/kdbus/node.c
|
||
|
index 520df00e676a..0d65c65d2bde 100644
|
||
|
--- a/ipc/kdbus/node.c
|
||
|
+++ b/ipc/kdbus/node.c
|
||
|
@@ -178,7 +178,7 @@
|
||
|
* accessed by other callers to properly initialize
|
||
|
* filesystem nodes.
|
||
|
*
|
||
|
- * * node->id: This is an unsigned 32bit integer allocated by an IDR. It is
|
||
|
+ * * node->id: This is an unsigned 32bit integer allocated by an IDA. It is
|
||
|
* always kept as small as possible during allocation and is
|
||
|
* globally unique across all nodes allocated by this module. 0
|
||
|
* is reserved as "not assigned" and is the default.
|
||
|
@@ -233,8 +233,7 @@
|
||
|
#define KDBUS_NODE_NEW (KDBUS_NODE_BIAS - 4)
|
||
|
|
||
|
/* global unique ID mapping for kdbus nodes */
|
||
|
-static DEFINE_IDR(kdbus_node_idr);
|
||
|
-static DECLARE_RWSEM(kdbus_node_idr_lock);
|
||
|
+DEFINE_IDA(kdbus_node_ida);
|
||
|
|
||
|
/**
|
||
|
* kdbus_node_name_hash() - hash a name
|
||
|
@@ -337,15 +336,11 @@ int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
|
||
|
node->hash = kdbus_node_name_hash(name);
|
||
|
}
|
||
|
|
||
|
- down_write(&kdbus_node_idr_lock);
|
||
|
- ret = idr_alloc(&kdbus_node_idr, node, 1, 0, GFP_KERNEL);
|
||
|
- if (ret >= 0)
|
||
|
- node->id = ret;
|
||
|
- up_write(&kdbus_node_idr_lock);
|
||
|
-
|
||
|
+ ret = ida_simple_get(&kdbus_node_ida, 1, 0, GFP_KERNEL);
|
||
|
if (ret < 0)
|
||
|
return ret;
|
||
|
|
||
|
+ node->id = ret;
|
||
|
ret = 0;
|
||
|
|
||
|
if (parent) {
|
||
|
@@ -440,16 +435,8 @@ struct kdbus_node *kdbus_node_unref(struct kdbus_node *node)
|
||
|
|
||
|
if (node->free_cb)
|
||
|
node->free_cb(node);
|
||
|
-
|
||
|
- down_write(&kdbus_node_idr_lock);
|
||
|
if (safe.id > 0)
|
||
|
- idr_remove(&kdbus_node_idr, safe.id);
|
||
|
- /* drop caches after last node to not leak memory on unload */
|
||
|
- if (idr_is_empty(&kdbus_node_idr)) {
|
||
|
- idr_destroy(&kdbus_node_idr);
|
||
|
- idr_init(&kdbus_node_idr);
|
||
|
- }
|
||
|
- up_write(&kdbus_node_idr_lock);
|
||
|
+ ida_simple_remove(&kdbus_node_ida, safe.id);
|
||
|
|
||
|
kfree(safe.name);
|
||
|
|
||
|
diff --git a/ipc/kdbus/node.h b/ipc/kdbus/node.h
|
||
|
index be125ce4fd58..970e02b08e9f 100644
|
||
|
--- a/ipc/kdbus/node.h
|
||
|
+++ b/ipc/kdbus/node.h
|
||
|
@@ -58,6 +58,8 @@ struct kdbus_node {
|
||
|
|
||
|
#define kdbus_node_from_rb(_node) rb_entry((_node), struct kdbus_node, rb)
|
||
|
|
||
|
+extern struct ida kdbus_node_ida;
|
||
|
+
|
||
|
void kdbus_node_init(struct kdbus_node *node, unsigned int type);
|
||
|
|
||
|
int kdbus_node_link(struct kdbus_node *node, struct kdbus_node *parent,
|