Skip to content

Commit 54b27f9

Browse files
WOnder93pcmoore
authored andcommitted
selinux: complete the inlining of hashtab functions
Move (most of) the definitions of hashtab_search() and hashtab_insert() to the header file. In combination with the previous patch, this avoids calling the callbacks indirectly by function pointers and allows for better optimization, leading to a drastic performance improvement of these operations. With this patch, I measured a speed up in the following areas (measured on x86_64 F32 VM with 4 CPUs): 1. Policy load (`load_policy`) - takes ~150 ms instead of ~230 ms. 2. `chcon -R unconfined_u:object_r:user_tmp_t:s0:c381,c519 /tmp/linux-src` where /tmp/linux-src is an extracted linux-5.7 source tarball - takes ~522 ms instead of ~576 ms. This is because of many symtab_search() calls in string_to_context_struct() when there are many categories specified in the context. 3. `stress-ng --msg 1 --msg-ops 10000000` - takes 12.41 s instead of 13.95 s (consumes 18.6 s of kernel CPU time instead of 21.6 s). This is thanks to security_transition_sid() being ~43% faster after this patch. Signed-off-by: Ondrej Mosnacek <[email protected]> Acked-by: Stephen Smalley <[email protected]> Signed-off-by: Paul Moore <[email protected]>
1 parent 24def7b commit 54b27f9

File tree

2 files changed

+63
-59
lines changed

2 files changed

+63
-59
lines changed

security/selinux/ss/hashtab.c

Lines changed: 5 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <linux/kernel.h>
88
#include <linux/slab.h>
99
#include <linux/errno.h>
10-
#include <linux/sched.h>
1110
#include "hashtab.h"
1211

1312
static struct kmem_cache *hashtab_node_cachep;
@@ -40,71 +39,23 @@ int hashtab_init(struct hashtab *h, u32 nel_hint)
4039
return h->htable ? 0 : -ENOMEM;
4140
}
4241

43-
int hashtab_insert(struct hashtab *h, void *key, void *datum,
44-
struct hashtab_key_params key_params)
42+
int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
43+
void *key, void *datum)
4544
{
46-
u32 hvalue;
47-
struct hashtab_node *prev, *cur, *newnode;
48-
49-
cond_resched();
50-
51-
if (!h->size || h->nel == HASHTAB_MAX_NODES)
52-
return -EINVAL;
53-
54-
hvalue = key_params.hash(key) & (h->size - 1);
55-
prev = NULL;
56-
cur = h->htable[hvalue];
57-
while (cur) {
58-
int cmp = key_params.cmp(key, cur->key);
59-
60-
if (cmp == 0)
61-
return -EEXIST;
62-
if (cmp < 0)
63-
break;
64-
prev = cur;
65-
cur = cur->next;
66-
}
45+
struct hashtab_node *newnode;
6746

6847
newnode = kmem_cache_zalloc(hashtab_node_cachep, GFP_KERNEL);
6948
if (!newnode)
7049
return -ENOMEM;
7150
newnode->key = key;
7251
newnode->datum = datum;
73-
if (prev) {
74-
newnode->next = prev->next;
75-
prev->next = newnode;
76-
} else {
77-
newnode->next = h->htable[hvalue];
78-
h->htable[hvalue] = newnode;
79-
}
52+
newnode->next = *dst;
53+
*dst = newnode;
8054

8155
h->nel++;
8256
return 0;
8357
}
8458

85-
void *hashtab_search(struct hashtab *h, const void *key,
86-
struct hashtab_key_params key_params)
87-
{
88-
u32 hvalue;
89-
struct hashtab_node *cur;
90-
91-
if (!h->size)
92-
return NULL;
93-
94-
hvalue = key_params.hash(key) & (h->size - 1);
95-
cur = h->htable[hvalue];
96-
while (cur) {
97-
int cmp = key_params.cmp(key, cur->key);
98-
99-
if (cmp == 0)
100-
return cur->datum;
101-
if (cmp < 0)
102-
break;
103-
cur = cur->next;
104-
}
105-
return NULL;
106-
}
107-
10859
void hashtab_destroy(struct hashtab *h)
10960
{
11061
u32 i;

security/selinux/ss/hashtab.h

Lines changed: 58 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
#ifndef _SS_HASHTAB_H_
1212
#define _SS_HASHTAB_H_
1313

14-
#define HASHTAB_MAX_NODES 0xffffffff
14+
#include <linux/types.h>
15+
#include <linux/errno.h>
16+
#include <linux/sched.h>
17+
18+
#define HASHTAB_MAX_NODES U32_MAX
1519

1620
struct hashtab_key_params {
1721
u32 (*hash)(const void *key); /* hash function */
@@ -43,6 +47,9 @@ struct hashtab_info {
4347
*/
4448
int hashtab_init(struct hashtab *h, u32 nel_hint);
4549

50+
int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
51+
void *key, void *datum);
52+
4653
/*
4754
* Inserts the specified (key, datum) pair into the specified hash table.
4855
*
@@ -51,17 +58,63 @@ int hashtab_init(struct hashtab *h, u32 nel_hint);
5158
* -EINVAL for general errors or
5259
0 otherwise.
5360
*/
54-
int hashtab_insert(struct hashtab *h, void *k, void *d,
55-
struct hashtab_key_params key_params);
61+
static inline int hashtab_insert(struct hashtab *h, void *key, void *datum,
62+
struct hashtab_key_params key_params)
63+
{
64+
u32 hvalue;
65+
struct hashtab_node *prev, *cur;
66+
67+
cond_resched();
68+
69+
if (!h->size || h->nel == HASHTAB_MAX_NODES)
70+
return -EINVAL;
71+
72+
hvalue = key_params.hash(key) & (h->size - 1);
73+
prev = NULL;
74+
cur = h->htable[hvalue];
75+
while (cur) {
76+
int cmp = key_params.cmp(key, cur->key);
77+
78+
if (cmp == 0)
79+
return -EEXIST;
80+
if (cmp < 0)
81+
break;
82+
prev = cur;
83+
cur = cur->next;
84+
}
85+
86+
return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue],
87+
key, datum);
88+
}
5689

5790
/*
5891
* Searches for the entry with the specified key in the hash table.
5992
*
6093
* Returns NULL if no entry has the specified key or
6194
* the datum of the entry otherwise.
6295
*/
63-
void *hashtab_search(struct hashtab *h, const void *k,
64-
struct hashtab_key_params key_params);
96+
static inline void *hashtab_search(struct hashtab *h, const void *key,
97+
struct hashtab_key_params key_params)
98+
{
99+
u32 hvalue;
100+
struct hashtab_node *cur;
101+
102+
if (!h->size)
103+
return NULL;
104+
105+
hvalue = key_params.hash(key) & (h->size - 1);
106+
cur = h->htable[hvalue];
107+
while (cur) {
108+
int cmp = key_params.cmp(key, cur->key);
109+
110+
if (cmp == 0)
111+
return cur->datum;
112+
if (cmp < 0)
113+
break;
114+
cur = cur->next;
115+
}
116+
return NULL;
117+
}
65118

66119
/*
67120
* Destroys the specified hash table.

0 commit comments

Comments
 (0)