RE: [RFC Patch 1/2] kexec: show memory info in /proc/iomem

Yu, Fenghua
2009-08-11T20:50:50Z

>
>---
>diff --git a/kernel/kexec.c b/kernel/kexec.c
>index f336e21..01673ad 100644
>--- a/kernel/kexec.c
>+++ b/kernel/kexec.c
>@@ -931,6 +931,8 @@ static int kimage_load_segment(struct kimage *image,
> */
> struct kimage *kexec_image;
> struct kimage *kexec_crash_image;
>+struct resource *kexec_res = NULL;
>+struct resource *kexec_free_res = NULL;
>
> static DEFINE_MUTEX(kexec_mutex);
>
>@@ -939,6 +941,8 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry,
>unsigned long, nr_segments,
> {
> struct kimage **dest_image, *image;
> int result;
>+ unsigned long kexec_start = crashk_res.start;
>+ unsigned long kexec_end = kexec_start;
>
> /* We only trust the superuser with rebooting the system. */
> if (!capable(CAP_SYS_BOOT))
>@@ -994,6 +998,7 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry,
>unsigned long, nr_segments,
> kimage_free(xchg(&kexec_crash_image, NULL));
> result = kimage_crash_alloc(&image, entry,
> nr_segments, segments);
>+ kexec_end += KEXEC_CONTROL_PAGE_SIZE;
> }
> if (result)
> goto out;
>@@ -1008,6 +1013,42 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry,
>unsigned long, nr_segments,
> result = kimage_load_segment(image, &image->segment[i]);
> if (result)
> goto out;
>+ if (flags & KEXEC_ON_CRASH)
>+ kexec_end += image->segment[i].memsz;
>+ }
>+ if (flags & KEXEC_ON_CRASH) {
>+ if (kexec_res) {
>+ release_resource(kexec_res);
>+ release_resource(kexec_free_res);
>+ kfree(kexec_res);
>+ kfree(kexec_free_res);
>+ }
>+ kexec_res = kzalloc(sizeof(*kexec_res), GFP_KERNEL);
>+ if (!kexec_res) {
>+ result = -ENOMEM;
>+ goto out;
>+ }
>+ kexec_free_res = kzalloc(sizeof(*kexec_free_res),
>GFP_KERNEL);
>+ if (!kexec_free_res) {
>+ result = -ENOMEM;
>+ goto out_free;
>+ }
>+ kexec_res->name = "Used";
>+ kexec_res->start = kexec_start;
>+ kexec_res->end = roundup(kexec_end, 1<<20) - 1;
>+ kexec_res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
>+ if (insert_resource(&crashk_res, kexec_res)) {
>+ result = -EBUSY;
>+ goto out_free;
>+ }
>+ kexec_free_res->name = "Unused";
>+ kexec_free_res->start = kexec_res->end + 1;
>+ kexec_free_res->end = crashk_res.end;
>+ kexec_free_res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;
>+ if (insert_resource(&crashk_res, kexec_free_res)) {
>+ result = -EBUSY;
>+ goto out_release;
>+ }
> }
> kimage_terminate(image);
> }
>@@ -1019,6 +1060,13 @@ out:
> kimage_free(image);
>
> return result;
>+
>+out_free:
>+ kfree(kexec_free_res);
>+ kfree(kexec_res);
>+out_release:
>+ release_resource(kexec_res);
>+ goto out;
> }

The order of out_free: and out_release: might be reversed. You need to release_resource first; then kfree. Otherwise the previous failures jump to here and will cause problem.

Thanks.

-Fenghua