Re: [PATCH 06/10] libata: implement new Power Management framework

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2006-06-14 at 22:29 +0900, Tejun Heo wrote:
> zhao, forrest wrote:
> > On Tue, 2006-06-13 at 00:50 +0900, Tejun Heo wrote:
> >> + */
> >> +static void ata_eh_handle_resume(struct ata_port *ap)
> >> +{
> >> +	unsigned long flags;
> >> +	int rc = 0;
> >> +
> >> +	spin_lock_irqsave(&ap->host_set->lock, flags);
> >> +	if (!(ap->flags & ATA_FLAG_PM_PENDING) ||
> >> +	    !(ap->flags & ATA_FLAG_SUSPENDED) ||
> >> +	    ap->pm_mesg.event != PM_EVENT_ON) {
> >> +		spin_unlock_irqrestore(&ap->host_set->lock, flags);
> >> +		return;
> >> +	}
> >> +	ap->flags &= ~ATA_FLAG_PM_PENDING;
> >> +	spin_unlock_irqrestore(&ap->host_set->lock, flags);
> >> +
> >> +	if (ap->host_set->dev->power.power_state.event == PM_EVENT_SUSPEND) {
> >> +		struct ata_eh_context *ehc = &ap->eh_context;
> >> +
> >> +		ehc->i.action |= ATA_EH_SPINUP;
> >> +		ata_ehi_hotplugged(&ehc->i);
> >> +	}
> >> +
> >> +	if (ap->ops->resume)
> >> +		rc = ap->ops->resume(ap);
> >> +
> >> +	spin_lock_irqsave(&ap->host_set->lock, flags);
> >> +	ap->flags &= ~ATA_FLAG_SUSPENDED;
> >> +	ap->pm_result = rc;
> >> +	spin_unlock_irqrestore(&ap->host_set->lock, flags);
> >> +}
> > 
> > I ported AHCI suspend/resume patches against your new PM framework. At
> > first resume from memsleep took 65 seconds to go through soft-reset,
> > hard-reset; then after I removed line 
> > "if (ap->host_set->dev->power.power_state.event == PM_EVENT_SUSPEND)" in
> > ata_eh_handle_resume(), AHCI can resume from memsleep in a few seconds.
> > After inserting a printk(), I found the "ap->host_set->dev->power.
> > power_state.event" is always 0(PM_EVENT_ON).
> 
> Can you post the AHCI patch you did?  The suspend routine is supposed to 
> set power state to PM_EVENT_SUSPEND on memsleep such that resume can 
> notice it's resuming from actual suspend.

Yeah, on memsleep host_set->dev->power.power_state is set to
PM_EVENT_SUSPEND in ata_host_set_suspend(). Then during resume process,
firstly ata_host_set_resume() is called, in which host_set->dev->power.
power_state is set to PMSG_ON, then ata_eh_handle_resume() is called
later. This is the reason why ap->host_set->dev->power.power_state.event
is 0 in ata_eh_handle_resume(). This is a race condition.

Thanks,
Forrest
-
: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux