Linux Power Management development
 help / color / mirror / Atom feed
* Re: Question regarding completion signal in S3 flow
From: Alan Stern @ 2012-01-26 16:49 UTC (permalink / raw)
  To: Mansoor, Illyas; +Cc: linux-pm@lists.linux-foundation.org
In-Reply-To: <810586B7581CC8469141DADEBC371912057F41@BGSMSX102.gar.corp.intel.com>

On Thu, 26 Jan 2012, Mansoor, Illyas wrote:

> > > I have question related to suspend flow and completion signal:
> > >
> > > Is it possible that a completion signal could be missed in S3 flow
> > > after processes are frozen?
> > 
> > What do you mean by "completion signal"?
> 
> In our case we have an interrupt that signals completion of the interrupt using
> complete()
> For a waiting thread.

It sounds like you're saying you have an interrupt handler that calls 
complete(), and the target thread is stuck in wait_for_completion().

> Our interrupt is configured with IRQ_NO_SUSPEND so we expect interrupts during 
> Suspend also.

IRQ_NO_SUSPEND no longer exists.  Regardless, you can't receive
interrupts while the system is in suspend, because by definition the
CPU isn't running at that time.

> So here is what I'm seeing in the panic logs:
> 
> <4>[ 7960.661939] Call Trace:
> <4>[ 7960.661953]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.661965]  [<c12735b5>] refrigerator+0xa5/0x160
> <4>[ 7960.661977]  [<c125f64d>] get_signal_to_deliver+0x9ad/0xdc0
> <4>[ 7960.661991]  [<c120257b>] do_signal+0x6b/0xa20
> <4>[ 7960.662003]  [<c186ffbd>] ? schedule_hrtimeout_range+0x1cd/0x220
> <4>[ 7960.662018]  [<c122d4a4>] ? pmu_sc_irq+0x364/0x3d0 <==============This is
> where in the interrupt we signal completion using complete()

That is irrelevant.  The '?' means this is merely a random value on the
stack, not the return address of a function call.

> <4>[ 7960.662030]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
> <4>[ 7960.662043]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.662056]  [<c134c162>] ? sys_epoll_wait+0x72/0x300
> <4>[ 7960.662069]  [<c1242c40>] ? default_wake_function+0x0/0x20
> <4>[ 7960.662082]  [<c1202f85>] do_notify_resume+0x55/0x90
> <4>[ 7960.662094]  [<c1871e99>] work_notifysig+0x9/0x1

This stack trace appears to show that some thread attempted to send a 
signal and got frozen while waiting.

> <6>[ 7960.380768] suspend         R running      0    19      2 0x00000000
> <4>[ 7960.380780]  f78e3c94 00000000 c1204760 f78e3c8c c12047eb f78e3c94
> 00000000 f78e3c04
> <4>[ 7960.380800]  00000004 00000000 00030002 c1852942 00000001 00000001
> 00000282 f78e3c5c
> <4>[ 7960.380820]  f78e3c30 c12384a5 00000282 f78e3c3c c18715f3 f7868000
> f78e3c84 c186eebc
> <4>[ 7960.380840] Call Trace:
> <4>[ 7960.380850]  [<c1204760>] ? do_invalid_op+0x0/0xb0
> <4>[ 7960.380862]  [<c12047eb>] ? do_invalid_op+0x8b/0xb0
> <4>[ 7960.380875]  [<c1852942>] ? pmu_pci_set_power_state+0x322/0x6e0 <==== here
> is where wait_for_completion_timeout call BUG() after timeout.
> <4>[ 7960.380888]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.380901]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
> <4>[ 7960.380913]  [<c186eebc>] ? schedule_timeout+0x1dc/0x430
> <4>[ 7960.380926]  [<c1204760>] ? do_invalid_op+0x0/0xb0
> <4>[ 7960.380937]  [<c14b916c>] ? trace_hardirqs_off_thunk+0xc/0x10
> <4>[ 7960.380950]  [<c187244b>] ? error_code+0x6b/0x70
> <4>[ 7960.380961]  [<c186dd96>] ? wait_for_common+0x96/0x120
> <4>[ 7960.380973]  [<c1204760>] ? do_invalid_op+0x0/0xb0
> <4>[ 7960.380985]  [<c1852942>] ? pmu_pci_set_power_state+0x322/0x6e0
> <4>[ 7960.380998]  [<c14b502a>] ? put_dec+0x2a/0xa0
> <4>[ 7960.381011]  [<c14b502a>] ? put_dec+0x2a/0xa0
> <4>[ 7960.381025]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.381038]  [<c14cee6e>] ? pci_platform_power_transition+0x3e/0xa0
> <4>[ 7960.381051]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
> <4>[ 7960.381064]  [<c14cf5df>] ? pci_set_power_state+0x3f/0x2c0
> <4>[ 7960.381077]  [<c14ced7c>] ? pci_update_current_state+0x3c/0x50
> <4>[ 7960.381090]  [<c14d180e>] ? pci_pm_runtime_resume+0x5e/0xa0
> <4>[ 7960.381102]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.381114]  [<c14d17b0>] ? pci_pm_runtime_resume+0x0/0xa0
> <4>[ 7960.381126]  [<c1554d7b>] ? rpm_callback+0x3b/0x70
> <4>[ 7960.381137]  [<c155577c>] ? rpm_resume+0x37c/0x5c0
> <4>[ 7960.381150]  [<c124923b>] ? release_console_sem+0x37b/0x3c0
> <4>[ 7960.381164]  [<c1238593>] ? add_preempt_count+0xb3/0xf0
> <4>[ 7960.381176]  [<c1556609>] ? __pm_runtime_resume+0x49/0xc0
> <4>[ 7960.381189]  [<c14d1b71>] ? pci_pm_prepare+0x21/0x60
> <4>[ 7960.381200]  [<c1553947>] ? dpm_suspend_start+0x137/0x7d0
> <4>[ 7960.381213]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.381225]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
> <4>[ 7960.381237]  [<c126f548>] ? up+0x28/0x40
> <4>[ 7960.381250]  [<c1288f13>] ? suspend_devices_and_enter+0x73/0x1d0
> <4>[ 7960.381262]  [<c1289196>] ? enter_state+0x126/0x1e0
> <4>[ 7960.381273]  [<c1289277>] ? pm_suspend+0x27/0x70
> <4>[ 7960.381285]  [<c128acba>] ? suspend+0x8a/0x160
> <4>[ 7960.381296]  [<c186e445>] ? schedule+0x545/0x9e0
> <4>[ 7960.381310]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
> <4>[ 7960.381322]  [<c1265833>] ? worker_thread+0x123/0x2c0
> <4>[ 7960.381333]  [<c186e445>] ? schedule+0x545/0x9e0
> <4>[ 7960.381346]  [<c128ac30>] ? suspend+0x0/0x160
> <4>[ 7960.381357]  [<c12690d0>] ? autoremove_wake_function+0x0/0x50
> <4>[ 7960.381369]  [<c1265710>] ? worker_thread+0x0/0x2c0
> <4>[ 7960.381381]  [<c1268c34>] ? kthread+0x74/0x80
> <4>[ 7960.381393]  [<c1268bc0>] ? kthread+0x0/0x80
> <4>[ 7960.381405]  [<c120357a>] ? kernel_thread_helper+0x6/0x1

This is very difficult to understand.  You should add some printk 
statements to your code, so that you will know what is going on.

> So my question, is it possible that the complete() called in interrupt context
> can be missed
> During S3?

I don't know what you mean by "missed".  The complete() call will work,
but the target thread might not return from wait_for_completion()  
until after the system returns to S0.

Alan Stern

^ permalink raw reply

* Re: Question regarding completion signal in S3 flow
From: Mansoor, Illyas @ 2012-01-26 15:19 UTC (permalink / raw)
  To: Alan Stern; +Cc: linux-pm@lists.linux-foundation.org
In-Reply-To: <Pine.LNX.4.44L0.1201260956370.1386-100000@iolanthe.rowland.org>


[-- Attachment #1.1: Type: text/plain, Size: 5450 bytes --]

> > I have question related to suspend flow and completion signal:
> >
> > Is it possible that a completion signal could be missed in S3 flow
> > after processes are frozen?
> 
> What do you mean by "completion signal"?

In our case we have an interrupt that signals completion of the interrupt using
complete()
For a waiting thread.

> 
> > The scenario is:
> >
> > Suspend_thread->...->dpm_suspend_start->suspend-
> >Wait_for_completion_t
> > imeout->do
> > es not receive signal and times out
> 
> dpm_suspend_start doesn't run until processes are frozen, and frozen processes
> cannot be waiting for a completion.  Therefore this can't happen.
> 
> > Interrupt->complete->
> >
> > This happens very rare, there are other reason why
> > wait_for_completion_times out like interrupt not received but I just
> > want To make sure if completion signal is not lost during S3.
> 
> Of course it's possible that interrupts will not be delivered while the
computer is
> suspending or suspended.  Those interrupts should be delivered later, when the
> computer wakes up again.
> 
Our interrupt is configured with IRQ_NO_SUSPEND so we expect interrupts during 
Suspend also.

So here is what I'm seeing in the panic logs:

<4>[ 7960.661939] Call Trace:
<4>[ 7960.661953]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.661965]  [<c12735b5>] refrigerator+0xa5/0x160
<4>[ 7960.661977]  [<c125f64d>] get_signal_to_deliver+0x9ad/0xdc0
<4>[ 7960.661991]  [<c120257b>] do_signal+0x6b/0xa20
<4>[ 7960.662003]  [<c186ffbd>] ? schedule_hrtimeout_range+0x1cd/0x220
<4>[ 7960.662018]  [<c122d4a4>] ? pmu_sc_irq+0x364/0x3d0 <==============This is
where in the interrupt we signal completion using complete()
<4>[ 7960.662030]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7960.662043]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.662056]  [<c134c162>] ? sys_epoll_wait+0x72/0x300
<4>[ 7960.662069]  [<c1242c40>] ? default_wake_function+0x0/0x20
<4>[ 7960.662082]  [<c1202f85>] do_notify_resume+0x55/0x90
<4>[ 7960.662094]  [<c1871e99>] work_notifysig+0x9/0x1


<6>[ 7960.380768] suspend         R running      0    19      2 0x00000000
<4>[ 7960.380780]  f78e3c94 00000000 c1204760 f78e3c8c c12047eb f78e3c94
00000000 f78e3c04
<4>[ 7960.380800]  00000004 00000000 00030002 c1852942 00000001 00000001
00000282 f78e3c5c
<4>[ 7960.380820]  f78e3c30 c12384a5 00000282 f78e3c3c c18715f3 f7868000
f78e3c84 c186eebc
<4>[ 7960.380840] Call Trace:
<4>[ 7960.380850]  [<c1204760>] ? do_invalid_op+0x0/0xb0
<4>[ 7960.380862]  [<c12047eb>] ? do_invalid_op+0x8b/0xb0
<4>[ 7960.380875]  [<c1852942>] ? pmu_pci_set_power_state+0x322/0x6e0 <==== here
is where wait_for_completion_timeout call BUG() after timeout.
<4>[ 7960.380888]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.380901]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7960.380913]  [<c186eebc>] ? schedule_timeout+0x1dc/0x430
<4>[ 7960.380926]  [<c1204760>] ? do_invalid_op+0x0/0xb0
<4>[ 7960.380937]  [<c14b916c>] ? trace_hardirqs_off_thunk+0xc/0x10
<4>[ 7960.380950]  [<c187244b>] ? error_code+0x6b/0x70
<4>[ 7960.380961]  [<c186dd96>] ? wait_for_common+0x96/0x120
<4>[ 7960.380973]  [<c1204760>] ? do_invalid_op+0x0/0xb0
<4>[ 7960.380985]  [<c1852942>] ? pmu_pci_set_power_state+0x322/0x6e0
<4>[ 7960.380998]  [<c14b502a>] ? put_dec+0x2a/0xa0
<4>[ 7960.381011]  [<c14b502a>] ? put_dec+0x2a/0xa0
<4>[ 7960.381025]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.381038]  [<c14cee6e>] ? pci_platform_power_transition+0x3e/0xa0
<4>[ 7960.381051]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7960.381064]  [<c14cf5df>] ? pci_set_power_state+0x3f/0x2c0
<4>[ 7960.381077]  [<c14ced7c>] ? pci_update_current_state+0x3c/0x50
<4>[ 7960.381090]  [<c14d180e>] ? pci_pm_runtime_resume+0x5e/0xa0
<4>[ 7960.381102]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.381114]  [<c14d17b0>] ? pci_pm_runtime_resume+0x0/0xa0
<4>[ 7960.381126]  [<c1554d7b>] ? rpm_callback+0x3b/0x70
<4>[ 7960.381137]  [<c155577c>] ? rpm_resume+0x37c/0x5c0
<4>[ 7960.381150]  [<c124923b>] ? release_console_sem+0x37b/0x3c0
<4>[ 7960.381164]  [<c1238593>] ? add_preempt_count+0xb3/0xf0
<4>[ 7960.381176]  [<c1556609>] ? __pm_runtime_resume+0x49/0xc0
<4>[ 7960.381189]  [<c14d1b71>] ? pci_pm_prepare+0x21/0x60
<4>[ 7960.381200]  [<c1553947>] ? dpm_suspend_start+0x137/0x7d0
<4>[ 7960.381213]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.381225]  [<c18715f3>] ? _raw_spin_unlock_irqrestore+0x23/0x50
<4>[ 7960.381237]  [<c126f548>] ? up+0x28/0x40
<4>[ 7960.381250]  [<c1288f13>] ? suspend_devices_and_enter+0x73/0x1d0
<4>[ 7960.381262]  [<c1289196>] ? enter_state+0x126/0x1e0
<4>[ 7960.381273]  [<c1289277>] ? pm_suspend+0x27/0x70
<4>[ 7960.381285]  [<c128acba>] ? suspend+0x8a/0x160
<4>[ 7960.381296]  [<c186e445>] ? schedule+0x545/0x9e0
<4>[ 7960.381310]  [<c12384a5>] ? sub_preempt_count+0x85/0xc0
<4>[ 7960.381322]  [<c1265833>] ? worker_thread+0x123/0x2c0
<4>[ 7960.381333]  [<c186e445>] ? schedule+0x545/0x9e0
<4>[ 7960.381346]  [<c128ac30>] ? suspend+0x0/0x160
<4>[ 7960.381357]  [<c12690d0>] ? autoremove_wake_function+0x0/0x50
<4>[ 7960.381369]  [<c1265710>] ? worker_thread+0x0/0x2c0
<4>[ 7960.381381]  [<c1268c34>] ? kthread+0x74/0x80
<4>[ 7960.381393]  [<c1268bc0>] ? kthread+0x0/0x80
<4>[ 7960.381405]  [<c120357a>] ? kernel_thread_helper+0x6/0x1


So my question, is it possible that the complete() called in interrupt context
can be missed
During S3?

-Illyas

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7212 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: Question regarding completion signal in S3 flow
From: Alan Stern @ 2012-01-26 15:02 UTC (permalink / raw)
  To: Mansoor, Illyas; +Cc: linux-pm@lists.linux-foundation.org
In-Reply-To: <810586B7581CC8469141DADEBC371912057D42@BGSMSX102.gar.corp.intel.com>

On Thu, 26 Jan 2012, Mansoor, Illyas wrote:

> Hi All,
> 
> I have question related to suspend flow and completion signal:
> 
> Is it possible that a completion signal could be missed in S3 flow after
> processes are frozen? 

What do you mean by "completion signal"?

> The scenario is:
> 
> Suspend_thread->...->dpm_suspend_start->suspend->Wait_for_completion_timeout->do
> es not receive signal and times out

dpm_suspend_start doesn't run until processes are frozen, and frozen 
processes cannot be waiting for a completion.  Therefore this can't 
happen.

> Interrupt->complete->
> 
> This happens very rare, there are other reason why wait_for_completion_times out
> like interrupt not received but I just want
> To make sure if completion signal is not lost during S3.

Of course it's possible that interrupts will not be delivered while the
computer is suspending or suspended.  Those interrupts should be
delivered later, when the computer wakes up again.

Alan Stern

^ permalink raw reply

* Question regarding completion signal in S3 flow
From: Mansoor, Illyas @ 2012-01-26 10:19 UTC (permalink / raw)
  To: linux-pm@lists.linux-foundation.org


[-- Attachment #1.1: Type: text/plain, Size: 546 bytes --]

Hi All,

I have question related to suspend flow and completion signal:

Is it possible that a completion signal could be missed in S3 flow after
processes are frozen? 

The scenario is:

Suspend_thread->...->dpm_suspend_start->suspend->Wait_for_completion_timeout->do
es not receive signal and times out

Interrupt->complete->

This happens very rare, there are other reason why wait_for_completion_times out
like interrupt not received but I just want
To make sure if completion signal is not lost during S3.

I'm using 2.6.35+ kernel

-Illyas

[-- Attachment #1.2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 7212 bytes --]

[-- Attachment #2: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply

* Re: [PATCH 2/7] tboot: Add return values for tboot_sleep
From: Cihula, Joseph @ 2012-01-26  0:16 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk
  Cc: Brown, Len, x86@kernel.org, linux-kernel@vger.kernel.org,
	linux-acpi@vger.kernel.org, tboot-devel@lists.sourceforge.net,
	liang.tang@oracle.com, hpa@zytor.com,
	linux-pm@lists.linux-foundation.org
In-Reply-To: <20120112202308.GA2030@phenom.dumpdata.com>

> From: Konrad Rzeszutek Wilk [mailto:konrad.wilk@oracle.com]
> Sent: Thursday, January 12, 2012 12:23 PM
eturn values for tboot_sleep
> 
> On Thu, Jan 12, 2012 at 09:49:58AM -0800, Konrad Rzeszutek Wilk wrote:
> > On Tue, Jan 10, 2012 at 08:10:53PM +0000, Cihula, Joseph wrote:
> > > ACK, but tboot_sleep() calls tboot_shutdown() and there are error conditions in that which you
> are not reflecting upward--i.e. you should make tboot_shutdown() return an 'int' and propagate its
> errors through tboot_sleep().
> >
> > Hey Joe,
> >
> > Thanks for looking at the patches.
> >
> > Right now [with this patch applied] the code looks as so:
> >
> > 297
> > 298         tboot_shutdown(acpi_shutdown_map[sleep_state]);
> > 299         return 0;
> > 300 }
> >
> >
> > If we do make tboot_shutdown() return an int, there will be a need to
> > modify other callers: native_machine_emergency_restart,
> > native_machine_halt, native_machine_power_off, and native_play_dead as well.
> >
> > Perhaps that could be done in another patch and leave this one as is
> > where the 'tboot_sleep' would just return 0 instead of 'return
> > tboot_shutdown(...)' ?
> >
> > Perhaps another way to do this is to extract the common code of
> > tboot_sleep and tboot_shutdown?

I'd be happier to see the callers above changed to handle a tboot_shutdown() that returned an error than splitting this up and only checking the error in one path.

Joe

> 
> Like this (not yet tested):
> 
> diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 6410744..2f93a50 100644
> --- a/arch/x86/kernel/tboot.c
> +++ b/arch/x86/kernel/tboot.c
> @@ -212,17 +212,16 @@ static int tboot_setup_sleep(void)  {
>  	/* S3 shutdown requested, but S3 not supported by the kernel... */
>  	BUG();
> -	return -1;
> +	return -ENOSYS;
>  }
> 
>  #endif
> 
> -void tboot_shutdown(u32 shutdown_type)
> -{
> -	void (*shutdown)(void);
> +static int tboot_check(u32 shutdown_type) {
> +
> 
>  	if (!tboot_enabled())
> -		return;
> +		return -ENODEV;
> 
>  	/*
>  	 * if we're being called before the 1:1 mapping is set up then just @@ -230,12 +229,21 @@
> void tboot_shutdown(u32 shutdown_type)
>  	 * due to very early panic()
>  	 */
>  	if (!tboot_pg_dir)
> -		return;
> +		return -EBUSY;
> 
>  	/* if this is S3 then set regions to MAC */
> -	if (shutdown_type == TB_SHUTDOWN_S3)
> -		if (tboot_setup_sleep())
> -			return;
> +	if (shutdown_type == TB_SHUTDOWN_S3) {
> +		int err = tboot_setup_sleep();
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
> +static void __tboot_shutdown(u32 shutdown_type) {
> +	void (*shutdown)(void);
> 
>  	tboot->shutdown_type = shutdown_type;
> 
> @@ -248,6 +256,13 @@ void tboot_shutdown(u32 shutdown_type)
>  	while (1)
>  		halt();
>  }
> +void tboot_shutdown(u32 shutdown_type)
> +{
> +	if (!tboot_check(shutdown_type))
> +		return;
> +
> +	__tboot_shutdown(shutdown_type);
> +}
> 
>  static void tboot_copy_fadt(const struct acpi_table_fadt *fadt)  { @@ -279,9 +294,17 @@ static
> int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
>  		/* S3: */ TB_SHUTDOWN_S3,
>  		/* S4: */ TB_SHUTDOWN_S4,
>  		/* S5: */ TB_SHUTDOWN_S5 };
> +	int err;
> 
> -	if (!tboot_enabled())
> -		return 0;
> +	if (sleep_state >= ACPI_S_STATE_COUNT ||
> +	    acpi_shutdown_map[sleep_state] == -1) {
> +		pr_warning("unsupported sleep state 0x%x\n", sleep_state);
> +		return -ENOSYS;
> +	}
> +
> +	err = tboot_check(acpi_shutdown_map[sleep_state]);
> +	if (!err && err != EBUSY)
> +		return err;
> 
>  	tboot_copy_fadt(&acpi_gbl_FADT);
>  	tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; @@ -289,13 +312,7 @@ static int
> tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control)
>  	/* we always use the 32b wakeup vector */
>  	tboot->acpi_sinfo.vector_width = 32;
> 
> -	if (sleep_state >= ACPI_S_STATE_COUNT ||
> -	    acpi_shutdown_map[sleep_state] == -1) {
> -		pr_warning("unsupported sleep state 0x%x\n", sleep_state);
> -		return -1;
> -	}
> -
> -	tboot_shutdown(acpi_shutdown_map[sleep_state]);
> +	__tboot_shutdown((acpi_shutdown_map[sleep_state]));
>  	return 0;
>  }
> 

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-25 22:00 UTC (permalink / raw)
  To: Srivatsa S. Bhat
  Cc: LKML, Baohua.Song, Tejun Heo, Linux-pm mailing list, Jiri Slaby
In-Reply-To: <4F202721.6050900@linux.vnet.ibm.com>

On 01/25/2012 05:00 PM, Srivatsa S. Bhat wrote:
> So, Jiri, can you please try the following patch and see if it works for
> you as expected? I'll be happy to provide a formal patch with a changelog
> if this works.

FWIW it works, thanks. If you want me test a proper fix, jsut let me know.

> ---
>  kernel/workqueue.c |    5 ++++-
>  1 files changed, 4 insertions(+), 1 deletions(-)
> 
> diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> index bec7b5b..cb26c5d 100644
> --- a/kernel/workqueue.c
> +++ b/kernel/workqueue.c
> @@ -3656,7 +3656,9 @@ void freeze_workqueues_begin(void)
>  
>  	spin_lock(&workqueue_lock);
>  
> -	BUG_ON(workqueue_freezing);
> +	if (workqueue_freezing)
> +		goto out_unlock;
> +
>  	workqueue_freezing = true;
>  
>  	for_each_gcwq_cpu(cpu) {
> @@ -3678,6 +3680,7 @@ void freeze_workqueues_begin(void)
>  		spin_unlock_irq(&gcwq->lock);
>  	}
>  
> +out_unlock:
>  	spin_unlock(&workqueue_lock);
>  }
>  


-- 
js

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Srivatsa S. Bhat @ 2012-01-25 18:44 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jiri Slaby, Linux PM mailing list, LKML, Baohua.Song, Tejun Heo,
	Linux-pm mailing list, Jiri Slaby
In-Reply-To: <4F202721.6050900@linux.vnet.ibm.com>

> 

> Commit 2aede851 (PM / Hibernate: Freeze kernel threads after preallocating
> memory) split up the freezing phase and moved the freezing of kernel threads
> to hibernation_snapshot() function.
> (This is a pretty old commit btw, I think it came in sometime around 3.2).
> 
> And there is a BUG_ON() in freeze_workqueues_begin() which complains if
> this function is called when the kernel threads are already frozen.
> 
> Now, coming to the userspace utility:
> 
>> In suspend.c inside the suspend-utils userspace package, I see a loop such
>> as:
>>
>>         error = freeze(snapshot_fd);
>> 	...
>>         attempts = 2;
>>         do {
>>                 if (set_image_size(snapshot_fd, image_size)) {
>>                         error = errno;
>>                         break;
>>                 }
>>                 if (atomic_snapshot(snapshot_fd, &in_suspend)) {
>                         ^^^ 
>         This ends up in the call to hibernation_snapshot().
> 
>>                         error = errno;
>>                         break;
>>                 }
>>                 if (!in_suspend) {
>>                         /* first unblank the console, see console_codes(4) */
>>                         printf("\e[13]");
>>                         printf("%s: returned to userspace\n", my_name);
>>                         free_snapshot(snapshot_fd);
>>                         break;
>>                 }
>>
>>                 error = write_image(snapshot_fd, resume_fd, -1);
>>                 if (error) {
> 
>         Since swap space is limited, we come here.
> 
>>                         free_swap_pages(snapshot_fd);
>>                         free_snapshot(snapshot_fd);

				^^^
	This function makes the ioctl call SNAPSHOT_FREE.

>>                         image_size = 0;
>>                         error = -error;
>>                         if (error != ENOSPC)
>>                                 break;
> 
> 
> 
> 
>         And because of the above 'if' condition, we don't break here.
>         IOW, we will run the loop a second time.
> 
>>                 } else {
>>                         splash.progress(100);
>> #ifdef CONFIG_BOTH
>>                         if (s2ram_kms || s2ram) {
>>                                 /* If we die (and allow system to continue)
>>                                  * between now and reset_signature(), very bad
>>                                  * things will happen. */
>>                                 error = suspend_to_ram(snapshot_fd);
>>                                 if (error)
>>                                         goto Shutdown;
>>                                 reset_signature(resume_fd);
>>                                 free_swap_pages(snapshot_fd);
>>                                 free_snapshot(snapshot_fd);
>>                                 if (!s2ram_kms)
>>                                         s2ram_resume();
>>                                 goto Unfreeze;
>>                         }
>> Shutdown:
>> #endif
>>                         close(resume_fd);
>>                         suspend_shutdown(snapshot_fd);
>>                 }
>>         } while (--attempts);
>>
>> ...
>> Unfreeze:
>>         unfreeze(snapshot_fd);
>>
>>
> 
> 
> So, since the loop is run a second time if not enough space was available,
> we end up calling hibernation_snapshot(), IOW freeze_workqueues_begin() a
> second time - and this is what makes the BUG_ON() to fire!
> 


SNAPSHOT_CREATE_IMAGE has a check for data->ready such as:

        if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
                error = -EPERM;
                break;
        }

data->ready would be set to 1 only under SNAPSHOT_CREATE_IMAGE. However,
SNAPSHOT_FREE (invoked at the place shown above) will reset the value to 0.
This makes it possible for hibernation_snapshot() and hence
freeze_workqueues_begin() to be called a second time, which is unfortunate.

And actually, the patch I posted in my previous mail is not really the right
long-term fix, though it might fix the particular issue that Jiri is facing..

Because, allowing hibernation_snapshot() to get called a second time while
kernel threads are still frozen brings us to the same situation that commit
2aede851 (PM / Hibernate: Freeze kernel threads after preallocating memory)
tried to prevent! IOW, a call to hibernate_preallocate_memory() would be
done inside hibernation_snapshot(), when kernel threads are frozen.. which
is known to break XFS, to give one example as mentioned in the changelog
of the above commit.

So, the right way to fix this IMHO, would be to split up thaw_processes()
just like freezing phase:

/* freezes or thaws user space processes */
freeze_processes() - thaw_processes()

/* freezes or thaws kernel threads */
freeze_kernel_threads() - thaw_kernel_threads()

We have to insert this thaw_kernel_threads() at appropriate places in such a
way as to not require another ioctl if possible... Then things would be
more symmetric (and hence more easy to understand) and we can avoid getting
into strange situations as discussed here.

But before we venture into that, it would be good to know if the patch posted
in the previous mail fixes the particular problem reported in this thread,
atleast just to see if there are other problems lurking that we aren't aware
of yet..

Regards,
Srivatsa S. Bhat

^ permalink raw reply

* Re: [linux-pm] PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Srivatsa S. Bhat @ 2012-01-25 16:00 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jiri Slaby, Linux-pm mailing list, Jiri Slaby, LKML, Baohua.Song,
	Tejun Heo, pavel@ucw.cz
In-Reply-To: <4F20204F.6040606@linux.vnet.ibm.com>

On 01/25/2012 09:01 PM, Srivatsa S. Bhat wrote:

> On 01/25/2012 05:40 AM, Rafael J. Wysocki wrote:
> 
>> On Wednesday, January 25, 2012, Jiri Slaby wrote:
>>> On 01/25/2012 12:02 AM, Rafael J. Wysocki wrote:
>>>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>>>>> On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
>>>>>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>>>>>>> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
>>>>>>>> Hi Jiri,
>>>>>>>>
>>>>>>>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
>>>>>>>>
>>>>>>>>> Hi,
>>>>>>>>>
>>>>>>>>> this is a freshly booted system. When I do s2dsk, I see:
>>>>>>>>> ...
>>>>>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>>>>>>> ------------[ cut here ]------------
>>>>>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>>>>>>> invalid opcode: 0000 [#1] SMP
>>>>>>>>> CPU 0
>>>>>>>>> Modules linked in:
>>>>>>>>>
>>>>>>>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
>>>>>>>>> Bochs Bochs
>>>>>>>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
>>>>>>>>> freeze_workqueues_begin+0x195/0x1a0
>>>>>>>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
>>>>>>>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
>>>>>>>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
>>>>>>>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
>>>>>>>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
>>>>>>>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
>>>>>>>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
>>>>>>>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>>>>>>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
>>>>>>>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>>>>>>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>>>>>>>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
>>>>>>>>> ffff880047251980)
>>>>>>>>> Stack:
>>>>>>>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>>>>>>>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>>>>>>>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
>>>>>>>>> Call Trace:
>>>>>>>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>>>>>>>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>>>>>>>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>>>>>>>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>>>>>>>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>>>>>>>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>>>>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>>>>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
>>>>>>>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
>>>>>>>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
>>>>>>>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>>>>>>>>>  RSP <ffff880046f01d68>
>>>>>>>>> ---[ end trace 632574abdc098963 ]---
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I couldn't find any obvious root-cause from a quick check. Is this completely
>>>>>>>> reproducible upon a fresh boot?
>>>>>>>
>>>>>>> True.
>>>>>>>
>>>>>>> The cause is that the function is called twice:
>>>>>>
>>>>>> Which function?
>>>>>
>>>>> The one where the BUG is. Maybe the functions which should clear the
>>>>> flag is not called in between? See:
>>>>>
>>>>>>>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
>>>>>                          ^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>>>> (elapsed 0.03 seconds) done.
>>>>> ...
>>>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>>>>> ------------[ cut here ]------------
>>>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>>> ...
>>>>>>> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
>>>>>>> freeze_workqueues_begin+0x1a1/0x1b0
>>>>>    ^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>> Call Trace:
>>>>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>
>>>> Ah.  So this is linux-next, right?
>>>
>>> Right.
>>>
>>>> Can you please test the linux-next branch of the linux-pm tree and see if
>>>> the problem is reproducible in there?
>>>
>>> Yeah, 100%. Just try it with a small enough swap.
>>
>> Ah, thanks, so that's an error code path problem and most likely in the Linus'
>> tree.
>>
>> Srivatsa, any ideas?
>>
> 
> 
> Ok, I will need to quote a part of the userspace utility to explain the
> problem.
> 




Commit 2aede851 (PM / Hibernate: Freeze kernel threads after preallocating
memory) split up the freezing phase and moved the freezing of kernel threads
to hibernation_snapshot() function.
(This is a pretty old commit btw, I think it came in sometime around 3.2).

And there is a BUG_ON() in freeze_workqueues_begin() which complains if
this function is called when the kernel threads are already frozen.

Now, coming to the userspace utility:

> In suspend.c inside the suspend-utils userspace package, I see a loop such
> as:
> 
>         error = freeze(snapshot_fd);
> 	...
>         attempts = 2;
>         do {
>                 if (set_image_size(snapshot_fd, image_size)) {
>                         error = errno;
>                         break;
>                 }
>                 if (atomic_snapshot(snapshot_fd, &in_suspend)) {



                        ^^^ 
        This ends up in the call to hibernation_snapshot().

>                         error = errno;
>                         break;
>                 }
>                 if (!in_suspend) {
>                         /* first unblank the console, see console_codes(4) */
>                         printf("\e[13]");
>                         printf("%s: returned to userspace\n", my_name);
>                         free_snapshot(snapshot_fd);
>                         break;
>                 }
> 
>                 error = write_image(snapshot_fd, resume_fd, -1);
>                 if (error) {




        Since swap space is limited, we come here.

>                         free_swap_pages(snapshot_fd);
>                         free_snapshot(snapshot_fd);
>                         image_size = 0;
>                         error = -error;
>                         if (error != ENOSPC)
>                                 break;




        And because of the above 'if' condition, we don't break here.
        IOW, we will run the loop a second time.

>                 } else {
>                         splash.progress(100);
> #ifdef CONFIG_BOTH
>                         if (s2ram_kms || s2ram) {
>                                 /* If we die (and allow system to continue)
>                                  * between now and reset_signature(), very bad
>                                  * things will happen. */
>                                 error = suspend_to_ram(snapshot_fd);
>                                 if (error)
>                                         goto Shutdown;
>                                 reset_signature(resume_fd);
>                                 free_swap_pages(snapshot_fd);
>                                 free_snapshot(snapshot_fd);
>                                 if (!s2ram_kms)
>                                         s2ram_resume();
>                                 goto Unfreeze;
>                         }
> Shutdown:
> #endif
>                         close(resume_fd);
>                         suspend_shutdown(snapshot_fd);
>                 }
>         } while (--attempts);
> 
> ...
> Unfreeze:
>         unfreeze(snapshot_fd);
> 
> 


So, since the loop is run a second time if not enough space was available,
we end up calling hibernation_snapshot(), IOW freeze_workqueues_begin() a
second time - and this is what makes the BUG_ON() to fire!

To solve this, I feel we can simply omit the BUG_ON() inside
freeze_workqueues_begin() and replace it with a simple check (just like
what we do in thaw_workqueues())...

And moreover, after the change that moved the freezing of kernel threads
to hibernation_snapshot(), it is quite natural to hit a scenario such
as this, because the entire freezing phase is not in one single place.
IOW, the existing BUG_ON() is not qualified to be there anymore!

(Also, exposing a straight-forward method like this to userspace, to
trigger a BUG_ON sounds ridiculous to start with!)

Of course, the other method would be to refactor the kernel code and stuff
like that, but that not only would be messy but it would also involve
breaking existing userspace applications, AFAICS.



So, Jiri, can you please try the following patch and see if it works for
you as expected? I'll be happy to provide a formal patch with a changelog
if this works.


---
 kernel/workqueue.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index bec7b5b..cb26c5d 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -3656,7 +3656,9 @@ void freeze_workqueues_begin(void)
 
 	spin_lock(&workqueue_lock);
 
-	BUG_ON(workqueue_freezing);
+	if (workqueue_freezing)
+		goto out_unlock;
+
 	workqueue_freezing = true;
 
 	for_each_gcwq_cpu(cpu) {
@@ -3678,6 +3680,7 @@ void freeze_workqueues_begin(void)
 		spin_unlock_irq(&gcwq->lock);
 	}
 
+out_unlock:
 	spin_unlock(&workqueue_lock);
 }
 
-- 
1.7.6

^ permalink raw reply related

* Re: [linux-pm] PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Srivatsa S. Bhat @ 2012-01-25 15:31 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Jiri Slaby, Linux-pm mailing list, Jiri Slaby, LKML, Baohua.Song,
	Tejun Heo, pavel@ucw.cz
In-Reply-To: <201201250110.44360.rjw@sisk.pl>

On 01/25/2012 05:40 AM, Rafael J. Wysocki wrote:

> On Wednesday, January 25, 2012, Jiri Slaby wrote:
>> On 01/25/2012 12:02 AM, Rafael J. Wysocki wrote:
>>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>>>> On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
>>>>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>>>>>> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
>>>>>>> Hi Jiri,
>>>>>>>
>>>>>>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
>>>>>>>
>>>>>>>> Hi,
>>>>>>>>
>>>>>>>> this is a freshly booted system. When I do s2dsk, I see:
>>>>>>>> ...
>>>>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>>>>>> ------------[ cut here ]------------
>>>>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>>>>>> invalid opcode: 0000 [#1] SMP
>>>>>>>> CPU 0
>>>>>>>> Modules linked in:
>>>>>>>>
>>>>>>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
>>>>>>>> Bochs Bochs
>>>>>>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
>>>>>>>> freeze_workqueues_begin+0x195/0x1a0
>>>>>>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
>>>>>>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
>>>>>>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
>>>>>>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
>>>>>>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
>>>>>>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
>>>>>>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
>>>>>>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>>>>>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
>>>>>>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>>>>>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>>>>>>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
>>>>>>>> ffff880047251980)
>>>>>>>> Stack:
>>>>>>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>>>>>>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>>>>>>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
>>>>>>>> Call Trace:
>>>>>>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>>>>>>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>>>>>>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>>>>>>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>>>>>>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>>>>>>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>>>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>>>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
>>>>>>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
>>>>>>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
>>>>>>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>>>>>>>>  RSP <ffff880046f01d68>
>>>>>>>> ---[ end trace 632574abdc098963 ]---
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> I couldn't find any obvious root-cause from a quick check. Is this completely
>>>>>>> reproducible upon a fresh boot?
>>>>>>
>>>>>> True.
>>>>>>
>>>>>> The cause is that the function is called twice:
>>>>>
>>>>> Which function?
>>>>
>>>> The one where the BUG is. Maybe the functions which should clear the
>>>> flag is not called in between? See:
>>>>
>>>>>>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
>>>>                          ^^^^^^^^^^^^^^^^^^^^^^^
>>>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>>> (elapsed 0.03 seconds) done.
>>>> ...
>>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>>>> ------------[ cut here ]------------
>>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>> ...
>>>>>> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
>>>>>> freeze_workqueues_begin+0x1a1/0x1b0
>>>>    ^^^^^^^^^^^^^^^^^^^^^^^
>>>>>> Call Trace:
>>>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>
>>> Ah.  So this is linux-next, right?
>>
>> Right.
>>
>>> Can you please test the linux-next branch of the linux-pm tree and see if
>>> the problem is reproducible in there?
>>
>> Yeah, 100%. Just try it with a small enough swap.
> 
> Ah, thanks, so that's an error code path problem and most likely in the Linus'
> tree.
> 
> Srivatsa, any ideas?
> 


Ok, I will need to quote a part of the userspace utility to explain the
problem.

In suspend.c inside the suspend-utils userspace package, I see a loop such
as:

        error = freeze(snapshot_fd);
	...
        attempts = 2;
        do {
                if (set_image_size(snapshot_fd, image_size)) {
                        error = errno;
                        break;
                }
                if (atomic_snapshot(snapshot_fd, &in_suspend)) {
                        error = errno;
                        break;
                }
                if (!in_suspend) {
                        /* first unblank the console, see console_codes(4) */
                        printf("\e[13]");
                        printf("%s: returned to userspace\n", my_name);
                        free_snapshot(snapshot_fd);
                        break;
                }

                error = write_image(snapshot_fd, resume_fd, -1);
                if (error) {
                        free_swap_pages(snapshot_fd);
                        free_snapshot(snapshot_fd);
                        image_size = 0;
                        error = -error;
                        if (error != ENOSPC)
                                break;
                } else {
                        splash.progress(100);
#ifdef CONFIG_BOTH
                        if (s2ram_kms || s2ram) {
                                /* If we die (and allow system to continue)
                                 * between now and reset_signature(), very bad
                                 * things will happen. */
                                error = suspend_to_ram(snapshot_fd);
                                if (error)
                                        goto Shutdown;
                                reset_signature(resume_fd);
                                free_swap_pages(snapshot_fd);
                                free_snapshot(snapshot_fd);
                                if (!s2ram_kms)
                                        s2ram_resume();
                                goto Unfreeze;
                        }
Shutdown:
#endif
                        close(resume_fd);
                        suspend_shutdown(snapshot_fd);
                }
        } while (--attempts);

...
Unfreeze:
        unfreeze(snapshot_fd);


Let me reply to this thread so that I can comment on the above code.

Regards,
Srivatsa S. Bhat

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-25 14:25 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux-pm mailing list, Jiri Slaby, LKML, Srivatsa S. Bhat
In-Reply-To: <201201250110.44360.rjw@sisk.pl>

On 01/25/2012 01:10 AM, Rafael J. Wysocki wrote:
> On Wednesday, January 25, 2012, Jiri Slaby wrote:
>> Yeah, 100%. Just try it with a small enough swap.
> 
> Ah, thanks, so that's an error code path problem and most likely in the Linus'
> tree.

Just to emphasize what I wrote earlier. I would apprectiate this fixed
in 3.2 stable too.

-- 
js

^ permalink raw reply

* Re: [PATCH 0/3] coupled cpuidle state support
From: Daniel Lezcano @ 2012-01-25 14:04 UTC (permalink / raw)
  To: Colin Cross
  Cc: Daniel Lezcano, linux-kernel, linux-arm-kernel, linux-pm,
	Len Brown, Kevin Hilman, Santosh Shilimkar, Amit Kucheria,
	Arjan van de Ven, Trinabh Gupta, Deepthi Dharwar, linux-omap,
	linux-tegra
In-Reply-To: <CAMbhsRTbVqV6p0py9NGZrpFPf2yvp-B0dr+o-m7qbdja_-Lfzw@mail.gmail.com>

On 01/20/2012 09:40 PM, Colin Cross wrote:
> On Fri, Jan 20, 2012 at 12:46 AM, Daniel Lezcano
> <daniel.lezcano@linaro.org>  wrote:
>> Hi Colin,
>>
>> this patchset could be interesting to resolve in a generic way the cpu
>> dependencies.
>> What is the status of this patchset ?
> I can't do much with it right now, because I don't have any devices
> that can do SMP idle with a v3.2 kernel.  I've started working on an
> updated version that avoids the spinlock, but it might be a while
> before I can test and post it.  I'm mostly looking for feedback on the
> approach taken in this patch, and whether it will be useful for other
> SoCs besides Tegra and OMAP4.

Hi Colin,

I will be happy to test your patchset. Do you have a pointer to a more 
recent kernel ?


>> Did you have the opportunity to measure the power consumption with and
>> without this patchset ?
> Power consumption will be very dependent on the specific SoC in
> question.  The most important factors are the power savings of the
> independent cpuidle state (normally WFI) vs. the hotplug state
> (normally 1 cpu in OFF), and the workload being tested.
>
> On a very idle system, these patches result in the same total power as
> hotplugging one cpu and letting the other idle normally.  On a 25%
> busy system, you might see a slight increase in power, as the best
> independent cpuidle state might be WFI, vs 1 cpu in OFF mode in
> hotplug.  On OMAP4, that difference is small, on the order of 10 mW.
> Once you hit the threshold where a hotplug governor would have
> hotplugged in the second cpu (lets say 40%), the savings from these
> patches are enormous, as you can hit the lowest power state up to 60%
> of the time, where the hotplug solution would never be going below WFI
> on both cpus.  On OMAP4, that can be well over 100 mW.

Interesting.


Thanks

   -- Daniel


^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Rafael J. Wysocki @ 2012-01-25  0:10 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Linux-pm mailing list, Jiri Slaby, LKML, Srivatsa S. Bhat
In-Reply-To: <4F1F4717.2090704@gmail.com>

On Wednesday, January 25, 2012, Jiri Slaby wrote:
> On 01/25/2012 12:02 AM, Rafael J. Wysocki wrote:
> > On Tuesday, January 24, 2012, Jiri Slaby wrote:
> >> On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
> >>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
> >>>> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
> >>>>> Hi Jiri,
> >>>>>
> >>>>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
> >>>>>
> >>>>>> Hi,
> >>>>>>
> >>>>>> this is a freshly booted system. When I do s2dsk, I see:
> >>>>>> ...
> >>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> >>>>>> ------------[ cut here ]------------
> >>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> >>>>>> invalid opcode: 0000 [#1] SMP
> >>>>>> CPU 0
> >>>>>> Modules linked in:
> >>>>>>
> >>>>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
> >>>>>> Bochs Bochs
> >>>>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
> >>>>>> freeze_workqueues_begin+0x195/0x1a0
> >>>>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
> >>>>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
> >>>>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
> >>>>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
> >>>>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> >>>>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
> >>>>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
> >>>>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >>>>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
> >>>>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >>>>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >>>>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
> >>>>>> ffff880047251980)
> >>>>>> Stack:
> >>>>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
> >>>>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
> >>>>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
> >>>>>> Call Trace:
> >>>>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>>>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
> >>>>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
> >>>>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
> >>>>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
> >>>>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
> >>>>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
> >>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> >>>>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
> >>>>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
> >>>>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
> >>>>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
> >>>>>>  RSP <ffff880046f01d68>
> >>>>>> ---[ end trace 632574abdc098963 ]---
> >>>>>>
> >>>>>
> >>>>>
> >>>>> I couldn't find any obvious root-cause from a quick check. Is this completely
> >>>>> reproducible upon a fresh boot?
> >>>>
> >>>> True.
> >>>>
> >>>> The cause is that the function is called twice:
> >>>
> >>> Which function?
> >>
> >> The one where the BUG is. Maybe the functions which should clear the
> >> flag is not called in between? See:
> >>
> >>>>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
> >>                          ^^^^^^^^^^^^^^^^^^^^^^^
> >>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
> >>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
> >>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
> >>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
> >>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
> >>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
> >>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> >>>> (elapsed 0.03 seconds) done.
> >> ...
> >>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> >>>> ------------[ cut here ]------------
> >>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> >> ...
> >>>> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
> >>>> freeze_workqueues_begin+0x1a1/0x1b0
> >>    ^^^^^^^^^^^^^^^^^^^^^^^
> >>>> Call Trace:
> >>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
> >>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
> >>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
> >>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
> >>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
> >>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
> >>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> > 
> > Ah.  So this is linux-next, right?
> 
> Right.
> 
> > Can you please test the linux-next branch of the linux-pm tree and see if
> > the problem is reproducible in there?
> 
> Yeah, 100%. Just try it with a small enough swap.

Ah, thanks, so that's an error code path problem and most likely in the Linus'
tree.

Srivatsa, any ideas?

Rafael

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-25  0:04 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux-pm mailing list, Jiri Slaby, LKML, Srivatsa S. Bhat
In-Reply-To: <201201250002.37916.rjw@sisk.pl>

On 01/25/2012 12:02 AM, Rafael J. Wysocki wrote:
> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>> On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
>>> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>>>> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
>>>>> Hi Jiri,
>>>>>
>>>>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> this is a freshly booted system. When I do s2dsk, I see:
>>>>>> ...
>>>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>>>> ------------[ cut here ]------------
>>>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>>>> invalid opcode: 0000 [#1] SMP
>>>>>> CPU 0
>>>>>> Modules linked in:
>>>>>>
>>>>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
>>>>>> Bochs Bochs
>>>>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
>>>>>> freeze_workqueues_begin+0x195/0x1a0
>>>>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
>>>>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
>>>>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
>>>>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
>>>>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
>>>>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
>>>>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
>>>>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>>>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
>>>>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>>>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>>>>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
>>>>>> ffff880047251980)
>>>>>> Stack:
>>>>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>>>>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>>>>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
>>>>>> Call Trace:
>>>>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>>>>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>>>>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>>>>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>>>>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>>>>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>>>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
>>>>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
>>>>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
>>>>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>>>>>>  RSP <ffff880046f01d68>
>>>>>> ---[ end trace 632574abdc098963 ]---
>>>>>>
>>>>>
>>>>>
>>>>> I couldn't find any obvious root-cause from a quick check. Is this completely
>>>>> reproducible upon a fresh boot?
>>>>
>>>> True.
>>>>
>>>> The cause is that the function is called twice:
>>>
>>> Which function?
>>
>> The one where the BUG is. Maybe the functions which should clear the
>> flag is not called in between? See:
>>
>>>>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
>>                          ^^^^^^^^^^^^^^^^^^^^^^^
>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>> (elapsed 0.03 seconds) done.
>> ...
>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>> ------------[ cut here ]------------
>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>> ...
>>>> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
>>>> freeze_workqueues_begin+0x1a1/0x1b0
>>    ^^^^^^^^^^^^^^^^^^^^^^^
>>>> Call Trace:
>>>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> 
> Ah.  So this is linux-next, right?

Right.

> Can you please test the linux-next branch of the linux-pm tree and see if
> the problem is reproducible in there?

Yeah, 100%. Just try it with a small enough swap.

thanks,
-- 
js

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Rafael J. Wysocki @ 2012-01-24 23:02 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Linux-pm mailing list, LKML, Srivatsa S. Bhat, Jiri Slaby
In-Reply-To: <4F1F350B.6010508@suse.cz>

On Tuesday, January 24, 2012, Jiri Slaby wrote:
> On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
> > On Tuesday, January 24, 2012, Jiri Slaby wrote:
> >> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
> >>> Hi Jiri,
> >>>
> >>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
> >>>
> >>>> Hi,
> >>>>
> >>>> this is a freshly booted system. When I do s2dsk, I see:
> >>>> ...
> >>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> >>>> ------------[ cut here ]------------
> >>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> >>>> invalid opcode: 0000 [#1] SMP
> >>>> CPU 0
> >>>> Modules linked in:
> >>>>
> >>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
> >>>> Bochs Bochs
> >>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
> >>>> freeze_workqueues_begin+0x195/0x1a0
> >>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
> >>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
> >>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
> >>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
> >>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> >>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
> >>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
> >>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
> >>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
> >>>> ffff880047251980)
> >>>> Stack:
> >>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
> >>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
> >>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
> >>>> Call Trace:
> >>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
> >>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
> >>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
> >>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
> >>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
> >>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
> >>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> >>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
> >>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
> >>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
> >>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
> >>>>  RSP <ffff880046f01d68>
> >>>> ---[ end trace 632574abdc098963 ]---
> >>>>
> >>>
> >>>
> >>> I couldn't find any obvious root-cause from a quick check. Is this completely
> >>> reproducible upon a fresh boot?
> >>
> >> True.
> >>
> >> The cause is that the function is called twice:
> > 
> > Which function?
> 
> The one where the BUG is. Maybe the functions which should clear the
> flag is not called in between? See:
> 
> >>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
>                          ^^^^^^^^^^^^^^^^^^^^^^^
> >>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
> >>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
> >>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
> >>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
> >>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
> >>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
> >>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> >> (elapsed 0.03 seconds) done.
> ...
> >> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> >> ------------[ cut here ]------------
> >> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> ...
> >> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
> >> freeze_workqueues_begin+0x1a1/0x1b0
>    ^^^^^^^^^^^^^^^^^^^^^^^
> >> Call Trace:
> >>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
> >>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
> >>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
> >>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
> >>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
> >>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
> >>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b

Ah.  So this is linux-next, right?

Can you please test the linux-next branch of the linux-pm tree and see if
the problem is reproducible in there?

Rafael

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-24 22:47 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Linux-pm mailing list, LKML, Srivatsa S. Bhat, Jiri Slaby
In-Reply-To: <201201242336.22482.rjw@sisk.pl>

On 01/24/2012 11:36 PM, Rafael J. Wysocki wrote:
> On Tuesday, January 24, 2012, Jiri Slaby wrote:
>> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
>>> Hi Jiri,
>>>
>>> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
>>>
>>>> Hi,
>>>>
>>>> this is a freshly booted system. When I do s2dsk, I see:
>>>> ...
>>>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>>>> ------------[ cut here ]------------
>>>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>>>> invalid opcode: 0000 [#1] SMP
>>>> CPU 0
>>>> Modules linked in:
>>>>
>>>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
>>>> Bochs Bochs
>>>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
>>>> freeze_workqueues_begin+0x195/0x1a0
>>>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
>>>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
>>>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
>>>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
>>>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
>>>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
>>>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
>>>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>>>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
>>>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>>>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>>>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
>>>> ffff880047251980)
>>>> Stack:
>>>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>>>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>>>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
>>>> Call Trace:
>>>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>>>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>>>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>>>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>>>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>>>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>>>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>>>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>>>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
>>>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
>>>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
>>>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>>>>  RSP <ffff880046f01d68>
>>>> ---[ end trace 632574abdc098963 ]---
>>>>
>>>
>>>
>>> I couldn't find any obvious root-cause from a quick check. Is this completely
>>> reproducible upon a fresh boot?
>>
>> True.
>>
>> The cause is that the function is called twice:
> 
> Which function?

The one where the BUG is. Maybe the functions which should clear the
flag is not called in between? See:

>>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
                         ^^^^^^^^^^^^^^^^^^^^^^^
>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>> (elapsed 0.03 seconds) done.
...
>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>> ------------[ cut here ]------------
>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
...
>> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>
>> freeze_workqueues_begin+0x1a1/0x1b0
   ^^^^^^^^^^^^^^^^^^^^^^^
>> Call Trace:
>>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b

-- 
js
suse labs

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Rafael J. Wysocki @ 2012-01-24 22:36 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Linux-pm mailing list, LKML, Srivatsa S. Bhat, Jiri Slaby
In-Reply-To: <4F1EDB41.2070303@suse.cz>

On Tuesday, January 24, 2012, Jiri Slaby wrote:
> On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
> > Hi Jiri,
> > 
> > On 01/24/2012 08:35 PM, Jiri Slaby wrote:
> > 
> >> Hi,
> >>
> >> this is a freshly booted system. When I do s2dsk, I see:
> >> ...
> >> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> >> ------------[ cut here ]------------
> >> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> >> invalid opcode: 0000 [#1] SMP
> >> CPU 0
> >> Modules linked in:
> >>
> >> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
> >> Bochs Bochs
> >> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
> >> freeze_workqueues_begin+0x195/0x1a0
> >> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
> >> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
> >> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
> >> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
> >> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> >> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
> >> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
> >> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> >> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
> >> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> >> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> >> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
> >> ffff880047251980)
> >> Stack:
> >>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
> >>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
> >>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
> >> Call Trace:
> >>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
> >>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
> >>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
> >>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
> >>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
> >>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
> >>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
> >>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> >> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
> >> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
> >> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
> >> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
> >>  RSP <ffff880046f01d68>
> >> ---[ end trace 632574abdc098963 ]---
> >>
> > 
> > 
> > I couldn't find any obvious root-cause from a quick check. Is this completely
> > reproducible upon a fresh boot?
> 
> True.
> 
> The cause is that the function is called twice:

Which function?

Rafael


> # s2disk
> PM: Marking nosave pages: 000000000009f000 - 0000000000100000
> PM: Basic memory bitmaps created
> Syncing filesystems ... done.
> Freezing user space processes ... (elapsed 0.01 seconds) done.
> PM: Preallocating image memory... done (allocated 264170 pages)
> PM: Allocated 1056680 kbytes in 0.45 seconds (2348.17 MB/s)
> Freezing remaining freezable tasks ... Pid: 2650, comm: s2disk Not
> tainted 3.3.0-rc1-next-20120124_64+ #1628
> Call Trace:
>  [<ffffffff8109edd2>] ? getnstimeofday+0x52/0xf0
>  [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> (elapsed 0.03 seconds) done.
> PM: freeze of devices complete after 57.216 msecs
> PM: late freeze of devices complete after 0.720 msecs
> ACPI: Preparing to enter system sleep state S4
> PM: Saving platform NVS memory
> Disabling non-boot CPUs ...
> CPU 1 is now offline
> PM: Creating hibernation image:
> PM: Need to copy 24112 pages
> PM: Normal pages needed: 24112 + 1024, available pages: 277076
> PM: Hibernation image created (24112 pages copied)
> Enabling non-boot CPUs ...
> Booting Node 0 Processor 1 APIC 0x1
> smpboot cpu 1: start_ip = 9a000
> Calibrating delay loop (skipped) already calibrated this CPU
> NMI watchdog disabled (cpu1): hardware events not enabled
> CPU1 is up
> ACPI: Waking up from system sleep state S4
> PM: early thaw of devices complete after 0.093 msecs
> ata_piix 0000:00:01.1: setting latency timer to 64
> e1000 0000:00:03.0: setting latency timer to 64
> e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
> ata2.01: NODEV after polling detection
> ata1.00: configured for MWDMA2
> ata2.00: configured for MWDMA2
> ata1.01: configured for MWDMA2
> sd 0:0:1:0: [sdb] Starting disk
> sd 0:0:0:0: [sda] Starting disk
> PM: thaw of devices complete after 192.317 msecs
> PM: Preallocating image memory... done (allocated 264295 pages)
> PM: Allocated 1057180 kbytes in 0.12 seconds (8809.83 MB/s)
> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> ------------[ cut here ]------------
> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> invalid opcode: 0000 [#1] SMP
> CPU 1
> Modules linked in:
> 
> Pid: 2650, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1628
> Bochs Bochs
> RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>]
> freeze_workqueues_begin+0x1a1/0x1b0
> RSP: 0018:ffff8800456d7d68  EFLAGS: 00010292
> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 0000000000000073
> RDX: 00000000000000ea RSI: 0000000000000046 RDI: ffffffff81b51f7c
> RBP: ffff8800456d7d98 R08: ffffffff81a9d760 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> R13: 00007fff11d8709c R14: ffffffffffffffff R15: 0000000000000004
> FS:  00007f4744397700(0000) GS:ffff880049700000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 0000000001f46bc0 CR3: 000000004483b000 CR4: 00000000000006e0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process s2disk (pid: 2650, threadinfo ffff8800456d6000, task
> ffff880046c93300)
> Stack:
>  ffff8800456d7d98 0000000000000001 0000000000000000 00007fff11d8709c
>  ffffffffffffffff 0000000000000004 ffff8800456d7e18 ffffffff81096cc9
>  00000000ffff008f 0000000000000004 ffff8800456d7e18 000000004f1edaaf
> Call Trace:
>  [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
>  [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
>  [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
>  [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
>  [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
>  [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
>  [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 1d 94 5a 00 0f 0b
> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 06 94 5a 00 <0f> 0b
> 66 66 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b
> RIP  [<ffffffff8107e371>] freeze_workqueues_begin+0x1a1/0x1b0
>  RSP <ffff8800456d7d68>
> ---[ end trace 696a23a038efce41 ]---
> 
> 
> 
> >  
> > Regards,
> > Srivatsa S. Bhat
> > IBM Linux Technology Center
> > 
> 
> 
> 

^ permalink raw reply

* Re: PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-24 16:24 UTC (permalink / raw)
  To: Srivatsa S. Bhat; +Cc: Linux-pm mailing list, LKML, Jiri Slaby
In-Reply-To: <4F1ED9C4.9020503@linux.vnet.ibm.com>

On 01/24/2012 05:18 PM, Srivatsa S. Bhat wrote:
> Hi Jiri,
> 
> On 01/24/2012 08:35 PM, Jiri Slaby wrote:
> 
>> Hi,
>>
>> this is a freshly booted system. When I do s2dsk, I see:
>> ...
>> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
>> ------------[ cut here ]------------
>> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
>> invalid opcode: 0000 [#1] SMP
>> CPU 0
>> Modules linked in:
>>
>> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
>> Bochs Bochs
>> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
>> freeze_workqueues_begin+0x195/0x1a0
>> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
>> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
>> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
>> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
>> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
>> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
>> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
>> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
>> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
>> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
>> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
>> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
>> ffff880047251980)
>> Stack:
>>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
>> Call Trace:
>>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
>> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
>> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
>> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
>> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>>  RSP <ffff880046f01d68>
>> ---[ end trace 632574abdc098963 ]---
>>
> 
> 
> I couldn't find any obvious root-cause from a quick check. Is this completely
> reproducible upon a fresh boot?

True.

The cause is that the function is called twice:
# s2disk
PM: Marking nosave pages: 000000000009f000 - 0000000000100000
PM: Basic memory bitmaps created
Syncing filesystems ... done.
Freezing user space processes ... (elapsed 0.01 seconds) done.
PM: Preallocating image memory... done (allocated 264170 pages)
PM: Allocated 1056680 kbytes in 0.45 seconds (2348.17 MB/s)
Freezing remaining freezable tasks ... Pid: 2650, comm: s2disk Not
tainted 3.3.0-rc1-next-20120124_64+ #1628
Call Trace:
 [<ffffffff8109edd2>] ? getnstimeofday+0x52/0xf0
 [<ffffffff8107e206>] freeze_workqueues_begin+0x36/0x1b0
 [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
 [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
 [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
 [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
 [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
 [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
 [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
 [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
(elapsed 0.03 seconds) done.
PM: freeze of devices complete after 57.216 msecs
PM: late freeze of devices complete after 0.720 msecs
ACPI: Preparing to enter system sleep state S4
PM: Saving platform NVS memory
Disabling non-boot CPUs ...
CPU 1 is now offline
PM: Creating hibernation image:
PM: Need to copy 24112 pages
PM: Normal pages needed: 24112 + 1024, available pages: 277076
PM: Hibernation image created (24112 pages copied)
Enabling non-boot CPUs ...
Booting Node 0 Processor 1 APIC 0x1
smpboot cpu 1: start_ip = 9a000
Calibrating delay loop (skipped) already calibrated this CPU
NMI watchdog disabled (cpu1): hardware events not enabled
CPU1 is up
ACPI: Waking up from system sleep state S4
PM: early thaw of devices complete after 0.093 msecs
ata_piix 0000:00:01.1: setting latency timer to 64
e1000 0000:00:03.0: setting latency timer to 64
e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: RX
ata2.01: NODEV after polling detection
ata1.00: configured for MWDMA2
ata2.00: configured for MWDMA2
ata1.01: configured for MWDMA2
sd 0:0:1:0: [sdb] Starting disk
sd 0:0:0:0: [sda] Starting disk
PM: thaw of devices complete after 192.317 msecs
PM: Preallocating image memory... done (allocated 264295 pages)
PM: Allocated 1057180 kbytes in 0.12 seconds (8809.83 MB/s)
Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
------------[ cut here ]------------
kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
invalid opcode: 0000 [#1] SMP
CPU 1
Modules linked in:

Pid: 2650, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1628
Bochs Bochs
RIP: 0010:[<ffffffff8107e371>]  [<ffffffff8107e371>]
freeze_workqueues_begin+0x1a1/0x1b0
RSP: 0018:ffff8800456d7d68  EFLAGS: 00010292
RAX: 0000000000000023 RBX: 0000000000000001 RCX: 0000000000000073
RDX: 00000000000000ea RSI: 0000000000000046 RDI: ffffffff81b51f7c
RBP: ffff8800456d7d98 R08: ffffffff81a9d760 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 00007fff11d8709c R14: ffffffffffffffff R15: 0000000000000004
FS:  00007f4744397700(0000) GS:ffff880049700000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000001f46bc0 CR3: 000000004483b000 CR4: 00000000000006e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process s2disk (pid: 2650, threadinfo ffff8800456d6000, task
ffff880046c93300)
Stack:
 ffff8800456d7d98 0000000000000001 0000000000000000 00007fff11d8709c
 ffffffffffffffff 0000000000000004 ffff8800456d7e18 ffffffff81096cc9
 00000000ffff008f 0000000000000004 ffff8800456d7e18 000000004f1edaaf
Call Trace:
 [<ffffffff81096cc9>] try_to_freeze_tasks+0x1b9/0x2d0
 [<ffffffff81096ee5>] freeze_kernel_threads+0x25/0x90
 [<ffffffff81097b65>] hibernation_snapshot+0x75/0x2e0
 [<ffffffff8109d734>] snapshot_ioctl+0x314/0x4e0
 [<ffffffff81130866>] do_vfs_ioctl+0x96/0x550
 [<ffffffff8111ff8b>] ? vfs_write+0x10b/0x180
 [<ffffffff81130d6a>] sys_ioctl+0x4a/0x80
 [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 1d 94 5a 00 0f 0b
48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 06 94 5a 00 <0f> 0b
66 66 66 66 2e 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b
RIP  [<ffffffff8107e371>] freeze_workqueues_begin+0x1a1/0x1b0
 RSP <ffff8800456d7d68>
---[ end trace 696a23a038efce41 ]---



>  
> Regards,
> Srivatsa S. Bhat
> IBM Linux Technology Center
> 


-- 
js
suse labs

^ permalink raw reply

* Re: [linux-pm] PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Srivatsa S. Bhat @ 2012-01-24 16:18 UTC (permalink / raw)
  To: Jiri Slaby; +Cc: Rafael J. Wysocki, Linux-pm mailing list, LKML, Jiri Slaby
In-Reply-To: <4F1EC8D5.5040102@suse.cz>

Hi Jiri,

On 01/24/2012 08:35 PM, Jiri Slaby wrote:

> Hi,
> 
> this is a freshly booted system. When I do s2dsk, I see:
> ...
> Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
> ------------[ cut here ]------------
> kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
> invalid opcode: 0000 [#1] SMP
> CPU 0
> Modules linked in:
> 
> Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
> Bochs Bochs
> RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
> freeze_workqueues_begin+0x195/0x1a0
> RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
> RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
> RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
> RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
> R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
> R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
> FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
> CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
> CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
> ffff880047251980)
> Stack:
>  ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
>  ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
>  00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
> Call Trace:
>  [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
>  [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
>  [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
>  [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
>  [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
>  [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
>  [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
>  [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
> Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
> 48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
> 66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
> RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
>  RSP <ffff880046f01d68>
> ---[ end trace 632574abdc098963 ]---
> 


I couldn't find any obvious root-cause from a quick check. Is this completely
reproducible upon a fresh boot?
 
Regards,
Srivatsa S. Bhat
IBM Linux Technology Center

^ permalink raw reply

* PM: cannot hibernate -- BUG at kernel/workqueue.c:3659
From: Jiri Slaby @ 2012-01-24 15:05 UTC (permalink / raw)
  To: Rafael J. Wysocki, Linux-pm mailing list, LKML, Jiri Slaby

Hi,

this is a freshly booted system. When I do s2dsk, I see:
...
Freezing remaining freezable tasks ... BUG: 'workqueue_freezing' is true!
------------[ cut here ]------------
kernel BUG at /l/latest/linux/kernel/workqueue.c:3659!
invalid opcode: 0000 [#1] SMP
CPU 0
Modules linked in:

Pid: 2669, comm: s2disk Not tainted 3.3.0-rc1-next-20120124_64+ #1627
Bochs Bochs
RIP: 0010:[<ffffffff8107e365>]  [<ffffffff8107e365>]
freeze_workqueues_begin+0x195/0x1a0
RSP: 0018:ffff880046f01d68  EFLAGS: 00010292
RAX: 0000000000000023 RBX: 0000000000000001 RCX: 00000000000000c9
RDX: 0000000000000077 RSI: 0000000000000046 RDI: ffffffff81b51f7c
RBP: ffff880046f01d98 R08: ffffffff81a9d760 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 00007fff579464dc R14: ffffffffffffffff R15: 0000000000000004
FS:  00007f3c65d54700(0000) GS:ffff880049600000(0000) knlGS:0000000000000000
CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 00007f3c64f58c20 CR3: 0000000045b64000 CR4: 00000000000006f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process s2disk (pid: 2669, threadinfo ffff880046f00000, task
ffff880047251980)
Stack:
 ffff880046f01d98 0000000000000001 0000000000000000 00007fff579464dc
 ffffffffffffffff 0000000000000004 ffff880046f01e18 ffffffff81096cb9
 00000000ffff0124 0000000000000004 ffff880046f01e18 000000004f1ec7d1
Call Trace:
 [<ffffffff81096cb9>] try_to_freeze_tasks+0x1b9/0x2d0
 [<ffffffff81096ed5>] freeze_kernel_threads+0x25/0x90
 [<ffffffff81097b55>] hibernation_snapshot+0x75/0x2e0
 [<ffffffff8109d724>] snapshot_ioctl+0x314/0x4e0
 [<ffffffff81130856>] do_vfs_ioctl+0x96/0x550
 [<ffffffff8111ff7b>] ? vfs_write+0x10b/0x180
 [<ffffffff81130d5a>] sys_ioctl+0x4a/0x80
 [<ffffffff81630e22>] system_call_fastpath+0x16/0x1b
Code: c7 c6 0a a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 19 94 5a 00 0f 0b
48 c7 c6 27 a4 92 81 48 c7 c7 16 65 92 81 31 c0 e8 02 94 5a 00 <0f> 0b
66 0f 1f 84 00 00 00 00 00 55 48 c7 c7 82 4b b9 81 48 89
RIP  [<ffffffff8107e365>] freeze_workqueues_begin+0x195/0x1a0
 RSP <ffff880046f01d68>
---[ end trace 632574abdc098963 ]---

I wanted to reproduce a different crash which happens on 3.2.1. When
there is not enough free swap, the kernel crashes (when s2disk is used).
I will post more info after the one above is resolved and I can
reproduce the latter :).

thanks,
-- 
js
suse labs

^ permalink raw reply

* [PATCH 10/10] Use acpi_os_map_memory() instead of ioremap() in einj driver
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Len Brown, Luck, Tony
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: "Luck, Tony" <tony.luck@intel.com>

ioremap() has become more picky and is now spitting out console messages like:

 ioremap error for 0xbddbd000-0xbddbe000, requested 0x10, got 0x0

when loading the einj driver.  What we are trying to so here is map
a couple of data structures that the EINJ table points to. Perhaps
acpi_os_map_memory() is a better tool for this?
Most importantly it works, but as a side benefit it maps the structures
into kernel virtual space so we can access them with normal C memory
dereferences, so instead of using:
	writel(param1, &v5param->apicid);
we can use the more natural:
	v5param->apicid = param1;

Signed-off-by: Tony Luck <tony.luck@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/apei/einj.c |   82 +++++++++++++++++++++------------------------
 1 files changed, 38 insertions(+), 44 deletions(-)

diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index c89b0e5..4ca087d 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
 
 static void *einj_param;
 
-#ifndef readq
-static inline __u64 readq(volatile void __iomem *addr)
-{
-	return ((__u64)readl(addr+4) << 32) + readl(addr);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
-	writel(val, addr);
-	writel(val >> 32, addr+4);
-}
-#endif
-
 static void einj_exec_ctx_init(struct apei_exec_context *ctx)
 {
 	apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
 static void check_vendor_extension(u64 paddr,
 				   struct set_error_type_with_address *v5param)
 {
-	int	offset = readl(&v5param->vendor_extension);
+	int	offset = v5param->vendor_extension;
 	struct	vendor_error_type_extension *v;
 	u32	sbdf;
 
 	if (!offset)
 		return;
-	v = ioremap(paddr + offset, sizeof(*v));
+	v = acpi_os_map_memory(paddr + offset, sizeof(*v));
 	if (!v)
 		return;
-	sbdf = readl(&v->pcie_sbdf);
+	sbdf = v->pcie_sbdf;
 	sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
 		sbdf >> 24, (sbdf >> 16) & 0xff,
 		(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
-		 readw(&v->vendor_id), readw(&v->device_id),
-		readb(&v->rev_id));
-	iounmap(v);
+		 v->vendor_id, v->device_id, v->rev_id);
+	acpi_os_unmap_memory(v, sizeof(*v));
 }
 
 static void *einj_get_parameter_address(void)
@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
 	if (paddrv5) {
 		struct set_error_type_with_address *v5param;
 
-		v5param = ioremap(paddrv5, sizeof(*v5param));
+		v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
 		if (v5param) {
 			acpi5 = 1;
 			check_vendor_extension(paddrv5, v5param);
@@ -257,11 +241,11 @@ static void *einj_get_parameter_address(void)
 	if (paddrv4) {
 		struct einj_parameter *v4param;
 
-		v4param = ioremap(paddrv4, sizeof(*v4param));
+		v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
 		if (!v4param)
 			return NULL;
-		if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) {
-			iounmap(v4param);
+		if (v4param->reserved1 || v4param->reserved2) {
+			acpi_os_unmap_memory(v4param, sizeof(*v4param));
 			return NULL;
 		}
 		return v4param;
@@ -440,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
 	if (acpi5) {
 		struct set_error_type_with_address *v5param = einj_param;
 
-		writel(type, &v5param->type);
+		v5param->type = type;
 		if (type & 0x80000000) {
 			switch (vendor_flags) {
 			case SETWA_FLAGS_APICID:
-				writel(param1, &v5param->apicid);
+				v5param->apicid = param1;
 				break;
 			case SETWA_FLAGS_MEM:
-				writeq(param1, &v5param->memory_address);
-				writeq(param2, &v5param->memory_address_range);
+				v5param->memory_address = param1;
+				v5param->memory_address_range = param2;
 				break;
 			case SETWA_FLAGS_PCIE_SBDF:
-				writel(param1, &v5param->pcie_sbdf);
+				v5param->pcie_sbdf = param1;
 				break;
 			}
-			writel(vendor_flags, &v5param->flags);
+			v5param->flags = vendor_flags;
 		} else {
 			switch (type) {
 			case ACPI_EINJ_PROCESSOR_CORRECTABLE:
 			case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
 			case ACPI_EINJ_PROCESSOR_FATAL:
-				writel(param1, &v5param->apicid);
-				writel(SETWA_FLAGS_APICID, &v5param->flags);
+				v5param->apicid = param1;
+				v5param->flags = SETWA_FLAGS_APICID;
 				break;
 			case ACPI_EINJ_MEMORY_CORRECTABLE:
 			case ACPI_EINJ_MEMORY_UNCORRECTABLE:
 			case ACPI_EINJ_MEMORY_FATAL:
-				writeq(param1, &v5param->memory_address);
-				writeq(param2, &v5param->memory_address_range);
-				writel(SETWA_FLAGS_MEM, &v5param->flags);
+				v5param->memory_address = param1;
+				v5param->memory_address_range = param2;
+				v5param->flags = SETWA_FLAGS_MEM;
 				break;
 			case ACPI_EINJ_PCIX_CORRECTABLE:
 			case ACPI_EINJ_PCIX_UNCORRECTABLE:
 			case ACPI_EINJ_PCIX_FATAL:
-				writel(param1, &v5param->pcie_sbdf);
-				writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags);
+				v5param->pcie_sbdf = param1;
+				v5param->flags = SETWA_FLAGS_PCIE_SBDF;
 				break;
 			}
 		}
@@ -484,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
 			return rc;
 		if (einj_param) {
 			struct einj_parameter *v4param = einj_param;
-			writeq(param1, &v4param->param1);
-			writeq(param2, &v4param->param2);
+			v4param->param1 = param1;
+			v4param->param2 = param2;
 		}
 	}
 	rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
@@ -736,8 +720,13 @@ static int __init einj_init(void)
 	return 0;
 
 err_unmap:
-	if (einj_param)
-		iounmap(einj_param);
+	if (einj_param) {
+		acpi_size size = (acpi5) ?
+			sizeof(struct set_error_type_with_address) :
+			sizeof(struct einj_parameter);
+
+		acpi_os_unmap_memory(einj_param, size);
+	}
 	apei_exec_post_unmap_gars(&ctx);
 err_release:
 	apei_resources_release(&einj_resources);
@@ -753,8 +742,13 @@ static void __exit einj_exit(void)
 {
 	struct apei_exec_context ctx;
 
-	if (einj_param)
-		iounmap(einj_param);
+	if (einj_param) {
+		acpi_size size = (acpi5) ?
+			sizeof(struct set_error_type_with_address) :
+			sizeof(struct einj_parameter);
+
+		acpi_os_unmap_memory(einj_param, size);
+	}
 	einj_exec_ctx_init(&ctx);
 	apei_exec_post_unmap_gars(&ctx);
 	apei_resources_release(&einj_resources);
-- 
1.7.9.rc2

^ permalink raw reply related

* [PATCH 09/10] ACPI, APEI, EINJ, cleanup 0 vs NULL confusion
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Dan Carpenter, Len Brown
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: Dan Carpenter <dan.carpenter@oracle.com>

This function is returning pointers.  Sparse complains here:
drivers/acpi/apei/einj.c:262:32: warning:
	Using plain integer as NULL pointer

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Acked-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/apei/einj.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index bb20b03..c89b0e5 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -259,15 +259,15 @@ static void *einj_get_parameter_address(void)
 
 		v4param = ioremap(paddrv4, sizeof(*v4param));
 		if (!v4param)
-			return 0;
+			return NULL;
 		if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) {
 			iounmap(v4param);
-			return 0;
+			return NULL;
 		}
 		return v4param;
 	}
 
-	return 0;
+	return NULL;
 }
 
 /* do sanity check to trigger table */
-- 
1.7.9.rc2


^ permalink raw reply related

* [PATCH 08/10] ACPI, APEI, EINJ Allow empty Trigger Error Action Table
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Niklas Söderlund, Len Brown
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: Niklas Söderlund <niklas.soderlund@ericsson.com>

According to the ACPI spec [1] section 18.6.4 the TRIGGER_ERROR action
table can consists of zero elements.

[1] Advanced Configuration and Power Interface Specification
    Revision 5.0, December 6, 2011
	http://www.acpi.info/DOWNLOADS/ACPIspec50.pdf

Signed-off-by: Niklas Söderlund <niklas.soderlund@ericsson.com>
Acked-by: Huang Ying <ying.huang@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/apei/einj.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index 5b898d4..bb20b03 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -276,7 +276,7 @@ static int einj_check_trigger_header(struct acpi_einj_trigger *trigger_tab)
 	if (trigger_tab->header_size != sizeof(struct acpi_einj_trigger))
 		return -EINVAL;
 	if (trigger_tab->table_size > PAGE_SIZE ||
-	    trigger_tab->table_size <= trigger_tab->header_size)
+	    trigger_tab->table_size < trigger_tab->header_size)
 		return -EINVAL;
 	if (trigger_tab->entry_count !=
 	    (trigger_tab->table_size - trigger_tab->header_size) /
@@ -340,6 +340,11 @@ static int __einj_error_trigger(u64 trigger_paddr, u32 type,
 			   "The trigger error action table is invalid\n");
 		goto out_rel_header;
 	}
+
+	/* No action structures in the TRIGGER_ERROR table, nothing to do */
+	if (!trigger_tab->entry_count)
+		goto out_rel_header;
+
 	rc = -EIO;
 	table_size = trigger_tab->table_size;
 	r = request_mem_region(trigger_paddr + sizeof(*trigger_tab),
-- 
1.7.9.rc2

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH 07/10] thermal: Rename generate_netlink_event
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Jean Delvare, Len Brown
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: Jean Delvare <khali@linux-fr.org>

It doesn't seem right for the thermal subsystem to export a symbol
named generate_netlink_event. This function is thermal-specific and
its name should reflect that fact. Rename it to
thermal_generate_netlink_event.

Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: R.Durgadoss <durgadoss.r@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 Documentation/thermal/sysfs-api.txt |    2 +-
 drivers/thermal/thermal_sys.c       |    4 ++--
 include/linux/thermal.h             |    4 ++--
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index b61e46f..1733ab9 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -284,7 +284,7 @@ method, the sys I/F structure will be built like this:
 The framework includes a simple notification mechanism, in the form of a
 netlink event. Netlink socket initialization is done during the _init_
 of the framework. Drivers which intend to use the notification mechanism
-just need to call generate_netlink_event() with two arguments viz
+just need to call thermal_generate_netlink_event() with two arguments viz
 (originator, event). Typically the originator will be an integer assigned
 to a thermal_zone_device when it registers itself with the framework. The
 event will be one of:{THERMAL_AUX0, THERMAL_AUX1, THERMAL_CRITICAL,
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index dd9a574..220ce7e 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1304,7 +1304,7 @@ static struct genl_multicast_group thermal_event_mcgrp = {
 	.name = THERMAL_GENL_MCAST_GROUP_NAME,
 };
 
-int generate_netlink_event(u32 orig, enum events event)
+int thermal_generate_netlink_event(u32 orig, enum events event)
 {
 	struct sk_buff *skb;
 	struct nlattr *attr;
@@ -1363,7 +1363,7 @@ int generate_netlink_event(u32 orig, enum events event)
 
 	return result;
 }
-EXPORT_SYMBOL(generate_netlink_event);
+EXPORT_SYMBOL(thermal_generate_netlink_event);
 
 static int genetlink_init(void)
 {
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 47b4a27..796f1ff 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -152,9 +152,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *, void *,
 void thermal_cooling_device_unregister(struct thermal_cooling_device *);
 
 #ifdef CONFIG_NET
-extern int generate_netlink_event(u32 orig, enum events event);
+extern int thermal_generate_netlink_event(u32 orig, enum events event);
 #else
-static inline int generate_netlink_event(u32 orig, enum events event)
+static inline int thermal_generate_netlink_event(u32 orig, enum events event)
 {
 	return 0;
 }
-- 
1.7.9.rc2


^ permalink raw reply related

* [PATCH 06/10] ACPI / PM: Add Sony Vaio VPCCW29FX to nonvs blacklist.
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Lan Tianyu, Len Brown
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: Lan Tianyu <tianyu.lan@intel.com>

Sony Vaio VPCCW29FX does not resume correctly without
acpi_sleep=nonvs, so add it to the ACPI sleep blacklist.

https://bugzilla.kernel.org/show_bug.cgi?id=34722

Signed-off-by: Lan Tianyu <tianyu.lan@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/sleep.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 0a7ed69..ca191ff 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -438,6 +438,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 	},
 	{
 	.callback = init_nvs_nosave,
+	.ident = "Sony Vaio VPCCW29FX",
+	.matches = {
+		DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
+		DMI_MATCH(DMI_PRODUCT_NAME, "VPCCW29FX"),
+		},
+	},
+	{
+	.callback = init_nvs_nosave,
 	.ident = "Averatec AV1020-ED2",
 	.matches = {
 		DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"),
-- 
1.7.9.rc2


^ permalink raw reply related

* [PATCH 05/10] ACPI: Remove ./drivers/acpi/atomicio.[ch]
From: Len Brown @ 2012-01-24  1:30 UTC (permalink / raw)
  To: linux-acpi, linux-pm; +Cc: Myron Stowe, Myron Stowe, Len Brown
In-Reply-To: <54d5dcc45af7adbb907072d042bbece4c2b4de6e.1327368464.git.len.brown@intel.com>

From: Myron Stowe <mstowe@redhat.com>

With the conversion of atomicio's routines in place (see commits
6f68c91c55e and 700130b41f4), atomicio.[ch] can be removed, replacing
the APEI specific pre-mapping capabilities with the more generalized
versions that drivers/acpi/osl.c provides.

Signed-off-by: Myron Stowe <myron.stowe@redhat.com>
Signed-off-by: Len Brown <len.brown@intel.com>
---
 drivers/acpi/Makefile   |    1 -
 drivers/acpi/atomicio.c |  422 -----------------------------------------------
 include/acpi/atomicio.h |   10 -
 3 files changed, 0 insertions(+), 433 deletions(-)
 delete mode 100644 drivers/acpi/atomicio.c
 delete mode 100644 include/acpi/atomicio.h

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index c07f44f..1567028 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -19,7 +19,6 @@ obj-y				+= acpi.o \
 
 # All the builtin files are in the "acpi." module_param namespace.
 acpi-y				+= osl.o utils.o reboot.o
-acpi-y				+= atomicio.o
 acpi-y				+= nvs.o
 
 # sleep related files
diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c
deleted file mode 100644
index d4a5b3d..0000000
--- a/drivers/acpi/atomicio.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * atomicio.c - ACPI IO memory pre-mapping/post-unmapping, then
- * accessing in atomic context.
- *
- * This is used for NMI handler to access IO memory area, because
- * ioremap/iounmap can not be used in NMI handler. The IO memory area
- * is pre-mapped in process context and accessed in NMI handler.
- *
- * Copyright (C) 2009-2010, Intel Corp.
- *	Author: Huang Ying <ying.huang@intel.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#include <linux/kernel.h>
-#include <linux/export.h>
-#include <linux/init.h>
-#include <linux/acpi.h>
-#include <linux/io.h>
-#include <linux/kref.h>
-#include <linux/rculist.h>
-#include <linux/interrupt.h>
-#include <linux/slab.h>
-#include <linux/mm.h>
-#include <linux/highmem.h>
-#include <acpi/atomicio.h>
-
-#define ACPI_PFX "ACPI: "
-
-static LIST_HEAD(acpi_iomaps);
-/*
- * Used for mutual exclusion between writers of acpi_iomaps list, for
- * synchronization between readers and writer, RCU is used.
- */
-static DEFINE_SPINLOCK(acpi_iomaps_lock);
-
-struct acpi_iomap {
-	struct list_head list;
-	void __iomem *vaddr;
-	unsigned long size;
-	phys_addr_t paddr;
-	struct kref ref;
-};
-
-/* acpi_iomaps_lock or RCU read lock must be held before calling */
-static struct acpi_iomap *__acpi_find_iomap(phys_addr_t paddr,
-					    unsigned long size)
-{
-	struct acpi_iomap *map;
-
-	list_for_each_entry_rcu(map, &acpi_iomaps, list) {
-		if (map->paddr + map->size >= paddr + size &&
-		    map->paddr <= paddr)
-			return map;
-	}
-	return NULL;
-}
-
-/*
- * Atomic "ioremap" used by NMI handler, if the specified IO memory
- * area is not pre-mapped, NULL will be returned.
- *
- * acpi_iomaps_lock or RCU read lock must be held before calling
- */
-static void __iomem *__acpi_ioremap_fast(phys_addr_t paddr,
-					 unsigned long size)
-{
-	struct acpi_iomap *map;
-
-	map = __acpi_find_iomap(paddr, size/8);
-	if (map)
-		return map->vaddr + (paddr - map->paddr);
-	else
-		return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __iomem *__acpi_try_ioremap(phys_addr_t paddr,
-					unsigned long size)
-{
-	struct acpi_iomap *map;
-
-	map = __acpi_find_iomap(paddr, size);
-	if (map) {
-		kref_get(&map->ref);
-		return map->vaddr + (paddr - map->paddr);
-	} else
-		return NULL;
-}
-
-#ifndef CONFIG_IA64
-#define should_use_kmap(pfn)	page_is_ram(pfn)
-#else
-/* ioremap will take care of cache attributes */
-#define should_use_kmap(pfn)	0
-#endif
-
-static void __iomem *acpi_map(phys_addr_t pg_off, unsigned long pg_sz)
-{
-	unsigned long pfn;
-
-	pfn = pg_off >> PAGE_SHIFT;
-	if (should_use_kmap(pfn)) {
-		if (pg_sz > PAGE_SIZE)
-			return NULL;
-		return (void __iomem __force *)kmap(pfn_to_page(pfn));
-	} else
-		return ioremap(pg_off, pg_sz);
-}
-
-static void acpi_unmap(phys_addr_t pg_off, void __iomem *vaddr)
-{
-	unsigned long pfn;
-
-	pfn = pg_off >> PAGE_SHIFT;
-	if (page_is_ram(pfn))
-		kunmap(pfn_to_page(pfn));
-	else
-		iounmap(vaddr);
-}
-
-/*
- * Used to pre-map the specified IO memory area. First try to find
- * whether the area is already pre-mapped, if it is, increase the
- * reference count (in __acpi_try_ioremap) and return; otherwise, do
- * the real ioremap, and add the mapping into acpi_iomaps list.
- */
-static void __iomem *acpi_pre_map(phys_addr_t paddr,
-				  unsigned long size)
-{
-	void __iomem *vaddr;
-	struct acpi_iomap *map;
-	unsigned long pg_sz, flags;
-	phys_addr_t pg_off;
-
-	spin_lock_irqsave(&acpi_iomaps_lock, flags);
-	vaddr = __acpi_try_ioremap(paddr, size);
-	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-	if (vaddr)
-		return vaddr;
-
-	pg_off = paddr & PAGE_MASK;
-	pg_sz = ((paddr + size + PAGE_SIZE - 1) & PAGE_MASK) - pg_off;
-	vaddr = acpi_map(pg_off, pg_sz);
-	if (!vaddr)
-		return NULL;
-	map = kmalloc(sizeof(*map), GFP_KERNEL);
-	if (!map)
-		goto err_unmap;
-	INIT_LIST_HEAD(&map->list);
-	map->paddr = pg_off;
-	map->size = pg_sz;
-	map->vaddr = vaddr;
-	kref_init(&map->ref);
-
-	spin_lock_irqsave(&acpi_iomaps_lock, flags);
-	vaddr = __acpi_try_ioremap(paddr, size);
-	if (vaddr) {
-		spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-		acpi_unmap(pg_off, map->vaddr);
-		kfree(map);
-		return vaddr;
-	}
-	list_add_tail_rcu(&map->list, &acpi_iomaps);
-	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
-	return map->vaddr + (paddr - map->paddr);
-err_unmap:
-	acpi_unmap(pg_off, vaddr);
-	return NULL;
-}
-
-/* acpi_iomaps_lock must be held before calling */
-static void __acpi_kref_del_iomap(struct kref *ref)
-{
-	struct acpi_iomap *map;
-
-	map = container_of(ref, struct acpi_iomap, ref);
-	list_del_rcu(&map->list);
-}
-
-/*
- * Used to post-unmap the specified IO memory area. The iounmap is
- * done only if the reference count goes zero.
- */
-static void acpi_post_unmap(phys_addr_t paddr, unsigned long size)
-{
-	struct acpi_iomap *map;
-	unsigned long flags;
-	int del;
-
-	spin_lock_irqsave(&acpi_iomaps_lock, flags);
-	map = __acpi_find_iomap(paddr, size);
-	BUG_ON(!map);
-	del = kref_put(&map->ref, __acpi_kref_del_iomap);
-	spin_unlock_irqrestore(&acpi_iomaps_lock, flags);
-
-	if (!del)
-		return;
-
-	synchronize_rcu();
-	acpi_unmap(map->paddr, map->vaddr);
-	kfree(map);
-}
-
-/* In NMI handler, should set silent = 1 */
-static int acpi_check_gar(struct acpi_generic_address *reg,
-			  u64 *paddr, int silent)
-{
-	u32 width, space_id;
-
-	width = reg->bit_width;
-	space_id = reg->space_id;
-	/* Handle possible alignment issues */
-	memcpy(paddr, &reg->address, sizeof(*paddr));
-	if (!*paddr) {
-		if (!silent)
-			pr_warning(FW_BUG ACPI_PFX
-			"Invalid physical address in GAR [0x%llx/%u/%u]\n",
-				   *paddr, width, space_id);
-		return -EINVAL;
-	}
-
-	if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
-		if (!silent)
-			pr_warning(FW_BUG ACPI_PFX
-				   "Invalid bit width in GAR [0x%llx/%u/%u]\n",
-				   *paddr, width, space_id);
-		return -EINVAL;
-	}
-
-	if (space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY &&
-	    space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
-		if (!silent)
-			pr_warning(FW_BUG ACPI_PFX
-			"Invalid address space type in GAR [0x%llx/%u/%u]\n",
-				   *paddr, width, space_id);
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/* Pre-map, working on GAR */
-int acpi_pre_map_gar(struct acpi_generic_address *reg)
-{
-	u64 paddr;
-	void __iomem *vaddr;
-	int rc;
-
-	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
-		return 0;
-
-	rc = acpi_check_gar(reg, &paddr, 0);
-	if (rc)
-		return rc;
-
-	vaddr = acpi_pre_map(paddr, reg->bit_width / 8);
-	if (!vaddr)
-		return -EIO;
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_pre_map_gar);
-
-/* Post-unmap, working on GAR */
-int acpi_post_unmap_gar(struct acpi_generic_address *reg)
-{
-	u64 paddr;
-	int rc;
-
-	if (reg->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
-		return 0;
-
-	rc = acpi_check_gar(reg, &paddr, 0);
-	if (rc)
-		return rc;
-
-	acpi_post_unmap(paddr, reg->bit_width / 8);
-
-	return 0;
-}
-EXPORT_SYMBOL_GPL(acpi_post_unmap_gar);
-
-#ifdef readq
-static inline u64 read64(const volatile void __iomem *addr)
-{
-	return readq(addr);
-}
-#else
-static inline u64 read64(const volatile void __iomem *addr)
-{
-	u64 l, h;
-	l = readl(addr);
-	h = readl(addr+4);
-	return l | (h << 32);
-}
-#endif
-
-/*
- * Can be used in atomic (including NMI) or process context. RCU read
- * lock can only be released after the IO memory area accessing.
- */
-static int acpi_atomic_read_mem(u64 paddr, u64 *val, u32 width)
-{
-	void __iomem *addr;
-
-	rcu_read_lock();
-	addr = __acpi_ioremap_fast(paddr, width);
-	switch (width) {
-	case 8:
-		*val = readb(addr);
-		break;
-	case 16:
-		*val = readw(addr);
-		break;
-	case 32:
-		*val = readl(addr);
-		break;
-	case 64:
-		*val = read64(addr);
-		break;
-	default:
-		return -EINVAL;
-	}
-	rcu_read_unlock();
-
-	return 0;
-}
-
-#ifdef writeq
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
-	writeq(val, addr);
-}
-#else
-static inline void write64(u64 val, volatile void __iomem *addr)
-{
-	writel(val, addr);
-	writel(val>>32, addr+4);
-}
-#endif
-
-static int acpi_atomic_write_mem(u64 paddr, u64 val, u32 width)
-{
-	void __iomem *addr;
-
-	rcu_read_lock();
-	addr = __acpi_ioremap_fast(paddr, width);
-	switch (width) {
-	case 8:
-		writeb(val, addr);
-		break;
-	case 16:
-		writew(val, addr);
-		break;
-	case 32:
-		writel(val, addr);
-		break;
-	case 64:
-		write64(val, addr);
-		break;
-	default:
-		return -EINVAL;
-	}
-	rcu_read_unlock();
-
-	return 0;
-}
-
-/* GAR accessing in atomic (including NMI) or process context */
-int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg)
-{
-	u64 paddr;
-	int rc;
-
-	rc = acpi_check_gar(reg, &paddr, 1);
-	if (rc)
-		return rc;
-
-	*val = 0;
-	switch (reg->space_id) {
-	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-		return acpi_atomic_read_mem(paddr, val, reg->bit_width);
-	case ACPI_ADR_SPACE_SYSTEM_IO:
-		return acpi_os_read_port(paddr, (u32 *)val, reg->bit_width);
-	default:
-		return -EINVAL;
-	}
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_read);
-
-int acpi_atomic_write(u64 val, struct acpi_generic_address *reg)
-{
-	u64 paddr;
-	int rc;
-
-	rc = acpi_check_gar(reg, &paddr, 1);
-	if (rc)
-		return rc;
-
-	switch (reg->space_id) {
-	case ACPI_ADR_SPACE_SYSTEM_MEMORY:
-		return acpi_atomic_write_mem(paddr, val, reg->bit_width);
-	case ACPI_ADR_SPACE_SYSTEM_IO:
-		return acpi_os_write_port(paddr, val, reg->bit_width);
-	default:
-		return -EINVAL;
-	}
-}
-EXPORT_SYMBOL_GPL(acpi_atomic_write);
diff --git a/include/acpi/atomicio.h b/include/acpi/atomicio.h
deleted file mode 100644
index 8b9fb4b..0000000
--- a/include/acpi/atomicio.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef ACPI_ATOMIC_IO_H
-#define ACPI_ATOMIC_IO_H
-
-int acpi_pre_map_gar(struct acpi_generic_address *reg);
-int acpi_post_unmap_gar(struct acpi_generic_address *reg);
-
-int acpi_atomic_read(u64 *val, struct acpi_generic_address *reg);
-int acpi_atomic_write(u64 val, struct acpi_generic_address *reg);
-
-#endif
-- 
1.7.9.rc2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox