mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-23 05:56:14 -04:00
selinux: convert avtab hash table to flex_array
Previously we shrank the avtab max hash buckets to avoid high order memory allocations, but this causes avtab lookups to degenerate to very long linear searches for the Fedora policy. Convert to using a flex_array instead so that we can increase the buckets without such limitations. This change does not alter the max hash buckets; that is left to a separate follow-on change. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: Paul Moore <pmoore@redhat.com>
This commit is contained in:
committed by
Paul Moore
parent
da8026fa0f
commit
ba39db6e05
@@ -46,8 +46,12 @@ avtab_insert_node(struct avtab *h, int hvalue,
|
||||
newnode->next = prev->next;
|
||||
prev->next = newnode;
|
||||
} else {
|
||||
newnode->next = h->htable[hvalue];
|
||||
h->htable[hvalue] = newnode;
|
||||
newnode->next = flex_array_get_ptr(h->htable, hvalue);
|
||||
if (flex_array_put_ptr(h->htable, hvalue, newnode,
|
||||
GFP_KERNEL|__GFP_ZERO)) {
|
||||
kmem_cache_free(avtab_node_cachep, newnode);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
h->nel++;
|
||||
@@ -64,7 +68,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat
|
||||
return -EINVAL;
|
||||
|
||||
hvalue = avtab_hash(key, h->mask);
|
||||
for (prev = NULL, cur = h->htable[hvalue];
|
||||
for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
|
||||
cur;
|
||||
prev = cur, cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
@@ -104,7 +108,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu
|
||||
if (!h || !h->htable)
|
||||
return NULL;
|
||||
hvalue = avtab_hash(key, h->mask);
|
||||
for (prev = NULL, cur = h->htable[hvalue];
|
||||
for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue);
|
||||
cur;
|
||||
prev = cur, cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
@@ -135,7 +139,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key)
|
||||
return NULL;
|
||||
|
||||
hvalue = avtab_hash(key, h->mask);
|
||||
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
|
||||
for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
|
||||
cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class == cur->key.target_class &&
|
||||
@@ -170,7 +175,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key)
|
||||
return NULL;
|
||||
|
||||
hvalue = avtab_hash(key, h->mask);
|
||||
for (cur = h->htable[hvalue]; cur; cur = cur->next) {
|
||||
for (cur = flex_array_get_ptr(h->htable, hvalue); cur;
|
||||
cur = cur->next) {
|
||||
if (key->source_type == cur->key.source_type &&
|
||||
key->target_type == cur->key.target_type &&
|
||||
key->target_class == cur->key.target_class &&
|
||||
@@ -228,15 +234,14 @@ void avtab_destroy(struct avtab *h)
|
||||
return;
|
||||
|
||||
for (i = 0; i < h->nslot; i++) {
|
||||
cur = h->htable[i];
|
||||
cur = flex_array_get_ptr(h->htable, i);
|
||||
while (cur) {
|
||||
temp = cur;
|
||||
cur = cur->next;
|
||||
kmem_cache_free(avtab_node_cachep, temp);
|
||||
}
|
||||
h->htable[i] = NULL;
|
||||
}
|
||||
kfree(h->htable);
|
||||
flex_array_free(h->htable);
|
||||
h->htable = NULL;
|
||||
h->nslot = 0;
|
||||
h->mask = 0;
|
||||
@@ -270,7 +275,8 @@ int avtab_alloc(struct avtab *h, u32 nrules)
|
||||
nslot = MAX_AVTAB_HASH_BUCKETS;
|
||||
mask = nslot - 1;
|
||||
|
||||
h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL);
|
||||
h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot,
|
||||
GFP_KERNEL | __GFP_ZERO);
|
||||
if (!h->htable)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -293,7 +299,7 @@ void avtab_hash_eval(struct avtab *h, char *tag)
|
||||
max_chain_len = 0;
|
||||
chain2_len_sum = 0;
|
||||
for (i = 0; i < h->nslot; i++) {
|
||||
cur = h->htable[i];
|
||||
cur = flex_array_get_ptr(h->htable, i);
|
||||
if (cur) {
|
||||
slots_used++;
|
||||
chain_len = 0;
|
||||
@@ -534,7 +540,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < a->nslot; i++) {
|
||||
for (cur = a->htable[i]; cur; cur = cur->next) {
|
||||
for (cur = flex_array_get_ptr(a->htable, i); cur;
|
||||
cur = cur->next) {
|
||||
rc = avtab_write_item(p, cur, fp);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
Reference in New Issue
Block a user