From: Wei Yang <richard.weiyang@gmail.com>
To: Baoquan He <bhe@redhat.com>
Cc: prudo@linux.vnet.ibm.com, kexec@lists.infradead.org,
linux-kernel@vger.kernel.org, takahiro.akashi@linaro.org,
ebiederm@xmission.com, Andrew Morton <akpm@linux-foundation.org>,
dyoung@redhat.com, vgoyal@redhat.com
Subject: Re: [PATCH 1/2] resource: add walk_system_ram_res_rev()
Date: Sun, 25 Mar 2018 00:13:43 +0800 [thread overview]
Message-ID: <20180324161343.GA58414@WeideMacBook-Pro.local> (raw)
In-Reply-To: <20180324133330.GD25740@localhost.localdomain>
On Sat, Mar 24, 2018 at 09:33:30PM +0800, Baoquan He wrote:
>>
>> Yes. That sounds perfectly acceptable.
>>
>> It would be interesting to see what this approach looks like, if you
>> have time to toss something together?
>
>OK, will make patches for reviewing. Thanks!
Hi, Baoquan, Andrew
I have come up with an implementation for top-down search the ram resources.
Hope this would meet your need.
From b36d50487f1d4e4d6a5103965a27101b3121e0ea Mon Sep 17 00:00:00 2001
From: Wei Yang <richard.weiyang@gmail.com>
Date: Sat, 24 Mar 2018 23:25:46 +0800
Subject: [PATCH] kernel/resource: add walk_system_ram_res_rev()
As discussed on https://patchwork.kernel.org/patch/10300819/, this patch
comes up with a variant implementation of walk_system_ram_res_rev(), which
uses iteration instead of allocating array to store those resources.
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
---
include/linux/ioport.h | 3 ++
kernel/resource.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..473f1d9cb97e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -277,6 +277,9 @@ extern int
walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *));
+extern int
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
void *arg, int (*func)(struct resource *, void *));
diff --git a/kernel/resource.c b/kernel/resource.c
index 769109f20fb7..ddf6b4c41498 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -73,6 +73,38 @@ static struct resource *next_resource(struct resource *p, bool sibling_only)
return p->sibling;
}
+static struct resource *prev_resource(struct resource *p, bool sibling_only)
+{
+ struct resource *prev;
+ if (NULL == iomem_resource.child)
+ return NULL;
+
+ if (p == NULL) {
+ prev = iomem_resource.child;
+ while (prev->sibling)
+ prev = prev->sibling;
+ } else {
+ if (p->parent->child == p) {
+ return p->parent;
+ }
+
+ for (prev = p->parent->child; prev->sibling != p;
+ prev = prev->sibling) {}
+ }
+
+ /* Caller wants to traverse through siblings only */
+ if (sibling_only)
+ return prev;
+
+ for (;prev->child;) {
+ prev = prev->child;
+
+ while (prev->sibling)
+ prev = prev->sibling;
+ }
+ return prev;
+}
+
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
{
struct resource *p = v;
@@ -401,6 +433,47 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
return 0;
}
+/*
+ * Finds the highest iomem resource existing within [res->start.res->end).
+ * The caller must specify res->start, res->end, res->flags, and optionally
+ * desc. If found, returns 0, res is overwritten, if not found, returns -1.
+ * This function walks the whole tree and not just first level children until
+ * and unless first_level_children_only is true.
+ */
+static int find_prev_iomem_res(struct resource *res, unsigned long desc,
+ bool first_level_children_only)
+{
+ struct resource *p;
+
+ BUG_ON(!res);
+ BUG_ON(res->start >= res->end);
+
+ read_lock(&resource_lock);
+
+ for (p = prev_resource(NULL, first_level_children_only); p;
+ p = prev_resource(p, first_level_children_only)) {
+ if ((p->flags & res->flags) != res->flags)
+ continue;
+ if ((desc != IORES_DESC_NONE) && (desc != p->desc))
+ continue;
+ if (p->end < res->start) {
+ p = NULL;
+ break;
+ }
+ if ((p->end >= res->start) && (p->start < res->end))
+ break;
+ }
+
+ read_unlock(&resource_lock);
+ if (!p)
+ return -1;
+ /* copy data */
+ resource_clip(res, p->start, p->end);
+ res->flags = p->flags;
+ res->desc = p->desc;
+ return 0;
+}
+
static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
bool first_level_children_only,
void *arg,
@@ -422,6 +495,27 @@ static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
return ret;
}
+static int __walk_iomem_res_rev_desc(struct resource *res, unsigned long desc,
+ bool first_level_children_only,
+ void *arg,
+ int (*func)(struct resource *, void *))
+{
+ u64 orig_start = res->start;
+ int ret = -1;
+
+ while ((res->start < res->end) &&
+ !find_prev_iomem_res(res, desc, first_level_children_only)) {
+ ret = (*func)(res, arg);
+ if (ret)
+ break;
+
+ res->end = res->start - 1;
+ res->start = orig_start;
+ }
+
+ return ret;
+}
+
/*
* Walks through iomem resources and calls func() with matching resource
* ranges. This walks through whole tree and not just first level children.
@@ -468,6 +562,25 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
arg, func);
}
+/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *))
+{
+ struct resource res;
+
+ res.start = start;
+ res.end = end;
+ res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+
+ return __walk_iomem_res_rev_desc(&res, IORES_DESC_NONE, true,
+ arg, func);
+}
+
/*
* This function calls the @func callback against all memory ranges, which
* are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
--
2.15.1
--
Wei Yang
Help you, Help me
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
WARNING: multiple messages have this Message-ID (diff)
From: Wei Yang <richard.weiyang@gmail.com>
To: Baoquan He <bhe@redhat.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
prudo@linux.vnet.ibm.com, kexec@lists.infradead.org,
linux-kernel@vger.kernel.org, takahiro.akashi@linaro.org,
ebiederm@xmission.com, dyoung@redhat.com, vgoyal@redhat.com
Subject: Re: [PATCH 1/2] resource: add walk_system_ram_res_rev()
Date: Sun, 25 Mar 2018 00:13:43 +0800 [thread overview]
Message-ID: <20180324161343.GA58414@WeideMacBook-Pro.local> (raw)
In-Reply-To: <20180324133330.GD25740@localhost.localdomain>
On Sat, Mar 24, 2018 at 09:33:30PM +0800, Baoquan He wrote:
>>
>> Yes. That sounds perfectly acceptable.
>>
>> It would be interesting to see what this approach looks like, if you
>> have time to toss something together?
>
>OK, will make patches for reviewing. Thanks!
Hi, Baoquan, Andrew
I have come up with an implementation for top-down search the ram resources.
Hope this would meet your need.
>From b36d50487f1d4e4d6a5103965a27101b3121e0ea Mon Sep 17 00:00:00 2001
From: Wei Yang <richard.weiyang@gmail.com>
Date: Sat, 24 Mar 2018 23:25:46 +0800
Subject: [PATCH] kernel/resource: add walk_system_ram_res_rev()
As discussed on https://patchwork.kernel.org/patch/10300819/, this patch
comes up with a variant implementation of walk_system_ram_res_rev(), which
uses iteration instead of allocating array to store those resources.
Signed-off-by: Wei Yang <richard.weiyang@gmail.com>
---
include/linux/ioport.h | 3 ++
kernel/resource.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+)
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index da0ebaec25f0..473f1d9cb97e 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -277,6 +277,9 @@ extern int
walk_system_ram_res(u64 start, u64 end, void *arg,
int (*func)(struct resource *, void *));
extern int
+walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *));
+extern int
walk_iomem_res_desc(unsigned long desc, unsigned long flags, u64 start, u64 end,
void *arg, int (*func)(struct resource *, void *));
diff --git a/kernel/resource.c b/kernel/resource.c
index 769109f20fb7..ddf6b4c41498 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -73,6 +73,38 @@ static struct resource *next_resource(struct resource *p, bool sibling_only)
return p->sibling;
}
+static struct resource *prev_resource(struct resource *p, bool sibling_only)
+{
+ struct resource *prev;
+ if (NULL == iomem_resource.child)
+ return NULL;
+
+ if (p == NULL) {
+ prev = iomem_resource.child;
+ while (prev->sibling)
+ prev = prev->sibling;
+ } else {
+ if (p->parent->child == p) {
+ return p->parent;
+ }
+
+ for (prev = p->parent->child; prev->sibling != p;
+ prev = prev->sibling) {}
+ }
+
+ /* Caller wants to traverse through siblings only */
+ if (sibling_only)
+ return prev;
+
+ for (;prev->child;) {
+ prev = prev->child;
+
+ while (prev->sibling)
+ prev = prev->sibling;
+ }
+ return prev;
+}
+
static void *r_next(struct seq_file *m, void *v, loff_t *pos)
{
struct resource *p = v;
@@ -401,6 +433,47 @@ static int find_next_iomem_res(struct resource *res, unsigned long desc,
return 0;
}
+/*
+ * Finds the highest iomem resource existing within [res->start.res->end).
+ * The caller must specify res->start, res->end, res->flags, and optionally
+ * desc. If found, returns 0, res is overwritten, if not found, returns -1.
+ * This function walks the whole tree and not just first level children until
+ * and unless first_level_children_only is true.
+ */
+static int find_prev_iomem_res(struct resource *res, unsigned long desc,
+ bool first_level_children_only)
+{
+ struct resource *p;
+
+ BUG_ON(!res);
+ BUG_ON(res->start >= res->end);
+
+ read_lock(&resource_lock);
+
+ for (p = prev_resource(NULL, first_level_children_only); p;
+ p = prev_resource(p, first_level_children_only)) {
+ if ((p->flags & res->flags) != res->flags)
+ continue;
+ if ((desc != IORES_DESC_NONE) && (desc != p->desc))
+ continue;
+ if (p->end < res->start) {
+ p = NULL;
+ break;
+ }
+ if ((p->end >= res->start) && (p->start < res->end))
+ break;
+ }
+
+ read_unlock(&resource_lock);
+ if (!p)
+ return -1;
+ /* copy data */
+ resource_clip(res, p->start, p->end);
+ res->flags = p->flags;
+ res->desc = p->desc;
+ return 0;
+}
+
static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
bool first_level_children_only,
void *arg,
@@ -422,6 +495,27 @@ static int __walk_iomem_res_desc(struct resource *res, unsigned long desc,
return ret;
}
+static int __walk_iomem_res_rev_desc(struct resource *res, unsigned long desc,
+ bool first_level_children_only,
+ void *arg,
+ int (*func)(struct resource *, void *))
+{
+ u64 orig_start = res->start;
+ int ret = -1;
+
+ while ((res->start < res->end) &&
+ !find_prev_iomem_res(res, desc, first_level_children_only)) {
+ ret = (*func)(res, arg);
+ if (ret)
+ break;
+
+ res->end = res->start - 1;
+ res->start = orig_start;
+ }
+
+ return ret;
+}
+
/*
* Walks through iomem resources and calls func() with matching resource
* ranges. This walks through whole tree and not just first level children.
@@ -468,6 +562,25 @@ int walk_system_ram_res(u64 start, u64 end, void *arg,
arg, func);
}
+/*
+ * This function, being a variant of walk_system_ram_res(), calls the @func
+ * callback against all memory ranges of type System RAM which are marked as
+ * IORESOURCE_SYSTEM_RAM and IORESOUCE_BUSY in reversed order, i.e., from
+ * higher to lower.
+ */
+int walk_system_ram_res_rev(u64 start, u64 end, void *arg,
+ int (*func)(struct resource *, void *))
+{
+ struct resource res;
+
+ res.start = start;
+ res.end = end;
+ res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+
+ return __walk_iomem_res_rev_desc(&res, IORES_DESC_NONE, true,
+ arg, func);
+}
+
/*
* This function calls the @func callback against all memory ranges, which
* are ranges marked as IORESOURCE_MEM and IORESOUCE_BUSY.
--
2.15.1
--
Wei Yang
Help you, Help me
next prev parent reply other threads:[~2018-03-24 16:14 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-22 3:37 [PATCH 0/2] Kexec_file: Load kernel at top of system ram Baoquan He
2018-03-22 3:37 ` Baoquan He
2018-03-22 3:37 ` [PATCH 1/2] resource: add walk_system_ram_res_rev() Baoquan He
2018-03-22 3:37 ` Baoquan He
2018-03-22 22:29 ` Andrew Morton
2018-03-22 22:29 ` Andrew Morton
2018-03-23 0:58 ` Baoquan He
2018-03-23 0:58 ` Baoquan He
2018-03-23 2:06 ` Andrew Morton
2018-03-23 2:06 ` Andrew Morton
2018-03-23 3:10 ` Baoquan He
2018-03-23 3:10 ` Baoquan He
2018-03-23 20:06 ` Andrew Morton
2018-03-23 20:06 ` Andrew Morton
2018-03-24 13:33 ` Baoquan He
2018-03-24 13:33 ` Baoquan He
2018-03-24 16:13 ` Wei Yang [this message]
2018-03-24 16:13 ` Wei Yang
2018-03-26 14:30 ` Baoquan He
2018-03-26 14:30 ` Baoquan He
2018-03-26 15:04 ` Wei Yang
2018-03-26 15:04 ` Wei Yang
2018-03-22 3:37 ` [PATCH 2/2] kexec_file: Load kernel at top of system RAM if required Baoquan He
2018-03-22 3:37 ` Baoquan He
2018-03-22 22:38 ` [PATCH 0/2] Kexec_file: Load kernel at top of system ram Andrew Morton
2018-03-22 22:38 ` Andrew Morton
2018-03-23 8:38 ` Baoquan He
2018-03-23 8:38 ` Baoquan He
-- strict thread matches above, loose matches on Subject: below --
2023-11-14 9:16 [PATCH 0/2] kexec_file: Load kernel at top of system RAM if required Baoquan He
2023-11-14 9:16 ` [PATCH 1/2] resource: add walk_system_ram_res_rev() Baoquan He
2023-11-14 9:16 ` Baoquan He
2023-11-14 9:16 ` Baoquan He
2023-11-14 9:16 ` Baoquan He
2023-11-14 23:17 ` Andrew Morton
2023-11-14 23:17 ` Andrew Morton
2023-11-14 23:17 ` Andrew Morton
2023-11-14 23:17 ` Andrew Morton
2023-11-15 0:40 ` Baoquan He
2023-11-15 0:40 ` Baoquan He
2023-11-15 0:40 ` Baoquan He
2023-11-15 0:40 ` Baoquan He
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=20180324161343.GA58414@WeideMacBook-Pro.local \
--to=richard.weiyang@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=bhe@redhat.com \
--cc=dyoung@redhat.com \
--cc=ebiederm@xmission.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=prudo@linux.vnet.ibm.com \
--cc=takahiro.akashi@linaro.org \
--cc=vgoyal@redhat.com \
/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 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.