From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
To: Marc Zyngier <marc.zyngier@arm.com>,
Thomas Gleixner <tglx@linutronix.de>,
Jason Cooper <jason@lakedaemon.net>
Cc: Rasmus Villemoes <linux@rasmusvillemoes.dk>,
linux-kernel@vger.kernel.org
Subject: [PATCH 4/4] irqchip/gic-v3-its: make free_lpi_range a little cheaper
Date: Tue, 12 Mar 2019 18:33:49 +0100 [thread overview]
Message-ID: <20190312173350.4025-5-linux@rasmusvillemoes.dk> (raw)
In-Reply-To: <20190312173350.4025-1-linux@rasmusvillemoes.dk>
Using list_add + list_sort to insert an element and keeping the list
sorted is a somewhat blunt instrument; one can find the right place to
insert in fewer lines of code than the cmp callback uses. Moreover,
walking the entire list afterwards to merge adjacent ranges is
overkill, since we know that only the just-inserted element may be
merged with its neighbours.
Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
drivers/irqchip/irq-gic-v3-its.c | 61 ++++++++++++++++----------------
1 file changed, 31 insertions(+), 30 deletions(-)
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 2ebc28a53d96..b362d62d3e91 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -26,7 +26,6 @@
#include <linux/interrupt.h>
#include <linux/irqdomain.h>
#include <linux/list.h>
-#include <linux/list_sort.h>
#include <linux/log2.h>
#include <linux/memblock.h>
#include <linux/mm.h>
@@ -1474,31 +1473,6 @@ static struct lpi_range *mk_lpi_range(u32 base, u32 span)
return range;
}
-static int lpi_range_cmp(void *priv, struct list_head *a, struct list_head *b)
-{
- struct lpi_range *ra, *rb;
-
- ra = container_of(a, struct lpi_range, entry);
- rb = container_of(b, struct lpi_range, entry);
-
- return ra->base_id - rb->base_id;
-}
-
-static void merge_lpi_ranges(void)
-{
- struct lpi_range *range, *tmp;
-
- list_for_each_entry_safe(range, tmp, &lpi_range_list, entry) {
- if (!list_is_last(&range->entry, &lpi_range_list) &&
- (tmp->base_id == (range->base_id + range->span))) {
- tmp->base_id = range->base_id;
- tmp->span += range->span;
- list_del(&range->entry);
- kfree(range);
- }
- }
-}
-
static int alloc_lpi_range(u32 nr_lpis, u32 *base)
{
struct lpi_range *range, *tmp;
@@ -1528,9 +1502,21 @@ static int alloc_lpi_range(u32 nr_lpis, u32 *base)
return err;
}
+static void merge_lpi_ranges(struct lpi_range *a, struct lpi_range *b)
+{
+ if (&a->entry == &lpi_range_list || &b->entry == &lpi_range_list)
+ return;
+ if (a->base_id + a->span != b->base_id)
+ return;
+ b->base_id = a->base_id;
+ b->span += a->span;
+ list_del(&a->entry);
+ kfree(a);
+}
+
static int free_lpi_range(u32 base, u32 nr_lpis)
{
- struct lpi_range *new;
+ struct lpi_range *new, *old;
new = mk_lpi_range(base, nr_lpis);
if (!new)
@@ -1538,9 +1524,24 @@ static int free_lpi_range(u32 base, u32 nr_lpis)
mutex_lock(&lpi_range_lock);
- list_add(&new->entry, &lpi_range_list);
- list_sort(NULL, &lpi_range_list, lpi_range_cmp);
- merge_lpi_ranges();
+ list_for_each_entry_reverse(old, &lpi_range_list, entry) {
+ if (old->base_id < base)
+ break;
+ }
+ /*
+ * old is the last element with ->base_id smaller than base,
+ * so new goes right after it. If there are no elements with
+ * ->base_id smaller than base, &old->entry ends up pointing
+ * at the head of the list, and inserting new it the start of
+ * the list is the right thing to do in that case as well.
+ */
+ list_add(&new->entry, &old->entry);
+ /*
+ * Now check if we can merge with the preceding and/or
+ * following ranges.
+ */
+ merge_lpi_ranges(old, new);
+ merge_lpi_ranges(new, list_next_entry(new, entry));
mutex_unlock(&lpi_range_lock);
return 0;
--
2.20.1
next prev parent reply other threads:[~2019-03-12 17:34 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-12 17:33 [PATCH 0/4] irqchip/gic-v3-its: free_lpi_range tweaks Rasmus Villemoes
2019-03-12 17:33 ` [PATCH 1/4] irqchip/gic-v3-its: fix comparison logic in lpi_range_cmp Rasmus Villemoes
2019-03-12 17:33 ` [PATCH 2/4] irqchip/gic-v3-its: move allocation outside mutex Rasmus Villemoes
2019-03-12 17:33 ` [PATCH 3/4] irqchip/gic-v3-its: drop redundant initialization in mk_lpi_range Rasmus Villemoes
2019-03-12 17:33 ` Rasmus Villemoes [this message]
2019-03-12 18:03 ` [PATCH 0/4] irqchip/gic-v3-its: free_lpi_range tweaks Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190312173350.4025-5-linux@rasmusvillemoes.dk \
--to=linux@rasmusvillemoes.dk \
--cc=jason@lakedaemon.net \
--cc=linux-kernel@vger.kernel.org \
--cc=marc.zyngier@arm.com \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®