LWN.net Logo

A pair of suspend2 patches

One of the outcomes from the power management summit held on July 17 was a decision to move toward merging Nigel Cunningham's suspend2 patches - at least, those which appear to make sense to the wider community. Suspend2 is an out-of-tree implementation of the suspend-to-disk and suspend-to-ram features which are so nice to have on laptop systems. The suspend2 implementation offers a number of features not found in the mainline version, including nice displays, progress bars, interruptible operation, and, it is said, greater reliability. Getting the better parts of suspend2 into the mainline seems like a clearly desirable goal. Since the summit, Nigel has posted a pair of patches which provide some clues as to what is coming, and how it will be received.

A big part of the software suspend problem is getting the system into a quiescent state before putting it on ice. To that end, processes are put into the "refrigerator," a special sort of suspended animation. When suspend time comes around, every process on the system is sent a special signal telling it that refrigeration time has come; each process, once it gets to a good stopping point, checks itself into the fridge and does not run again until after the system has been resumed.

The problem that this scheme runs into is that some processes are dependent on others. If a process which, for example, is involved with getting data written to disk is refrigerated too early in the process, it may never be possible to get the system to a state where it can be suspended. So the software suspend patches try to figure out which processes must be allowed to continue running while the system is being quiesced. It has always been a bit of a hit-and-miss business. The current suspend2 patches try to clean up that process a bit.

Many of the processes which should not be refrigerated are associated with various driver workqueues. So the mainline suspend code marks every workqueue process with the special PF_NOFREEZE flag, keeping it out of the clutches of the refrigerator. But most of those processes can be refrigerated just fine with no ill effect, and they should be. Having unneeded processes running when the system is trying to suspend itself can only serve to destabilize the entire situation.

Previous versions of the suspend2 patches changed the workqueue API so that every creator of a workqueue had to explicitly state whether it should be refrigerated or not. That approach worked, but it broke every create_workqueue() call. The current patch, instead, leaves the existing calls alone, but extends the API with a couple of new calls:

    struct workqueue_struct *create_nofreeze_workqueue(const char *name);
    struct workqueue_struct *create_nofreeze_singlethread_workqueue(const char *name);

As an aside, one notes that kernel namespace is starting to acquire some very long function names. One might almost wish for the good old days, when only the first six characters of a function name were used.

Seriously, however, these functions show how refrigeration is now handled with workqueues. By default, worker tasks associated with workqueues will be put on ice when the system is suspended. Anybody wishing to create a workqueue which does not behave that way must call one of the new functions.

This change has been propagated down to the generic kernel threads layer, which also picked up a new function:

    struct task_struct *kthread_nofreeze_create(int (fn)(void *data),
                                                void *data,
						const char *namefmt, ...);

This patch seems likely to be merged with, at most, minor tweaks. Nigel's second patch, however, got a somewhat less friendly reception. It creates a new process flag called PF_SYNCTHREAD. Any process which is actively trying to flush data to disk is marked with this flag; the end result is that it will be passed over by the refrigerator during the early part of the suspend process. In this way, processes which are creating dirty pages can be put on hold prior to those which are trying to clean those pages up. This patch is not popular, however; it has been criticized for being overly intrusive when simply flushing all pages to disk prior to beginning the suspend process would do the trick. So, unless things change, this patch will not go in.

In any case, these patches are just preparatory work for a larger event: the merging of a new refrigerator implementation. That code has not (recently) been posted; stay tuned.


(Log in to post comments)

Bravo for Nigel and Suspend2!

Posted Jul 29, 2005 1:19 UTC (Fri) by cthulhu (guest, #4776) [Link]

Whenever I see a suspend2 article, I have to say *something* because I think it's great.

I have been using suspend2 for quite a while, now. It works much better in the 2.6 kernel than in the 2.4.

Yes, it is very useful, almost essential, for laptops, and I have it installed on my Linux laptop. However, I use it most often with my desktop system. Before suspend existed, I'd leave my system on all the time because I didn't want to lose all my existing state. Now, I just hibernate, and I save *all* my desktop (and obviously machine) state, and AC power as well.

Linux does a fantastic job with servers, and I would never speak against the need for server functionality. But if we want it to really succeed on the desktop, I believe we absolutely *require* good, reliable hibernation functionality.

Anyway, just my 2 cents.

Really nice writeup

Posted Jul 29, 2005 3:36 UTC (Fri) by apollock (subscriber, #14629) [Link]

I am definitely in the user-land camp when it comes to kernel stuff, but I found this article extremely readable and interested. Nice work.

A pair of suspend2 patches

Posted Jul 30, 2005 8:36 UTC (Sat) by NCunningham (guest, #6457) [Link]

"...simply flushing all pages to disk prior to beginning the suspend process would do the trick..."

Hi. This is precisely the point I've trying to make: Flushing all pages to disk prior to beginning the suspend process wouldn't do the trick. It is entirely possible that other processes will submit I/O while or after the flush runs. In addition, if other processes are submitting I/O while the sync is running, the sync may not return until after the other processes have submitted an awfully large amount of I/O (depending on patterns). I've been told that work is in progress to address this, but it still leaves the first problem.

The only way to address the race is to remove the race: stop processes submitting new I/O, sync the I/O that is there and then get on with suspending.

Regards,

Nigel

Dumbest question ever

Posted Aug 4, 2005 9:56 UTC (Thu) by rvfh (subscriber, #31018) [Link]

That's probably the dumbest question ever heard, but...
Why is it needed to flush dirty pages? Presumably, all pages are in the memory, which is going to be saved to disk anyway...
Why is it not possible to
  • stop all processes
  • tell all drivers to suspend (apart from hard-disk, of course)
  • copy memory contents and registers to disk
  • suspend system

Is there some document I could read about that so I'll ask more clever questions in the future?

Dumbest question ever

Posted Aug 6, 2005 15:54 UTC (Sat) by fjalvingh (guest, #4803) [Link]

I think the reason would be:

Dirty pages can also be pages from the file system. Not flushing them would put the FS in an inconsistent state - i.e. the changes are not written. This would not be a problem IF the machine was brought up again from the hibernated state, but if that fails then you have a damaged file system..

A pair of suspend2 patches

Posted Aug 1, 2005 17:42 UTC (Mon) by bronson (subscriber, #4806) [Link]

Long function names like this usually indicate a flags parameter could be useful:

create_workqueue(NOFREEZE | SINGLETHREAD);

This tends to make the API more future-friendly too. Other than performance (which isn't too critical when creating workqueues), is there any reason to create 2^N function calls instead of N flags?

A pair of suspend2 patches

Posted Sep 15, 2005 7:23 UTC (Thu) by NCunningham (guest, #6457) [Link]

Sorry for the long delay in replying :)

I agree, but the consensus from others was that they view it as more important to minimise the changes to the api. Adding a _nofreeze variant lets us only change the functions that need to be unfreezable.

Regards,

Nigel

Copyright © 2005, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds