From: Baoquan He <bhe@redhat.com>
To: Yuntao Wang <ytcoode@gmail.com>
Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
x86@kernel.org, Andrew Morton <akpm@linux-foundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>, Vivek Goyal <vgoyal@redhat.com>,
Dave Young <dyoung@redhat.com>,
Hari Bathini <hbathini@linux.ibm.com>,
Sourabh Jain <sourabhjain@linux.ibm.com>,
Takashi Iwai <tiwai@suse.de>
Subject: Re: [PATCH v2 3/3] crash_core: fix and simplify the logic of crash_exclude_mem_range()
Date: Wed, 3 Jan 2024 07:42:05 +0800 [thread overview]
Message-ID: <ZZSfTUUckEErqMGq@MiWiFi-R3L-srv> (raw)
In-Reply-To: <20240102144905.110047-4-ytcoode@gmail.com>
On 01/02/24 at 10:49pm, Yuntao Wang wrote:
> The purpose of crash_exclude_mem_range() is to remove all memory ranges
> that overlap with [mstart-mend]. However, the current logic only removes
> the first overlapping memory range.
>
> Commit a2e9a95d2190 ("kexec: Improve & fix crash_exclude_mem_range() to
> handle overlapping ranges") attempted to address this issue, but it did not
> fix all error cases.
>
> Let's fix and simplify the logic of crash_exclude_mem_range().
Thanks, this makes the code logic much clearer and easier to follow.
Acked-by: Baoquan He <bhe@redhat.com>
>
> Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
> ---
> kernel/crash_core.c | 80 ++++++++++++++++-----------------------------
> 1 file changed, 29 insertions(+), 51 deletions(-)
>
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index efe87d501c8c..c51d0a54296b 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -565,9 +565,8 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> int crash_exclude_mem_range(struct crash_mem *mem,
> unsigned long long mstart, unsigned long long mend)
> {
> - int i, j;
> + int i;
> unsigned long long start, end, p_start, p_end;
> - struct range temp_range = {0, 0};
>
> for (i = 0; i < mem->nr_ranges; i++) {
> start = mem->ranges[i].start;
> @@ -575,72 +574,51 @@ int crash_exclude_mem_range(struct crash_mem *mem,
> p_start = mstart;
> p_end = mend;
>
> - if (mstart > end || mend < start)
> + if (p_start > end)
> continue;
>
> + /*
> + * Because the memory ranges in mem->ranges are stored in
> + * ascending order, when we detect `p_end < start`, we can
> + * immediately exit the for loop, as the subsequent memory
> + * ranges will definitely be outside the range we are looking
> + * for.
> + */
> + if (p_end < start)
> + break;
> +
> /* Truncate any area outside of range */
> - if (mstart < start)
> + if (p_start < start)
> p_start = start;
> - if (mend > end)
> + if (p_end > end)
> p_end = end;
>
> /* Found completely overlapping range */
> if (p_start == start && p_end == end) {
> - mem->ranges[i].start = 0;
> - mem->ranges[i].end = 0;
> - if (i < mem->nr_ranges - 1) {
> - /* Shift rest of the ranges to left */
> - for (j = i; j < mem->nr_ranges - 1; j++) {
> - mem->ranges[j].start =
> - mem->ranges[j+1].start;
> - mem->ranges[j].end =
> - mem->ranges[j+1].end;
> - }
> -
> - /*
> - * Continue to check if there are another overlapping ranges
> - * from the current position because of shifting the above
> - * mem ranges.
> - */
> - i--;
> - mem->nr_ranges--;
> - continue;
> - }
> + memmove(&mem->ranges[i], &mem->ranges[i + 1],
> + (mem->nr_ranges - (i + 1)) * sizeof(mem->ranges[i]));
> + i--;
> mem->nr_ranges--;
> - return 0;
> - }
> -
> - if (p_start > start && p_end < end) {
> + } else if (p_start > start && p_end < end) {
> /* Split original range */
> + if (mem->nr_ranges >= mem->max_nr_ranges)
> + return -ENOMEM;
> +
> + memmove(&mem->ranges[i + 2], &mem->ranges[i + 1],
> + (mem->nr_ranges - (i + 1)) * sizeof(mem->ranges[i]));
> +
> mem->ranges[i].end = p_start - 1;
> - temp_range.start = p_end + 1;
> - temp_range.end = end;
> + mem->ranges[i + 1].start = p_end + 1;
> + mem->ranges[i + 1].end = end;
> +
> + i++;
> + mem->nr_ranges++;
> } else if (p_start != start)
> mem->ranges[i].end = p_start - 1;
> else
> mem->ranges[i].start = p_end + 1;
> - break;
> - }
> -
> - /* If a split happened, add the split to array */
> - if (!temp_range.end)
> - return 0;
> -
> - /* Split happened */
> - if (i == mem->max_nr_ranges - 1)
> - return -ENOMEM;
> -
> - /* Location where new range should go */
> - j = i + 1;
> - if (j < mem->nr_ranges) {
> - /* Move over all ranges one slot towards the end */
> - for (i = mem->nr_ranges - 1; i >= j; i--)
> - mem->ranges[i + 1] = mem->ranges[i];
> }
>
> - mem->ranges[j].start = temp_range.start;
> - mem->ranges[j].end = temp_range.end;
> - mem->nr_ranges++;
> return 0;
> }
>
> --
> 2.43.0
>
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
WARNING: multiple messages have this Message-ID (diff)
From: Baoquan He <bhe@redhat.com>
To: Yuntao Wang <ytcoode@gmail.com>
Cc: linux-kernel@vger.kernel.org, kexec@lists.infradead.org,
x86@kernel.org, Andrew Morton <akpm@linux-foundation.org>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
"H. Peter Anvin" <hpa@zytor.com>, Vivek Goyal <vgoyal@redhat.com>,
Dave Young <dyoung@redhat.com>,
Hari Bathini <hbathini@linux.ibm.com>,
Sourabh Jain <sourabhjain@linux.ibm.com>,
Takashi Iwai <tiwai@suse.de>
Subject: Re: [PATCH v2 3/3] crash_core: fix and simplify the logic of crash_exclude_mem_range()
Date: Wed, 3 Jan 2024 07:42:05 +0800 [thread overview]
Message-ID: <ZZSfTUUckEErqMGq@MiWiFi-R3L-srv> (raw)
In-Reply-To: <20240102144905.110047-4-ytcoode@gmail.com>
On 01/02/24 at 10:49pm, Yuntao Wang wrote:
> The purpose of crash_exclude_mem_range() is to remove all memory ranges
> that overlap with [mstart-mend]. However, the current logic only removes
> the first overlapping memory range.
>
> Commit a2e9a95d2190 ("kexec: Improve & fix crash_exclude_mem_range() to
> handle overlapping ranges") attempted to address this issue, but it did not
> fix all error cases.
>
> Let's fix and simplify the logic of crash_exclude_mem_range().
Thanks, this makes the code logic much clearer and easier to follow.
Acked-by: Baoquan He <bhe@redhat.com>
>
> Signed-off-by: Yuntao Wang <ytcoode@gmail.com>
> ---
> kernel/crash_core.c | 80 ++++++++++++++++-----------------------------
> 1 file changed, 29 insertions(+), 51 deletions(-)
>
> diff --git a/kernel/crash_core.c b/kernel/crash_core.c
> index efe87d501c8c..c51d0a54296b 100644
> --- a/kernel/crash_core.c
> +++ b/kernel/crash_core.c
> @@ -565,9 +565,8 @@ int crash_prepare_elf64_headers(struct crash_mem *mem, int need_kernel_map,
> int crash_exclude_mem_range(struct crash_mem *mem,
> unsigned long long mstart, unsigned long long mend)
> {
> - int i, j;
> + int i;
> unsigned long long start, end, p_start, p_end;
> - struct range temp_range = {0, 0};
>
> for (i = 0; i < mem->nr_ranges; i++) {
> start = mem->ranges[i].start;
> @@ -575,72 +574,51 @@ int crash_exclude_mem_range(struct crash_mem *mem,
> p_start = mstart;
> p_end = mend;
>
> - if (mstart > end || mend < start)
> + if (p_start > end)
> continue;
>
> + /*
> + * Because the memory ranges in mem->ranges are stored in
> + * ascending order, when we detect `p_end < start`, we can
> + * immediately exit the for loop, as the subsequent memory
> + * ranges will definitely be outside the range we are looking
> + * for.
> + */
> + if (p_end < start)
> + break;
> +
> /* Truncate any area outside of range */
> - if (mstart < start)
> + if (p_start < start)
> p_start = start;
> - if (mend > end)
> + if (p_end > end)
> p_end = end;
>
> /* Found completely overlapping range */
> if (p_start == start && p_end == end) {
> - mem->ranges[i].start = 0;
> - mem->ranges[i].end = 0;
> - if (i < mem->nr_ranges - 1) {
> - /* Shift rest of the ranges to left */
> - for (j = i; j < mem->nr_ranges - 1; j++) {
> - mem->ranges[j].start =
> - mem->ranges[j+1].start;
> - mem->ranges[j].end =
> - mem->ranges[j+1].end;
> - }
> -
> - /*
> - * Continue to check if there are another overlapping ranges
> - * from the current position because of shifting the above
> - * mem ranges.
> - */
> - i--;
> - mem->nr_ranges--;
> - continue;
> - }
> + memmove(&mem->ranges[i], &mem->ranges[i + 1],
> + (mem->nr_ranges - (i + 1)) * sizeof(mem->ranges[i]));
> + i--;
> mem->nr_ranges--;
> - return 0;
> - }
> -
> - if (p_start > start && p_end < end) {
> + } else if (p_start > start && p_end < end) {
> /* Split original range */
> + if (mem->nr_ranges >= mem->max_nr_ranges)
> + return -ENOMEM;
> +
> + memmove(&mem->ranges[i + 2], &mem->ranges[i + 1],
> + (mem->nr_ranges - (i + 1)) * sizeof(mem->ranges[i]));
> +
> mem->ranges[i].end = p_start - 1;
> - temp_range.start = p_end + 1;
> - temp_range.end = end;
> + mem->ranges[i + 1].start = p_end + 1;
> + mem->ranges[i + 1].end = end;
> +
> + i++;
> + mem->nr_ranges++;
> } else if (p_start != start)
> mem->ranges[i].end = p_start - 1;
> else
> mem->ranges[i].start = p_end + 1;
> - break;
> - }
> -
> - /* If a split happened, add the split to array */
> - if (!temp_range.end)
> - return 0;
> -
> - /* Split happened */
> - if (i == mem->max_nr_ranges - 1)
> - return -ENOMEM;
> -
> - /* Location where new range should go */
> - j = i + 1;
> - if (j < mem->nr_ranges) {
> - /* Move over all ranges one slot towards the end */
> - for (i = mem->nr_ranges - 1; i >= j; i--)
> - mem->ranges[i + 1] = mem->ranges[i];
> }
>
> - mem->ranges[j].start = temp_range.start;
> - mem->ranges[j].end = temp_range.end;
> - mem->nr_ranges++;
> return 0;
> }
>
> --
> 2.43.0
>
next prev parent reply other threads:[~2024-01-02 23:42 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-02 14:49 [PATCH v2 0/3] crash: Some cleanups and fixes Yuntao Wang
2024-01-02 14:49 ` Yuntao Wang
2024-01-02 14:49 ` [PATCH v2 1/3] x86/crash: remove the unused image parameter from prepare_elf_headers() Yuntao Wang
2024-01-02 14:49 ` Yuntao Wang
2024-01-02 14:49 ` [PATCH v2 2/3] x86/crash: use SZ_1M macro instead of hardcoded value Yuntao Wang
2024-01-02 14:49 ` Yuntao Wang
2024-01-02 14:49 ` [PATCH v2 3/3] crash_core: fix and simplify the logic of crash_exclude_mem_range() Yuntao Wang
2024-01-02 14:49 ` Yuntao Wang
2024-01-02 23:42 ` Baoquan He [this message]
2024-01-02 23:42 ` 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=ZZSfTUUckEErqMGq@MiWiFi-R3L-srv \
--to=bhe@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=dyoung@redhat.com \
--cc=hbathini@linux.ibm.com \
--cc=hpa@zytor.com \
--cc=kexec@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=sourabhjain@linux.ibm.com \
--cc=tglx@linutronix.de \
--cc=tiwai@suse.de \
--cc=vgoyal@redhat.com \
--cc=x86@kernel.org \
--cc=ytcoode@gmail.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.