* [PATCH userspace] libsepol: cache ebitmap cardinality value
@ 2020-02-12 11:51 Ondrej Mosnacek
2020-02-13 12:21 ` Ondrej Mosnacek
0 siblings, 1 reply; 2+ messages in thread
From: Ondrej Mosnacek @ 2020-02-12 11:51 UTC (permalink / raw)
To: selinux
According to profiling of semodule -BN, ebitmap_cardinality() is called
quite often and contributes a lot to the total runtime. Cache its result
in the ebitmap struct to reduce this overhead. The cached value is
invalidated on most modifying operations, but ebitmap_cardinality() is
usually called once the ebitmap doesn't change any more.
After this patch, the time to do 'semodule -BN' on Fedora Rawhide has
decreased from ~21.4s to ~18.6s (2.8s saved).
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
libsepol/include/sepol/policydb/ebitmap.h | 1 +
libsepol/src/ebitmap.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
index e62df01c..53fafdaa 100644
--- a/libsepol/include/sepol/policydb/ebitmap.h
+++ b/libsepol/include/sepol/policydb/ebitmap.h
@@ -37,6 +37,7 @@ typedef struct ebitmap_node {
typedef struct ebitmap {
ebitmap_node_t *node; /* first node in the bitmap */
uint32_t highbit; /* highest position in the total bitmap */
+ unsigned int cardinality; /* cached value of cardinality */
} ebitmap_t;
#define ebitmap_length(e) ((e)->highbit)
diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
index 6c9951b7..d23444ce 100644
--- a/libsepol/src/ebitmap.c
+++ b/libsepol/src/ebitmap.c
@@ -67,6 +67,7 @@ int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1)
ebitmap_destroy(dst);
dst->node = tmp.node;
dst->highbit = tmp.highbit;
+ dst->cardinality = 0;
return 0;
}
@@ -128,9 +129,14 @@ int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int ma
unsigned int ebitmap_cardinality(ebitmap_t *e1)
{
unsigned int i, count = 0;
+
+ if (e1->cardinality || e1->highbit == 0)
+ return e1->cardinality;
+
for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++)
if (ebitmap_get_bit(e1, i))
count++;
+ e1->cardinality = count;
return count;
}
@@ -194,6 +200,7 @@ int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src)
}
dst->highbit = src->highbit;
+ dst->cardinality = src->cardinality;
return 0;
}
@@ -309,6 +316,7 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value)
free(n);
}
}
+ e->cardinality = 0; /* invalidate cached cardinality */
return 0;
}
prev = n;
@@ -339,6 +347,7 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value)
e->node = new;
}
+ e->cardinality = 0; /* invalidate cached cardinality */
return 0;
}
@@ -358,6 +367,7 @@ void ebitmap_destroy(ebitmap_t * e)
e->highbit = 0;
e->node = 0;
+ e->cardinality = 0;
return;
}
--
2.24.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH userspace] libsepol: cache ebitmap cardinality value
2020-02-12 11:51 [PATCH userspace] libsepol: cache ebitmap cardinality value Ondrej Mosnacek
@ 2020-02-13 12:21 ` Ondrej Mosnacek
0 siblings, 0 replies; 2+ messages in thread
From: Ondrej Mosnacek @ 2020-02-13 12:21 UTC (permalink / raw)
To: SElinux list
On Wed, Feb 12, 2020 at 12:51 PM Ondrej Mosnacek <omosnace@redhat.com> wrote:
> According to profiling of semodule -BN, ebitmap_cardinality() is called
> quite often and contributes a lot to the total runtime. Cache its result
> in the ebitmap struct to reduce this overhead. The cached value is
> invalidated on most modifying operations, but ebitmap_cardinality() is
> usually called once the ebitmap doesn't change any more.
>
> After this patch, the time to do 'semodule -BN' on Fedora Rawhide has
> decreased from ~21.4s to ~18.6s (2.8s saved).
Please don't ack/merge this yet, I need to re-evaluate these numbers...
>
> Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
> ---
> libsepol/include/sepol/policydb/ebitmap.h | 1 +
> libsepol/src/ebitmap.c | 10 ++++++++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/libsepol/include/sepol/policydb/ebitmap.h b/libsepol/include/sepol/policydb/ebitmap.h
> index e62df01c..53fafdaa 100644
> --- a/libsepol/include/sepol/policydb/ebitmap.h
> +++ b/libsepol/include/sepol/policydb/ebitmap.h
> @@ -37,6 +37,7 @@ typedef struct ebitmap_node {
> typedef struct ebitmap {
> ebitmap_node_t *node; /* first node in the bitmap */
> uint32_t highbit; /* highest position in the total bitmap */
> + unsigned int cardinality; /* cached value of cardinality */
> } ebitmap_t;
>
> #define ebitmap_length(e) ((e)->highbit)
> diff --git a/libsepol/src/ebitmap.c b/libsepol/src/ebitmap.c
> index 6c9951b7..d23444ce 100644
> --- a/libsepol/src/ebitmap.c
> +++ b/libsepol/src/ebitmap.c
> @@ -67,6 +67,7 @@ int ebitmap_union(ebitmap_t * dst, const ebitmap_t * e1)
> ebitmap_destroy(dst);
> dst->node = tmp.node;
> dst->highbit = tmp.highbit;
> + dst->cardinality = 0;
>
> return 0;
> }
> @@ -128,9 +129,14 @@ int ebitmap_andnot(ebitmap_t *dst, ebitmap_t *e1, ebitmap_t *e2, unsigned int ma
> unsigned int ebitmap_cardinality(ebitmap_t *e1)
> {
> unsigned int i, count = 0;
> +
> + if (e1->cardinality || e1->highbit == 0)
> + return e1->cardinality;
> +
> for (i=ebitmap_startbit(e1); i < ebitmap_length(e1); i++)
> if (ebitmap_get_bit(e1, i))
> count++;
> + e1->cardinality = count;
> return count;
> }
>
> @@ -194,6 +200,7 @@ int ebitmap_cpy(ebitmap_t * dst, const ebitmap_t * src)
> }
>
> dst->highbit = src->highbit;
> + dst->cardinality = src->cardinality;
> return 0;
> }
>
> @@ -309,6 +316,7 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value)
> free(n);
> }
> }
> + e->cardinality = 0; /* invalidate cached cardinality */
> return 0;
> }
> prev = n;
> @@ -339,6 +347,7 @@ int ebitmap_set_bit(ebitmap_t * e, unsigned int bit, int value)
> e->node = new;
> }
>
> + e->cardinality = 0; /* invalidate cached cardinality */
> return 0;
> }
>
> @@ -358,6 +367,7 @@ void ebitmap_destroy(ebitmap_t * e)
>
> e->highbit = 0;
> e->node = 0;
> + e->cardinality = 0;
> return;
> }
>
> --
> 2.24.1
>
--
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2020-02-13 12:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-12 11:51 [PATCH userspace] libsepol: cache ebitmap cardinality value Ondrej Mosnacek
2020-02-13 12:21 ` Ondrej Mosnacek
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.