Commit 7c830b4a authored by James Morris's avatar James Morris Committed by Linus Torvalds

[PATCH] Reduce SELinux kernel memory use on 64-bit systems

The patch below reduces kernel memory used by SELinux policy rules by about
37% on 64-bit systems.  This is because the size of struct avtab_node is 40
bytes on 64-bit, and defaults to a size-64 slab.

Creating a slab cache specifically for these structs saves considerable
amounts of kernel memory on 64-bit systems with large rulesets.  'Strict'
policy has over 300k rules, while 'targeted' policy has around 3k rules.

Here's the slabtop output with 64 and 40 byte sized slabs to show the
memory savings, for strict policy:

303475 303447  99%    0.06K   4975       61     19900K avtab_node 
303456 303447  99%    0.04K   3161       96     12644K avtab_node

Also, there are 57% more objects per slab.
Signed-off-by: default avatarJames Morris <jmorris@redhat.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0f1af7ba
...@@ -28,12 +28,14 @@ ...@@ -28,12 +28,14 @@
(keyp->source_type << 9)) & \ (keyp->source_type << 9)) & \
AVTAB_HASH_MASK) AVTAB_HASH_MASK)
static kmem_cache_t *avtab_node_cachep;
static struct avtab_node* static struct avtab_node*
avtab_insert_node(struct avtab *h, int hvalue, struct avtab_node * prev, struct avtab_node * cur, avtab_insert_node(struct avtab *h, int hvalue, struct avtab_node * prev, struct avtab_node * cur,
struct avtab_key *key, struct avtab_datum *datum) struct avtab_key *key, struct avtab_datum *datum)
{ {
struct avtab_node * newnode; struct avtab_node * newnode;
newnode = (struct avtab_node *) kmalloc(sizeof(struct avtab_node),GFP_KERNEL); newnode = kmem_cache_alloc(avtab_node_cachep, SLAB_KERNEL);
if (newnode == NULL) if (newnode == NULL)
return NULL; return NULL;
memset(newnode, 0, sizeof(struct avtab_node)); memset(newnode, 0, sizeof(struct avtab_node));
...@@ -226,7 +228,7 @@ void avtab_destroy(struct avtab *h) ...@@ -226,7 +228,7 @@ void avtab_destroy(struct avtab *h)
while (cur != NULL) { while (cur != NULL) {
temp = cur; temp = cur;
cur = cur->next; cur = cur->next;
kfree(temp); kmem_cache_free(avtab_node_cachep, temp);
} }
h->htable[i] = NULL; h->htable[i] = NULL;
} }
...@@ -399,3 +401,9 @@ int avtab_read(struct avtab *a, void *fp, u32 config) ...@@ -399,3 +401,9 @@ int avtab_read(struct avtab *a, void *fp, u32 config)
goto out; goto out;
} }
void avtab_cache_init(void)
{
avtab_node_cachep = kmem_cache_create("avtab_node",
sizeof(struct avtab_node),
0, SLAB_PANIC, NULL, NULL);
}
...@@ -78,6 +78,8 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key, int ...@@ -78,6 +78,8 @@ struct avtab_node *avtab_search_node(struct avtab *h, struct avtab_key *key, int
struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified); struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified);
void avtab_cache_init(void);
#define AVTAB_HASH_BITS 15 #define AVTAB_HASH_BITS 15
#define AVTAB_HASH_BUCKETS (1 << AVTAB_HASH_BITS) #define AVTAB_HASH_BUCKETS (1 << AVTAB_HASH_BITS)
#define AVTAB_HASH_MASK (AVTAB_HASH_BUCKETS-1) #define AVTAB_HASH_MASK (AVTAB_HASH_BUCKETS-1)
......
...@@ -1034,6 +1034,7 @@ int security_load_policy(void *data, size_t len) ...@@ -1034,6 +1034,7 @@ int security_load_policy(void *data, size_t len)
LOAD_LOCK; LOAD_LOCK;
if (!ss_initialized) { if (!ss_initialized) {
avtab_cache_init();
if (policydb_read(&policydb, fp)) { if (policydb_read(&policydb, fp)) {
LOAD_UNLOCK; LOAD_UNLOCK;
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment