linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
@ 2015-07-02  1:45 Minfei Huang
  2015-07-07 21:18 ` Vivek Goyal
  0 siblings, 1 reply; 8+ messages in thread
From: Minfei Huang @ 2015-07-02  1:45 UTC (permalink / raw)
  To: ebiederm, vgoyal, schwidefsky, heiko.carstens, linux390, holzheu
  Cc: linux-s390, kexec, linux-kernel, Minfei Huang

For some arch, kexec shall map the reserved pages, then use them, when
we try to start the kdump service.

Now kexec will never unmap the reserved pages, once it fails to continue
starting the kdump service.

Make a pair of reserved pages in kdump starting path, whatever kexec
fails or not.

Signed-off-by: Minfei Huang <mnfhuang@gmail.com>
---
v2:
- replace the "failure" label with "fail_unmap_pages"
v1:
- reconstruct the patch code
---
 kernel/kexec.c | 26 ++++++++++++++------------
 1 file changed, 14 insertions(+), 12 deletions(-)

diff --git a/kernel/kexec.c b/kernel/kexec.c
index 4589899..9cb09d9 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1291,35 +1291,37 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 			 */
 
 			kimage_free(xchg(&kexec_crash_image, NULL));
-			result = kimage_alloc_init(&image, entry, nr_segments,
-						   segments, flags);
-			crash_map_reserved_pages();
-		} else {
-			/* Loading another kernel to reboot into. */
-
-			result = kimage_alloc_init(&image, entry, nr_segments,
-						   segments, flags);
 		}
+
+		result = kimage_alloc_init(&image, entry, nr_segments,
+				segments, flags);
 		if (result)
 			goto out;
 
+		if (flags & KEXEC_ON_CRASH)
+			crash_map_reserved_pages();
+
 		if (flags & KEXEC_PRESERVE_CONTEXT)
 			image->preserve_context = 1;
 		result = machine_kexec_prepare(image);
 		if (result)
-			goto out;
+			goto fail_unmap_pages;
 
 		for (i = 0; i < nr_segments; i++) {
 			result = kimage_load_segment(image, &image->segment[i]);
 			if (result)
-				goto out;
+				goto fail_unmap_pages;
 		}
 		kimage_terminate(image);
+
+fail_unmap_pages:
 		if (flags & KEXEC_ON_CRASH)
 			crash_unmap_reserved_pages();
 	}
-	/* Install the new kernel, and  Uninstall the old */
-	image = xchg(dest_image, image);
+
+	if (result == 0)
+		/* Install the new kernel, and  Uninstall the old */
+		image = xchg(dest_image, image);
 
 out:
 	mutex_unlock(&kexec_mutex);
-- 
2.2.2


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-02  1:45 [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start Minfei Huang
@ 2015-07-07 21:18 ` Vivek Goyal
  2015-07-08 12:06   ` Minfei Huang
  2015-07-09 15:54   ` Michael Holzheu
  0 siblings, 2 replies; 8+ messages in thread
From: Vivek Goyal @ 2015-07-07 21:18 UTC (permalink / raw)
  To: Minfei Huang
  Cc: ebiederm, schwidefsky, heiko.carstens, linux390, holzheu,
	linux-s390, kexec, linux-kernel

On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> For some arch, kexec shall map the reserved pages, then use them, when
> we try to start the kdump service.
> 
> Now kexec will never unmap the reserved pages, once it fails to continue
> starting the kdump service.
> 
> Make a pair of reserved pages in kdump starting path, whatever kexec
> fails or not.
> 
> Signed-off-by: Minfei Huang <mnfhuang@gmail.com>
> ---
> v2:
> - replace the "failure" label with "fail_unmap_pages"
> v1:
> - reconstruct the patch code
> ---
>  kernel/kexec.c | 26 ++++++++++++++------------
>  1 file changed, 14 insertions(+), 12 deletions(-)
> 

Hi Minfei,

I am thinking of moving kernel loading code in a separate function to
make things little simpler. Right now it is confusing.

Can you please test attached patch. I have only compile tested it. This
is primarily doing what you are doing but in a separate function. It
seems more readable now.

Thanks
Vivek


---
 kernel/kexec.c |   90 +++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 56 insertions(+), 34 deletions(-)

Index: rhvgoyal-linux/kernel/kexec.c
===================================================================
--- rhvgoyal-linux.orig/kernel/kexec.c	2015-07-06 13:59:35.088129148 -0400
+++ rhvgoyal-linux/kernel/kexec.c	2015-07-07 17:14:23.593175644 -0400
@@ -1247,6 +1247,57 @@ int kexec_load_disabled;
 
 static DEFINE_MUTEX(kexec_mutex);
 
+static int __kexec_load(struct kimage **rimage, unsigned long entry,
+			unsigned long nr_segments,
+			struct kexec_segment __user * segments,
+			unsigned long flags)
+{
+	unsigned long i;
+	int result;
+	struct kimage *image;
+
+	if (flags & KEXEC_ON_CRASH) {
+		/*
+		 * Loading another kernel to switch to if this one
+		 * crashes.  Free any current crash dump kernel before
+		 * we corrupt it.
+		 */
+
+		kimage_free(xchg(&kexec_crash_image, NULL));
+	}
+
+	result = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
+	if (result)
+		return result;
+
+	if (flags & KEXEC_ON_CRASH)
+		crash_map_reserved_pages();
+
+	if (flags & KEXEC_PRESERVE_CONTEXT)
+		image->preserve_context = 1;
+
+	result = machine_kexec_prepare(image);
+	if (result)
+		goto out;
+
+	for (i = 0; i < nr_segments; i++) {
+		result = kimage_load_segment(image, &image->segment[i]);
+		if (result)
+			goto out;
+	}
+
+	kimage_terminate(image);
+	*rimage = image;
+out:
+	if (flags & KEXEC_ON_CRASH)
+		crash_unmap_reserved_pages();
+
+	/* Free image if there was an error */
+	if (result)
+		kimage_free(image);
+	return result;
+}
+
 SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 		struct kexec_segment __user *, segments, unsigned long, flags)
 {
@@ -1292,44 +1343,15 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
 	dest_image = &kexec_image;
 	if (flags & KEXEC_ON_CRASH)
 		dest_image = &kexec_crash_image;
-	if (nr_segments > 0) {
-		unsigned long i;
 
-		if (flags & KEXEC_ON_CRASH) {
-			/*
-			 * Loading another kernel to switch to if this one
-			 * crashes.  Free any current crash dump kernel before
-			 * we corrupt it.
-			 */
-
-			kimage_free(xchg(&kexec_crash_image, NULL));
-			result = kimage_alloc_init(&image, entry, nr_segments,
-						   segments, flags);
-			crash_map_reserved_pages();
-		} else {
-			/* Loading another kernel to reboot into. */
-
-			result = kimage_alloc_init(&image, entry, nr_segments,
-						   segments, flags);
-		}
-		if (result)
-			goto out;
-
-		if (flags & KEXEC_PRESERVE_CONTEXT)
-			image->preserve_context = 1;
-		result = machine_kexec_prepare(image);
+	/* Load new kernel */
+	if (nr_segments > 0) {
+		result = __kexec_load(&image, entry, nr_segments, segments,
+				      flags);
 		if (result)
 			goto out;
-
-		for (i = 0; i < nr_segments; i++) {
-			result = kimage_load_segment(image, &image->segment[i]);
-			if (result)
-				goto out;
-		}
-		kimage_terminate(image);
-		if (flags & KEXEC_ON_CRASH)
-			crash_unmap_reserved_pages();
 	}
+
 	/* Install the new kernel, and  Uninstall the old */
 	image = xchg(dest_image, image);
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-07 21:18 ` Vivek Goyal
@ 2015-07-08 12:06   ` Minfei Huang
  2015-07-08 12:09     ` Minfei Huang
  2015-07-09 15:54   ` Michael Holzheu
  1 sibling, 1 reply; 8+ messages in thread
From: Minfei Huang @ 2015-07-08 12:06 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, schwidefsky, heiko.carstens, linux390, holzheu,
	linux-s390, kexec, linux-kernel

On 07/07/15 at 05:18P, Vivek Goyal wrote:
> On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> > For some arch, kexec shall map the reserved pages, then use them, when
> > we try to start the kdump service.
> > 
> > Now kexec will never unmap the reserved pages, once it fails to continue
> > starting the kdump service.
> > 
> > Make a pair of reserved pages in kdump starting path, whatever kexec
> > fails or not.
> > 
> > Signed-off-by: Minfei Huang <mnfhuang@gmail.com>
> > ---
> > v2:
> > - replace the "failure" label with "fail_unmap_pages"
> > v1:
> > - reconstruct the patch code
> > ---
> >  kernel/kexec.c | 26 ++++++++++++++------------
> >  1 file changed, 14 insertions(+), 12 deletions(-)
> > 
> 
> Hi Minfei,
> 
> I am thinking of moving kernel loading code in a separate function to
> make things little simpler. Right now it is confusing.

In my patch, I think maybe the label confuses with the reviewer, which
does not express the intention clearly. 

> 
> Can you please test attached patch. I have only compile tested it. This
> is primarily doing what you are doing but in a separate function. It
> seems more readable now.
> 

The patch passed the simple testcase. Since it does change the code
logic, I think there is no risky.

Thanks
Minfei

> Thanks
> Vivek
> 
> 
> ---
>  kernel/kexec.c |   90 +++++++++++++++++++++++++++++++++++----------------------
>  1 file changed, 56 insertions(+), 34 deletions(-)
> 
> Index: rhvgoyal-linux/kernel/kexec.c
> ===================================================================
> --- rhvgoyal-linux.orig/kernel/kexec.c	2015-07-06 13:59:35.088129148 -0400
> +++ rhvgoyal-linux/kernel/kexec.c	2015-07-07 17:14:23.593175644 -0400
> @@ -1247,6 +1247,57 @@ int kexec_load_disabled;
>  
>  static DEFINE_MUTEX(kexec_mutex);
>  
> +static int __kexec_load(struct kimage **rimage, unsigned long entry,
> +			unsigned long nr_segments,
> +			struct kexec_segment __user * segments,
> +			unsigned long flags)
> +{
> +	unsigned long i;
> +	int result;
> +	struct kimage *image;
> +
> +	if (flags & KEXEC_ON_CRASH) {
> +		/*
> +		 * Loading another kernel to switch to if this one
> +		 * crashes.  Free any current crash dump kernel before
> +		 * we corrupt it.
> +		 */
> +
> +		kimage_free(xchg(&kexec_crash_image, NULL));
> +	}
> +
> +	result = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
> +	if (result)
> +		return result;
> +
> +	if (flags & KEXEC_ON_CRASH)
> +		crash_map_reserved_pages();
> +
> +	if (flags & KEXEC_PRESERVE_CONTEXT)
> +		image->preserve_context = 1;
> +
> +	result = machine_kexec_prepare(image);
> +	if (result)
> +		goto out;
> +
> +	for (i = 0; i < nr_segments; i++) {
> +		result = kimage_load_segment(image, &image->segment[i]);
> +		if (result)
> +			goto out;
> +	}
> +
> +	kimage_terminate(image);
> +	*rimage = image;
> +out:
> +	if (flags & KEXEC_ON_CRASH)
> +		crash_unmap_reserved_pages();
> +
> +	/* Free image if there was an error */
> +	if (result)
> +		kimage_free(image);
> +	return result;
> +}
> +
>  SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
>  		struct kexec_segment __user *, segments, unsigned long, flags)
>  {
> @@ -1292,44 +1343,15 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
>  	dest_image = &kexec_image;
>  	if (flags & KEXEC_ON_CRASH)
>  		dest_image = &kexec_crash_image;
> -	if (nr_segments > 0) {
> -		unsigned long i;
>  
> -		if (flags & KEXEC_ON_CRASH) {
> -			/*
> -			 * Loading another kernel to switch to if this one
> -			 * crashes.  Free any current crash dump kernel before
> -			 * we corrupt it.
> -			 */
> -
> -			kimage_free(xchg(&kexec_crash_image, NULL));
> -			result = kimage_alloc_init(&image, entry, nr_segments,
> -						   segments, flags);
> -			crash_map_reserved_pages();
> -		} else {
> -			/* Loading another kernel to reboot into. */
> -
> -			result = kimage_alloc_init(&image, entry, nr_segments,
> -						   segments, flags);
> -		}
> -		if (result)
> -			goto out;
> -
> -		if (flags & KEXEC_PRESERVE_CONTEXT)
> -			image->preserve_context = 1;
> -		result = machine_kexec_prepare(image);
> +	/* Load new kernel */
> +	if (nr_segments > 0) {
> +		result = __kexec_load(&image, entry, nr_segments, segments,
> +				      flags);
>  		if (result)
>  			goto out;
> -
> -		for (i = 0; i < nr_segments; i++) {
> -			result = kimage_load_segment(image, &image->segment[i]);
> -			if (result)
> -				goto out;
> -		}
> -		kimage_terminate(image);
> -		if (flags & KEXEC_ON_CRASH)
> -			crash_unmap_reserved_pages();
>  	}
> +
>  	/* Install the new kernel, and  Uninstall the old */
>  	image = xchg(dest_image, image);
>  

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-08 12:06   ` Minfei Huang
@ 2015-07-08 12:09     ` Minfei Huang
  0 siblings, 0 replies; 8+ messages in thread
From: Minfei Huang @ 2015-07-08 12:09 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: ebiederm, schwidefsky, heiko.carstens, linux390, holzheu,
	linux-s390, kexec, linux-kernel

On 07/08/15 at 08:06P, Minfei Huang wrote:
> On 07/07/15 at 05:18P, Vivek Goyal wrote:
> > On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> > > For some arch, kexec shall map the reserved pages, then use them, when
> > > we try to start the kdump service.
> > > 
> > > Now kexec will never unmap the reserved pages, once it fails to continue
> > > starting the kdump service.
> > > 
> > > Make a pair of reserved pages in kdump starting path, whatever kexec
> > > fails or not.
> > > 
> > > Signed-off-by: Minfei Huang <mnfhuang@gmail.com>
> > > ---
> > > v2:
> > > - replace the "failure" label with "fail_unmap_pages"
> > > v1:
> > > - reconstruct the patch code
> > > ---
> > >  kernel/kexec.c | 26 ++++++++++++++------------
> > >  1 file changed, 14 insertions(+), 12 deletions(-)
> > > 
> > 
> > Hi Minfei,
> > 
> > I am thinking of moving kernel loading code in a separate function to
> > make things little simpler. Right now it is confusing.
> 
> In my patch, I think maybe the label confuses with the reviewer, which
> does not express the intention clearly. 
> 
> > 
> > Can you please test attached patch. I have only compile tested it. This
> > is primarily doing what you are doing but in a separate function. It
> > seems more readable now.
> > 
> 
> The patch passed the simple testcase. Since it does change the code
						   ^^^^^
						 does not change
> logic, I think there is no risky.
> 
> Thanks
> Minfei
> 
> > Thanks
> > Vivek
> > 
> > 
> > ---
> >  kernel/kexec.c |   90 +++++++++++++++++++++++++++++++++++----------------------
> >  1 file changed, 56 insertions(+), 34 deletions(-)
> > 
> > Index: rhvgoyal-linux/kernel/kexec.c
> > ===================================================================
> > --- rhvgoyal-linux.orig/kernel/kexec.c	2015-07-06 13:59:35.088129148 -0400
> > +++ rhvgoyal-linux/kernel/kexec.c	2015-07-07 17:14:23.593175644 -0400
> > @@ -1247,6 +1247,57 @@ int kexec_load_disabled;
> >  
> >  static DEFINE_MUTEX(kexec_mutex);
> >  
> > +static int __kexec_load(struct kimage **rimage, unsigned long entry,
> > +			unsigned long nr_segments,
> > +			struct kexec_segment __user * segments,
> > +			unsigned long flags)
> > +{
> > +	unsigned long i;
> > +	int result;
> > +	struct kimage *image;
> > +
> > +	if (flags & KEXEC_ON_CRASH) {
> > +		/*
> > +		 * Loading another kernel to switch to if this one
> > +		 * crashes.  Free any current crash dump kernel before
> > +		 * we corrupt it.
> > +		 */
> > +
> > +		kimage_free(xchg(&kexec_crash_image, NULL));
> > +	}
> > +
> > +	result = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
> > +	if (result)
> > +		return result;
> > +
> > +	if (flags & KEXEC_ON_CRASH)
> > +		crash_map_reserved_pages();
> > +
> > +	if (flags & KEXEC_PRESERVE_CONTEXT)
> > +		image->preserve_context = 1;
> > +
> > +	result = machine_kexec_prepare(image);
> > +	if (result)
> > +		goto out;
> > +
> > +	for (i = 0; i < nr_segments; i++) {
> > +		result = kimage_load_segment(image, &image->segment[i]);
> > +		if (result)
> > +			goto out;
> > +	}
> > +
> > +	kimage_terminate(image);
> > +	*rimage = image;
> > +out:
> > +	if (flags & KEXEC_ON_CRASH)
> > +		crash_unmap_reserved_pages();
> > +
> > +	/* Free image if there was an error */
> > +	if (result)
> > +		kimage_free(image);
> > +	return result;
> > +}
> > +
> >  SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
> >  		struct kexec_segment __user *, segments, unsigned long, flags)
> >  {
> > @@ -1292,44 +1343,15 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
> >  	dest_image = &kexec_image;
> >  	if (flags & KEXEC_ON_CRASH)
> >  		dest_image = &kexec_crash_image;
> > -	if (nr_segments > 0) {
> > -		unsigned long i;
> >  
> > -		if (flags & KEXEC_ON_CRASH) {
> > -			/*
> > -			 * Loading another kernel to switch to if this one
> > -			 * crashes.  Free any current crash dump kernel before
> > -			 * we corrupt it.
> > -			 */
> > -
> > -			kimage_free(xchg(&kexec_crash_image, NULL));
> > -			result = kimage_alloc_init(&image, entry, nr_segments,
> > -						   segments, flags);
> > -			crash_map_reserved_pages();
> > -		} else {
> > -			/* Loading another kernel to reboot into. */
> > -
> > -			result = kimage_alloc_init(&image, entry, nr_segments,
> > -						   segments, flags);
> > -		}
> > -		if (result)
> > -			goto out;
> > -
> > -		if (flags & KEXEC_PRESERVE_CONTEXT)
> > -			image->preserve_context = 1;
> > -		result = machine_kexec_prepare(image);
> > +	/* Load new kernel */
> > +	if (nr_segments > 0) {
> > +		result = __kexec_load(&image, entry, nr_segments, segments,
> > +				      flags);
> >  		if (result)
> >  			goto out;
> > -
> > -		for (i = 0; i < nr_segments; i++) {
> > -			result = kimage_load_segment(image, &image->segment[i]);
> > -			if (result)
> > -				goto out;
> > -		}
> > -		kimage_terminate(image);
> > -		if (flags & KEXEC_ON_CRASH)
> > -			crash_unmap_reserved_pages();
> >  	}
> > +
> >  	/* Install the new kernel, and  Uninstall the old */
> >  	image = xchg(dest_image, image);
> >  

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-07 21:18 ` Vivek Goyal
  2015-07-08 12:06   ` Minfei Huang
@ 2015-07-09 15:54   ` Michael Holzheu
  2015-07-09 23:37     ` Minfei Huang
  2015-07-10  4:05     ` Minfei Huang
  1 sibling, 2 replies; 8+ messages in thread
From: Michael Holzheu @ 2015-07-09 15:54 UTC (permalink / raw)
  To: Vivek Goyal
  Cc: Minfei Huang, ebiederm, schwidefsky, heiko.carstens, linux390,
	linux-s390, kexec, linux-kernel

On Tue, 7 Jul 2015 17:18:40 -0400
Vivek Goyal <vgoyal@redhat.com> wrote:

> On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:

[snip]

> I am thinking of moving kernel loading code in a separate function to
> make things little simpler. Right now it is confusing.
> 
> Can you please test attached patch. I have only compile tested it. This
> is primarily doing what you are doing but in a separate function. It
> seems more readable now.

The patch looks good to me. What about the following patch on top
to make things even more readable?
---
 kernel/kexec.c |   50 +++++++++++++++++---------------------------------
 1 file changed, 17 insertions(+), 33 deletions(-)

--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1236,14 +1236,18 @@ int kexec_load_disabled;
 
 static DEFINE_MUTEX(kexec_mutex);
 
-static int __kexec_load(struct kimage **rimage, unsigned long entry,
-			unsigned long nr_segments,
+static int __kexec_load(unsigned long entry, unsigned long nr_segments,
 			struct kexec_segment __user * segments,
 			unsigned long flags)
 {
+	struct kimage *image, **dest_image;
 	unsigned long i;
 	int result;
-	struct kimage *image;
+
+	dest_image = (flags & KEXEC_ON_CRASH) ? &kexec_crash_image : &kexec_image;
+
+	if (nr_segments == 0)
+		return 0;
 
 	if (flags & KEXEC_ON_CRASH) {
 		/*
@@ -1251,7 +1255,6 @@ static int __kexec_load(struct kimage **
 		 * crashes.  Free any current crash dump kernel before
 		 * we corrupt it.
 		 */
-
 		kimage_free(xchg(&kexec_crash_image, NULL));
 	}
 
@@ -1267,30 +1270,29 @@ static int __kexec_load(struct kimage **
 
 	result = machine_kexec_prepare(image);
 	if (result)
-		goto out;
+		goto fail;
 
 	for (i = 0; i < nr_segments; i++) {
 		result = kimage_load_segment(image, &image->segment[i]);
 		if (result)
-			goto out;
+			goto fail;
 	}
-
 	kimage_terminate(image);
-	*rimage = image;
-out:
+	/* Install the new kernel, and  uninstall the old */
+	kimage_free(xchg(dest_image, image));
 	if (flags & KEXEC_ON_CRASH)
 		crash_unmap_reserved_pages();
-
-	/* Free image if there was an error */
-	if (result)
-		kimage_free(image);
+	return 0;
+fail:
+	if (flags & KEXEC_ON_CRASH)
+		crash_unmap_reserved_pages();
+	kimage_free(image);
 	return result;
 }
 
 SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
 		struct kexec_segment __user *, segments, unsigned long, flags)
 {
-	struct kimage **dest_image, *image;
 	int result;
 
 	/* We only trust the superuser with rebooting the system. */
@@ -1315,9 +1317,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
 	if (nr_segments > KEXEC_SEGMENT_MAX)
 		return -EINVAL;
 
-	image = NULL;
-	result = 0;
-
 	/* Because we write directly to the reserved memory
 	 * region when loading crash kernels we need a mutex here to
 	 * prevent multiple crash  kernels from attempting to load
@@ -1329,24 +1328,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
 	if (!mutex_trylock(&kexec_mutex))
 		return -EBUSY;
 
-	dest_image = &kexec_image;
-	if (flags & KEXEC_ON_CRASH)
-		dest_image = &kexec_crash_image;
-
 	/* Load new kernel */
-	if (nr_segments > 0) {
-		result = __kexec_load(&image, entry, nr_segments, segments,
-				      flags);
-		if (result)
-			goto out;
-	}
-
-	/* Install the new kernel, and  Uninstall the old */
-	image = xchg(dest_image, image);
-
-out:
+	result = __kexec_load(entry, nr_segments, segments, flags);
 	mutex_unlock(&kexec_mutex);
-	kimage_free(image);
 
 	return result;
 }


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-09 15:54   ` Michael Holzheu
@ 2015-07-09 23:37     ` Minfei Huang
  2015-07-10  4:05     ` Minfei Huang
  1 sibling, 0 replies; 8+ messages in thread
From: Minfei Huang @ 2015-07-09 23:37 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: Vivek Goyal, ebiederm, schwidefsky, heiko.carstens, linux390,
	linux-s390, kexec, linux-kernel

Hi, Michael.

Yes, The code is more readable after wrapping the all of function code
in a function. Since this is a small issue, I think it is better to use
one patch to fix it. I am glad to repost a patch to merge you and
Vivek's patches as one patch.

Thanks
Minfei

On 07/09/15 at 05:54P, Michael Holzheu wrote:
> On Tue, 7 Jul 2015 17:18:40 -0400
> Vivek Goyal <vgoyal@redhat.com> wrote:
> 
> > On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> 
> [snip]
> 
> > I am thinking of moving kernel loading code in a separate function to
> > make things little simpler. Right now it is confusing.
> > 
> > Can you please test attached patch. I have only compile tested it. This
> > is primarily doing what you are doing but in a separate function. It
> > seems more readable now.
> 
> The patch looks good to me. What about the following patch on top
> to make things even more readable?
> ---
>  kernel/kexec.c |   50 +++++++++++++++++---------------------------------
>  1 file changed, 17 insertions(+), 33 deletions(-)
> 
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -1236,14 +1236,18 @@ int kexec_load_disabled;
>  
>  static DEFINE_MUTEX(kexec_mutex);
>  
> -static int __kexec_load(struct kimage **rimage, unsigned long entry,
> -			unsigned long nr_segments,
> +static int __kexec_load(unsigned long entry, unsigned long nr_segments,
>  			struct kexec_segment __user * segments,
>  			unsigned long flags)
>  {
> +	struct kimage *image, **dest_image;
>  	unsigned long i;
>  	int result;
> -	struct kimage *image;
> +
> +	dest_image = (flags & KEXEC_ON_CRASH) ? &kexec_crash_image : &kexec_image;
> +
> +	if (nr_segments == 0)
> +		return 0;
>  
>  	if (flags & KEXEC_ON_CRASH) {
>  		/*
> @@ -1251,7 +1255,6 @@ static int __kexec_load(struct kimage **
>  		 * crashes.  Free any current crash dump kernel before
>  		 * we corrupt it.
>  		 */
> -
>  		kimage_free(xchg(&kexec_crash_image, NULL));
>  	}
>  
> @@ -1267,30 +1270,29 @@ static int __kexec_load(struct kimage **
>  
>  	result = machine_kexec_prepare(image);
>  	if (result)
> -		goto out;
> +		goto fail;
>  
>  	for (i = 0; i < nr_segments; i++) {
>  		result = kimage_load_segment(image, &image->segment[i]);
>  		if (result)
> -			goto out;
> +			goto fail;
>  	}
> -
>  	kimage_terminate(image);
> -	*rimage = image;
> -out:
> +	/* Install the new kernel, and  uninstall the old */
> +	kimage_free(xchg(dest_image, image));
>  	if (flags & KEXEC_ON_CRASH)
>  		crash_unmap_reserved_pages();
> -
> -	/* Free image if there was an error */
> -	if (result)
> -		kimage_free(image);
> +	return 0;
> +fail:
> +	if (flags & KEXEC_ON_CRASH)
> +		crash_unmap_reserved_pages();
> +	kimage_free(image);
>  	return result;
>  }
>  
>  SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
>  		struct kexec_segment __user *, segments, unsigned long, flags)
>  {
> -	struct kimage **dest_image, *image;
>  	int result;
>  
>  	/* We only trust the superuser with rebooting the system. */
> @@ -1315,9 +1317,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
>  	if (nr_segments > KEXEC_SEGMENT_MAX)
>  		return -EINVAL;
>  
> -	image = NULL;
> -	result = 0;
> -
>  	/* Because we write directly to the reserved memory
>  	 * region when loading crash kernels we need a mutex here to
>  	 * prevent multiple crash  kernels from attempting to load
> @@ -1329,24 +1328,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
>  	if (!mutex_trylock(&kexec_mutex))
>  		return -EBUSY;
>  
> -	dest_image = &kexec_image;
> -	if (flags & KEXEC_ON_CRASH)
> -		dest_image = &kexec_crash_image;
> -
>  	/* Load new kernel */
> -	if (nr_segments > 0) {
> -		result = __kexec_load(&image, entry, nr_segments, segments,
> -				      flags);
> -		if (result)
> -			goto out;
> -	}
> -
> -	/* Install the new kernel, and  Uninstall the old */
> -	image = xchg(dest_image, image);
> -
> -out:
> +	result = __kexec_load(entry, nr_segments, segments, flags);
>  	mutex_unlock(&kexec_mutex);
> -	kimage_free(image);
>  
>  	return result;
>  }
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-09 15:54   ` Michael Holzheu
  2015-07-09 23:37     ` Minfei Huang
@ 2015-07-10  4:05     ` Minfei Huang
  2015-07-10  8:28       ` Michael Holzheu
  1 sibling, 1 reply; 8+ messages in thread
From: Minfei Huang @ 2015-07-10  4:05 UTC (permalink / raw)
  To: Michael Holzheu
  Cc: Vivek Goyal, ebiederm, schwidefsky, heiko.carstens, linux390,
	linux-s390, kexec, linux-kernel

On 07/09/15 at 05:54P, Michael Holzheu wrote:
> On Tue, 7 Jul 2015 17:18:40 -0400
> Vivek Goyal <vgoyal@redhat.com> wrote:
> 
> > On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> 
> [snip]
> 
> > I am thinking of moving kernel loading code in a separate function to
> > make things little simpler. Right now it is confusing.
> > 
> > Can you please test attached patch. I have only compile tested it. This
> > is primarily doing what you are doing but in a separate function. It
> > seems more readable now.
> 
> The patch looks good to me. What about the following patch on top
> to make things even more readable?
> ---
>  kernel/kexec.c |   50 +++++++++++++++++---------------------------------
>  1 file changed, 17 insertions(+), 33 deletions(-)
> 
> --- a/kernel/kexec.c
> +++ b/kernel/kexec.c
> @@ -1236,14 +1236,18 @@ int kexec_load_disabled;
>  
>  static DEFINE_MUTEX(kexec_mutex);
>  
> -static int __kexec_load(struct kimage **rimage, unsigned long entry,
> -			unsigned long nr_segments,
> +static int __kexec_load(unsigned long entry, unsigned long nr_segments,
>  			struct kexec_segment __user * segments,
>  			unsigned long flags)
>  {
> +	struct kimage *image, **dest_image;
>  	unsigned long i;
>  	int result;
> -	struct kimage *image;
> +
> +	dest_image = (flags & KEXEC_ON_CRASH) ? &kexec_crash_image : &kexec_image;
> +
> +	if (nr_segments == 0)
> +		return 0;

It is fine, if nr_segments is 0. So we should deal with this case like
original kexec code.

>  
>  	if (flags & KEXEC_ON_CRASH) {
>  		/*
> @@ -1251,7 +1255,6 @@ static int __kexec_load(struct kimage **
>  		 * crashes.  Free any current crash dump kernel before
>  		 * we corrupt it.
>  		 */
> -
>  		kimage_free(xchg(&kexec_crash_image, NULL));
>  	}
>  
> @@ -1267,30 +1270,29 @@ static int __kexec_load(struct kimage **
>  
>  	result = machine_kexec_prepare(image);
>  	if (result)
> -		goto out;
> +		goto fail;
>  
>  	for (i = 0; i < nr_segments; i++) {
>  		result = kimage_load_segment(image, &image->segment[i]);
>  		if (result)
> -			goto out;
> +			goto fail;
>  	}
> -
>  	kimage_terminate(image);
> -	*rimage = image;
> -out:
> +	/* Install the new kernel, and  uninstall the old */
> +	kimage_free(xchg(dest_image, image));
>  	if (flags & KEXEC_ON_CRASH)
>  		crash_unmap_reserved_pages();
> -
> -	/* Free image if there was an error */
> -	if (result)
> -		kimage_free(image);
> +	return 0;
> +fail:
> +	if (flags & KEXEC_ON_CRASH)
> +		crash_unmap_reserved_pages();
> +	kimage_free(image);

Kernel release image again, and will crash in here, since we do not
assign the image to NULL when we release the image above.

Thanks
Minfei

>  	return result;
>  }
>  
>  SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
>  		struct kexec_segment __user *, segments, unsigned long, flags)
>  {
> -	struct kimage **dest_image, *image;
>  	int result;
>  
>  	/* We only trust the superuser with rebooting the system. */
> @@ -1315,9 +1317,6 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
>  	if (nr_segments > KEXEC_SEGMENT_MAX)
>  		return -EINVAL;
>  
> -	image = NULL;
> -	result = 0;
> -
>  	/* Because we write directly to the reserved memory
>  	 * region when loading crash kernels we need a mutex here to
>  	 * prevent multiple crash  kernels from attempting to load
> @@ -1329,24 +1328,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned lon
>  	if (!mutex_trylock(&kexec_mutex))
>  		return -EBUSY;
>  
> -	dest_image = &kexec_image;
> -	if (flags & KEXEC_ON_CRASH)
> -		dest_image = &kexec_crash_image;
> -
>  	/* Load new kernel */
> -	if (nr_segments > 0) {
> -		result = __kexec_load(&image, entry, nr_segments, segments,
> -				      flags);
> -		if (result)
> -			goto out;
> -	}
> -
> -	/* Install the new kernel, and  Uninstall the old */
> -	image = xchg(dest_image, image);
> -
> -out:
> +	result = __kexec_load(entry, nr_segments, segments, flags);
>  	mutex_unlock(&kexec_mutex);
> -	kimage_free(image);
>  
>  	return result;
>  }
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start
  2015-07-10  4:05     ` Minfei Huang
@ 2015-07-10  8:28       ` Michael Holzheu
  0 siblings, 0 replies; 8+ messages in thread
From: Michael Holzheu @ 2015-07-10  8:28 UTC (permalink / raw)
  To: Minfei Huang
  Cc: Vivek Goyal, ebiederm, schwidefsky, heiko.carstens, linux390,
	linux-s390, kexec, linux-kernel

On Fri, 10 Jul 2015 12:05:27 +0800
Minfei Huang <mnfhuang@gmail.com> wrote:

> On 07/09/15 at 05:54P, Michael Holzheu wrote:
> > On Tue, 7 Jul 2015 17:18:40 -0400
> > Vivek Goyal <vgoyal@redhat.com> wrote:
> > 
> > > On Thu, Jul 02, 2015 at 09:45:52AM +0800, Minfei Huang wrote:
> > 
> > [snip]
> > 
> > > I am thinking of moving kernel loading code in a separate function to
> > > make things little simpler. Right now it is confusing.
> > > 
> > > Can you please test attached patch. I have only compile tested it. This
> > > is primarily doing what you are doing but in a separate function. It
> > > seems more readable now.
> > 
> > The patch looks good to me. What about the following patch on top
> > to make things even more readable?
> > ---
> >  kernel/kexec.c |   50 +++++++++++++++++---------------------------------
> >  1 file changed, 17 insertions(+), 33 deletions(-)
> > 
> > --- a/kernel/kexec.c
> > +++ b/kernel/kexec.c
> > @@ -1236,14 +1236,18 @@ int kexec_load_disabled;
> >  
> >  static DEFINE_MUTEX(kexec_mutex);
> >  
> > -static int __kexec_load(struct kimage **rimage, unsigned long entry,
> > -			unsigned long nr_segments,
> > +static int __kexec_load(unsigned long entry, unsigned long nr_segments,
> >  			struct kexec_segment __user * segments,
> >  			unsigned long flags)
> >  {
> > +	struct kimage *image, **dest_image;
> >  	unsigned long i;
> >  	int result;
> > -	struct kimage *image;
> > +
> > +	dest_image = (flags & KEXEC_ON_CRASH) ? &kexec_crash_image : &kexec_image;
> > +
> > +	if (nr_segments == 0)
> > +		return 0;
> 
> It is fine, if nr_segments is 0. So we should deal with this case like
> original kexec code.
> 
> >  
> >  	if (flags & KEXEC_ON_CRASH) {
> >  		/*
> > @@ -1251,7 +1255,6 @@ static int __kexec_load(struct kimage **
> >  		 * crashes.  Free any current crash dump kernel before
> >  		 * we corrupt it.
> >  		 */
> > -
> >  		kimage_free(xchg(&kexec_crash_image, NULL));
> >  	}
> >  
> > @@ -1267,30 +1270,29 @@ static int __kexec_load(struct kimage **
> >  
> >  	result = machine_kexec_prepare(image);
> >  	if (result)
> > -		goto out;
> > +		goto fail;
> >  
> >  	for (i = 0; i < nr_segments; i++) {
> >  		result = kimage_load_segment(image, &image->segment[i]);
> >  		if (result)
> > -			goto out;
> > +			goto fail;
> >  	}
> > -
> >  	kimage_terminate(image);
> > -	*rimage = image;
> > -out:
> > +	/* Install the new kernel, and  uninstall the old */
> > +	kimage_free(xchg(dest_image, image));
> >  	if (flags & KEXEC_ON_CRASH)
> >  		crash_unmap_reserved_pages();
> > -
> > -	/* Free image if there was an error */
> > -	if (result)
> > -		kimage_free(image);
> > +	return 0;
> > +fail:
> > +	if (flags & KEXEC_ON_CRASH)
> > +		crash_unmap_reserved_pages();
> > +	kimage_free(image);
> 
> Kernel release image again

Again? This is only done in the error case.

> , and will crash in here, since we do not
> assign the image to NULL when we release the image above.

Good catch, I should have set image=NULL at the beginning of __kexec_load().

Michael


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2015-07-10  8:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-02  1:45 [PATCH v3] kexec: Make a pair of map and unmap reserved pages when kdump fails to start Minfei Huang
2015-07-07 21:18 ` Vivek Goyal
2015-07-08 12:06   ` Minfei Huang
2015-07-08 12:09     ` Minfei Huang
2015-07-09 15:54   ` Michael Holzheu
2015-07-09 23:37     ` Minfei Huang
2015-07-10  4:05     ` Minfei Huang
2015-07-10  8:28       ` Michael Holzheu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).