From mboxrd@z Thu Jan 1 00:00:00 1970 From: Malcolm Crossley Subject: Re: S3 resume issues Date: Tue, 15 Jan 2013 18:17:39 +0000 Message-ID: <50F59D43.9080304@citrix.com> References: <50E44F25.2060501@citrix.com> <50E5695202000078000B2A88@nat28.tlf.novell.com> <50E5C92102000078000B2D94@nat28.tlf.novell.com> <50E6A23802000078000B303D@nat28.tlf.novell.com> <50F5225702000078000B5AB4@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; Format="flowed" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Ben Guthro Cc: Jinsong Liu , Jan Beulich , "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org On 15/01/13 18:10, Ben Guthro wrote: > On Tue, Jan 15, 2013 at 7:55 AM, Ben Guthro wrote: >> I'll continue down the rcu_check_callbacks() path, I guess. > I believe I've found the culprit of the issue, but am unsure of what > the proper solution is. > > It looks like after resume, on these newer machines, the ns16550 > registers contain all FF's - and so, the timer code was getting stuck > in > __ns16550_poll in the following stack: > > __ns16550_poll() > execute_timer() > timer_softirq_action() > __do_softirq() > process_pending_softirqs() > rcu_barrier_action() > rcu_barrier() > enter_state() > > The while loop in this function was spinning, calling > serial_rx_interrupt() over, and over again, since the LSR register was > 0xFF > > A workaround seems to be to check some of the named registers at > resume time, and bail out if they contain 0xFF's: > > diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c > index d77042e..b370581 100644 > --- a/xen/drivers/char/ns16550.c > +++ b/xen/drivers/char/ns16550.c > @@ -342,6 +342,15 @@ static void ns16550_resume(struct serial_port *port) > PCI_COMMAND, uart->cr); > } > > + if ( (((unsigned char)ns_read_reg(uart, LSR)) == 0xff) && > + (((unsigned char)ns_read_reg(uart, MCR)) == 0xff) && > + (((unsigned char)ns_read_reg(uart, IER)) == 0xff) && > + (((unsigned char)ns_read_reg(uart, IIR)) == 0xff) && > + (((unsigned char)ns_read_reg(uart, LCR)) == 0xff) ) { > + printk(KERN_ERR "ns16550 resume has bad register data!\n"); > + return; > + } > + > ns16550_setup_preirq(port->uart); > ns16550_setup_postirq(port->uart); > } > > > This, of course means that you don't get any serial data after resume, > which is not ideal. > > > I'm going to try to figure out if there is any chipset (Panther Point) > specific initialization that should be getting done. > If you (or anyone else) has any other thoughts on this serial > initialization, please let me know. > > > Ben You get 0xFF when there is nothing responding to the ioport. If the 16550 is on a PCI card then it could be the PCI connection has not been setup again after the resume and you can't get to that ioport range. Malcolm