* Freezer Patches.
@ 2005-06-01 12:33 Nigel Cunningham
2005-06-01 13:02 ` Pavel Machek
0 siblings, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-01 12:33 UTC (permalink / raw)
To: Pavel Machek; +Cc: Linux Kernel Mailing List, Benjamin Herrenschmidt
[-- Attachment #1: Type: text/plain, Size: 195 bytes --]
Hi Pavel.
Here are the freezer patches. They were prepared against rc3, but I
think they still apply fine against rc5. (Ben, these are the same ones I
sent you the other day).
Regards,
Nigel
[-- Attachment #2: 300-workthreads.patch --]
[-- Type: text/x-patch, Size: 26559 bytes --]
diff -ruNp 210-workthreads.patch-old/drivers/acpi/osl.c 210-workthreads.patch-new/drivers/acpi/osl.c
--- 210-workthreads.patch-old/drivers/acpi/osl.c 2005-04-22 23:32:09.000000000 +1000
+++ 210-workthreads.patch-new/drivers/acpi/osl.c 2005-05-02 13:53:32.000000000 +1000
@@ -95,7 +95,7 @@ acpi_os_initialize1(void)
return AE_NULL_ENTRY;
}
#endif
- kacpid_wq = create_singlethread_workqueue("kacpid");
+ kacpid_wq = create_singlethread_workqueue("kacpid", PF_NOFREEZE);
BUG_ON(!kacpid_wq);
return AE_OK;
diff -ruNp 210-workthreads.patch-old/drivers/block/ll_rw_blk.c 210-workthreads.patch-new/drivers/block/ll_rw_blk.c
--- 210-workthreads.patch-old/drivers/block/ll_rw_blk.c 2005-04-22 23:32:09.000000000 +1000
+++ 210-workthreads.patch-new/drivers/block/ll_rw_blk.c 2005-05-02 13:53:32.000000000 +1000
@@ -3266,7 +3266,7 @@ EXPORT_SYMBOL(kblockd_flush);
int __init blk_dev_init(void)
{
- kblockd_workqueue = create_workqueue("kblockd");
+ kblockd_workqueue = create_workqueue("kblockd", PF_NOFREEZE);
if (!kblockd_workqueue)
panic("Failed to create kblockd\n");
diff -ruNp 210-workthreads.patch-old/drivers/block/pktcdvd.c 210-workthreads.patch-new/drivers/block/pktcdvd.c
--- 210-workthreads.patch-old/drivers/block/pktcdvd.c 2005-04-22 23:32:09.000000000 +1000
+++ 210-workthreads.patch-new/drivers/block/pktcdvd.c 2005-05-02 13:53:32.000000000 +1000
@@ -2366,7 +2366,7 @@ static int pkt_new_dev(struct pktcdvd_de
pkt_init_queue(pd);
atomic_set(&pd->cdrw.pending_bios, 0);
- pd->cdrw.thread = kthread_run(kcdrwd, pd, "%s", pd->name);
+ pd->cdrw.thread = kthread_run(kcdrwd, pd, 0, "%s", pd->name);
if (IS_ERR(pd->cdrw.thread)) {
printk("pktcdvd: can't start kernel thread\n");
ret = -ENOMEM;
diff -ruNp 210-workthreads.patch-old/drivers/char/hvc_console.c 210-workthreads.patch-new/drivers/char/hvc_console.c
--- 210-workthreads.patch-old/drivers/char/hvc_console.c 2005-02-03 22:33:25.000000000 +1100
+++ 210-workthreads.patch-new/drivers/char/hvc_console.c 2005-05-02 13:53:32.000000000 +1000
@@ -709,7 +709,7 @@ int __init hvc_init(void)
/* Always start the kthread because there can be hotplug vty adapters
* added later. */
- hvc_task = kthread_run(khvcd, NULL, "khvcd");
+ hvc_task = kthread_run(khvcd, NULL, PF_NOFREEZE, "khvcd");
if (IS_ERR(hvc_task)) {
panic("Couldn't create kthread for console.\n");
put_tty_driver(hvc_driver);
diff -ruNp 210-workthreads.patch-old/drivers/char/hvcs.c 210-workthreads.patch-new/drivers/char/hvcs.c
--- 210-workthreads.patch-old/drivers/char/hvcs.c 2005-02-14 09:05:25.000000000 +1100
+++ 210-workthreads.patch-new/drivers/char/hvcs.c 2005-05-02 13:53:32.000000000 +1000
@@ -1403,7 +1403,7 @@ static int __init hvcs_module_init(void)
return -ENOMEM;
}
- hvcs_task = kthread_run(khvcsd, NULL, "khvcsd");
+ hvcs_task = kthread_run(khvcsd, NULL, PF_NOFREEZE, "khvcsd");
if (IS_ERR(hvcs_task)) {
printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n");
kfree(hvcs_pi_buff);
diff -ruNp 210-workthreads.patch-old/drivers/infiniband/core/fmr_pool.c 210-workthreads.patch-new/drivers/infiniband/core/fmr_pool.c
--- 210-workthreads.patch-old/drivers/infiniband/core/fmr_pool.c 2005-04-22 23:32:11.000000000 +1000
+++ 210-workthreads.patch-new/drivers/infiniband/core/fmr_pool.c 2005-05-02 13:53:32.000000000 +1000
@@ -266,6 +266,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(s
pool->thread = kthread_create(ib_fmr_cleanup_thread,
pool,
+ 0,
"ib_fmr(%s)",
device->name);
if (IS_ERR(pool->thread)) {
diff -ruNp 210-workthreads.patch-old/drivers/infiniband/core/mad.c 210-workthreads.patch-new/drivers/infiniband/core/mad.c
--- 210-workthreads.patch-old/drivers/infiniband/core/mad.c 2005-04-22 23:32:11.000000000 +1000
+++ 210-workthreads.patch-new/drivers/infiniband/core/mad.c 2005-05-02 13:53:32.000000000 +1000
@@ -2502,7 +2502,7 @@ static int ib_mad_port_open(struct ib_de
goto error7;
snprintf(name, sizeof name, "ib_mad%d", port_num);
- port_priv->wq = create_singlethread_workqueue(name);
+ port_priv->wq = create_singlethread_workqueue(name, 0);
if (!port_priv->wq) {
ret = -ENOMEM;
goto error8;
diff -ruNp 210-workthreads.patch-old/drivers/infiniband/ulp/ipoib/ipoib_main.c 210-workthreads.patch-new/drivers/infiniband/ulp/ipoib/ipoib_main.c
--- 210-workthreads.patch-old/drivers/infiniband/ulp/ipoib/ipoib_main.c 2005-04-22 23:32:11.000000000 +1000
+++ 210-workthreads.patch-new/drivers/infiniband/ulp/ipoib/ipoib_main.c 2005-05-02 13:53:32.000000000 +1000
@@ -1070,7 +1070,7 @@ static int __init ipoib_init_module(void
* so flush_scheduled_work() can deadlock during device
* removal.
*/
- ipoib_workqueue = create_singlethread_workqueue("ipoib");
+ ipoib_workqueue = create_singlethread_workqueue("ipoib", 0);
if (!ipoib_workqueue) {
ret = -ENOMEM;
goto err_fs;
diff -ruNp 210-workthreads.patch-old/drivers/macintosh/therm_adt746x.c 210-workthreads.patch-new/drivers/macintosh/therm_adt746x.c
--- 210-workthreads.patch-old/drivers/macintosh/therm_adt746x.c 2005-04-22 23:32:12.000000000 +1000
+++ 210-workthreads.patch-new/drivers/macintosh/therm_adt746x.c 2005-05-02 13:53:32.000000000 +1000
@@ -438,7 +438,7 @@ static int attach_one_thermostat(struct
write_both_fan_speed(th, -1);
}
- thread_therm = kthread_run(monitor_task, th, "kfand");
+ thread_therm = kthread_run(monitor_task, th, 0, "kfand");
if (thread_therm == ERR_PTR(-ENOMEM)) {
printk(KERN_INFO "adt746x: Kthread creation failed\n");
diff -ruNp 210-workthreads.patch-old/drivers/md/dm-crypt.c 210-workthreads.patch-new/drivers/md/dm-crypt.c
--- 210-workthreads.patch-old/drivers/md/dm-crypt.c 2005-04-22 23:32:12.000000000 +1000
+++ 210-workthreads.patch-new/drivers/md/dm-crypt.c 2005-05-02 13:53:32.000000000 +1000
@@ -936,7 +936,7 @@ static int __init dm_crypt_init(void)
if (!_crypt_io_pool)
return -ENOMEM;
- _kcryptd_workqueue = create_workqueue("kcryptd");
+ _kcryptd_workqueue = create_workqueue("kcryptd", PF_NOFREEZE);
if (!_kcryptd_workqueue) {
r = -ENOMEM;
DMERR(PFX "couldn't create kcryptd");
diff -ruNp 210-workthreads.patch-old/drivers/md/dm-raid1.c 210-workthreads.patch-new/drivers/md/dm-raid1.c
--- 210-workthreads.patch-old/drivers/md/dm-raid1.c 2005-04-22 23:32:12.000000000 +1000
+++ 210-workthreads.patch-new/drivers/md/dm-raid1.c 2005-05-02 13:53:32.000000000 +1000
@@ -1229,7 +1229,7 @@ static int __init dm_mirror_init(void)
if (r)
return r;
- _kmirrord_wq = create_workqueue("kmirrord");
+ _kmirrord_wq = create_workqueue("kmirrord", PF_SYNCTHREAD);
if (!_kmirrord_wq) {
DMERR("couldn't start kmirrord");
dm_dirty_log_exit();
diff -ruNp 210-workthreads.patch-old/drivers/md/kcopyd.c 210-workthreads.patch-new/drivers/md/kcopyd.c
--- 210-workthreads.patch-old/drivers/md/kcopyd.c 2005-02-03 22:33:28.000000000 +1100
+++ 210-workthreads.patch-new/drivers/md/kcopyd.c 2005-05-02 13:53:32.000000000 +1000
@@ -609,7 +609,7 @@ static int kcopyd_init(void)
return r;
}
- _kcopyd_wq = create_singlethread_workqueue("kcopyd");
+ _kcopyd_wq = create_singlethread_workqueue("kcopyd", PF_SYNCTHREAD);
if (!_kcopyd_wq) {
jobs_exit();
up(&kcopyd_init_lock);
diff -ruNp 210-workthreads.patch-old/drivers/media/video/cx88/cx88-video.c 210-workthreads.patch-new/drivers/media/video/cx88/cx88-video.c
--- 210-workthreads.patch-old/drivers/media/video/cx88/cx88-video.c 2005-04-22 23:32:12.000000000 +1000
+++ 210-workthreads.patch-new/drivers/media/video/cx88/cx88-video.c 2005-05-02 13:53:32.000000000 +1000
@@ -2121,7 +2121,7 @@ static int __devinit cx8800_initdev(stru
/* start tvaudio thread */
if (core->tuner_type != TUNER_ABSENT)
- core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
+ core->kthread = kthread_run(cx88_audio_thread, core, 0, "cx88 tvaudio");
return 0;
fail_unreg:
diff -ruNp 210-workthreads.patch-old/drivers/media/video/msp3400.c 210-workthreads.patch-new/drivers/media/video/msp3400.c
--- 210-workthreads.patch-old/drivers/media/video/msp3400.c 2005-04-22 23:32:12.000000000 +1000
+++ 210-workthreads.patch-new/drivers/media/video/msp3400.c 2005-05-02 13:53:32.000000000 +1000
@@ -1555,7 +1555,7 @@ static int msp_attach(struct i2c_adapter
/* startup control thread if needed */
if (thread_func) {
- msp->kthread = kthread_run(thread_func, c, "msp34xx");
+ msp->kthread = kthread_run(thread_func, c, 0, "msp34xx");
if (NULL == msp->kthread)
printk(KERN_WARNING "msp34xx: kernel_thread() failed\n");
msp_wake_thread(c);
diff -ruNp 210-workthreads.patch-old/drivers/media/video/video-buf-dvb.c 210-workthreads.patch-new/drivers/media/video/video-buf-dvb.c
--- 210-workthreads.patch-old/drivers/media/video/video-buf-dvb.c 2005-02-03 22:33:29.000000000 +1100
+++ 210-workthreads.patch-new/drivers/media/video/video-buf-dvb.c 2005-05-02 13:53:32.000000000 +1000
@@ -104,7 +104,7 @@ static int videobuf_dvb_start_feed(struc
if (NULL != dvb->thread)
goto out;
dvb->thread = kthread_run(videobuf_dvb_thread,
- dvb, "%s dvb", dvb->name);
+ dvb, 0, "%s dvb", dvb->name);
if (IS_ERR(dvb->thread)) {
rc = PTR_ERR(dvb->thread);
dvb->thread = NULL;
diff -ruNp 210-workthreads.patch-old/drivers/message/i2o/driver.c 210-workthreads.patch-new/drivers/message/i2o/driver.c
--- 210-workthreads.patch-old/drivers/message/i2o/driver.c 2005-02-03 22:33:29.000000000 +1100
+++ 210-workthreads.patch-new/drivers/message/i2o/driver.c 2005-05-02 13:53:32.000000000 +1000
@@ -79,7 +79,7 @@ int i2o_driver_register(struct i2o_drive
pr_debug("i2o: Register driver %s\n", drv->name);
if (drv->event) {
- drv->event_queue = create_workqueue(drv->name);
+ drv->event_queue = create_workqueue(drv->name, 0);
if (!drv->event_queue) {
printk(KERN_ERR "i2o: Could not initialize event queue "
"for driver %s\n", drv->name);
diff -ruNp 210-workthreads.patch-old/drivers/net/wan/sdlamain.c 210-workthreads.patch-new/drivers/net/wan/sdlamain.c
--- 210-workthreads.patch-old/drivers/net/wan/sdlamain.c 2004-11-03 21:54:35.000000000 +1100
+++ 210-workthreads.patch-new/drivers/net/wan/sdlamain.c 2005-05-02 13:53:32.000000000 +1000
@@ -240,7 +240,7 @@ static int __init wanpipe_init(void)
printk(KERN_INFO "%s v%u.%u %s\n",
fullname, DRV_VERSION, DRV_RELEASE, copyright);
- wanpipe_wq = create_workqueue("wanpipe_wq");
+ wanpipe_wq = create_workqueue("wanpipe_wq", 0);
if (!wanpipe_wq)
return -ENOMEM;
diff -ruNp 210-workthreads.patch-old/drivers/s390/cio/device.c 210-workthreads.patch-new/drivers/s390/cio/device.c
--- 210-workthreads.patch-old/drivers/s390/cio/device.c 2005-04-22 23:32:15.000000000 +1000
+++ 210-workthreads.patch-new/drivers/s390/cio/device.c 2005-05-02 13:53:32.000000000 +1000
@@ -148,15 +148,16 @@ init_ccw_bus_type (void)
init_waitqueue_head(&ccw_device_init_wq);
atomic_set(&ccw_device_init_count, 0);
- ccw_device_work = create_singlethread_workqueue("cio");
+ ccw_device_work = create_singlethread_workqueue("cio", 0);
if (!ccw_device_work)
return -ENOMEM; /* FIXME: better errno ? */
- ccw_device_notify_work = create_singlethread_workqueue("cio_notify");
+ ccw_device_notify_work = create_singlethread_workqueue("cio_notify",
+ 0);
if (!ccw_device_notify_work) {
ret = -ENOMEM; /* FIXME: better errno ? */
goto out_err;
}
- slow_path_wq = create_singlethread_workqueue("kslowcrw");
+ slow_path_wq = create_singlethread_workqueue("kslowcrw", 0);
if (!slow_path_wq) {
ret = -ENOMEM; /* FIXME: better errno ? */
goto out_err;
diff -ruNp 210-workthreads.patch-old/drivers/scsi/hosts.c 210-workthreads.patch-new/drivers/scsi/hosts.c
--- 210-workthreads.patch-old/drivers/scsi/hosts.c 2005-04-22 23:32:16.000000000 +1000
+++ 210-workthreads.patch-new/drivers/scsi/hosts.c 2005-05-02 13:53:32.000000000 +1000
@@ -133,7 +133,7 @@ int scsi_add_host(struct Scsi_Host *shos
snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d",
shost->host_no);
shost->work_q = create_singlethread_workqueue(
- shost->work_q_name);
+ shost->work_q_name, PF_NOFREEZE);
if (!shost->work_q)
goto out_free_shost_data;
}
diff -ruNp 210-workthreads.patch-old/drivers/scsi/libata-core.c 210-workthreads.patch-new/drivers/scsi/libata-core.c
--- 210-workthreads.patch-old/drivers/scsi/libata-core.c 2005-04-22 23:32:16.000000000 +1000
+++ 210-workthreads.patch-new/drivers/scsi/libata-core.c 2005-05-02 13:53:32.000000000 +1000
@@ -3951,7 +3951,7 @@ int pci_test_config_bits(struct pci_dev
static int __init ata_init(void)
{
- ata_wq = create_workqueue("ata");
+ ata_wq = create_workqueue("ata", 0);
if (!ata_wq)
return -ENOMEM;
diff -ruNp 210-workthreads.patch-old/drivers/usb/net/pegasus.c 210-workthreads.patch-new/drivers/usb/net/pegasus.c
--- 210-workthreads.patch-old/drivers/usb/net/pegasus.c 2005-04-22 23:32:18.000000000 +1000
+++ 210-workthreads.patch-new/drivers/usb/net/pegasus.c 2005-05-02 13:53:32.000000000 +1000
@@ -1412,7 +1412,7 @@ static struct usb_driver pegasus_driver
static int __init pegasus_init(void)
{
pr_info("%s: %s, " DRIVER_DESC "\n", driver_name, DRIVER_VERSION);
- pegasus_workqueue = create_singlethread_workqueue("pegasus");
+ pegasus_workqueue = create_singlethread_workqueue("pegasus", PF_NOFREEZE);
if (!pegasus_workqueue)
return -ENOMEM;
return usb_register(&pegasus_driver);
diff -ruNp 210-workthreads.patch-old/fs/aio.c 210-workthreads.patch-new/fs/aio.c
--- 210-workthreads.patch-old/fs/aio.c 2005-04-22 23:32:19.000000000 +1000
+++ 210-workthreads.patch-new/fs/aio.c 2005-05-02 13:53:32.000000000 +1000
@@ -73,7 +73,7 @@ static int __init aio_setup(void)
kioctx_cachep = kmem_cache_create("kioctx", sizeof(struct kioctx),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
- aio_wq = create_workqueue("aio");
+ aio_wq = create_workqueue("aio", 0);
pr_debug("aio_setup: sizeof(struct page) = %d\n", (int)sizeof(struct page));
diff -ruNp 210-workthreads.patch-old/fs/nfsd/nfs4state.c 210-workthreads.patch-new/fs/nfsd/nfs4state.c
--- 210-workthreads.patch-old/fs/nfsd/nfs4state.c 2005-04-22 23:32:19.000000000 +1000
+++ 210-workthreads.patch-new/fs/nfsd/nfs4state.c 2005-05-02 13:53:32.000000000 +1000
@@ -1356,7 +1356,7 @@ void nfsd_break_deleg_cb(struct file_loc
/* XXX need to merge NFSD_LEASE_TIME with fs/locks.c:lease_break_time */
fl->fl_break_time = jiffies + NFSD_LEASE_TIME * HZ;
- t = kthread_run(do_recall, dp, "%s", "nfs4_cb_recall");
+ t = kthread_run(do_recall, dp, 0, "%s", "nfs4_cb_recall");
if (IS_ERR(t)) {
struct nfs4_client *clp = dp->dl_client;
diff -ruNp 210-workthreads.patch-old/fs/reiserfs/journal.c 210-workthreads.patch-new/fs/reiserfs/journal.c
--- 210-workthreads.patch-old/fs/reiserfs/journal.c 2005-04-22 23:32:19.000000000 +1000
+++ 210-workthreads.patch-new/fs/reiserfs/journal.c 2005-05-02 13:53:32.000000000 +1000
@@ -2512,7 +2512,7 @@ int journal_init(struct super_block *p_s
reiserfs_mounted_fs_count++ ;
if (reiserfs_mounted_fs_count <= 1)
- commit_wq = create_workqueue("reiserfs");
+ commit_wq = create_workqueue("reiserfs", PF_SYNCTHREAD);
INIT_WORK(&journal->j_work, flush_async_commits, p_s_sb);
return 0 ;
diff -ruNp 210-workthreads.patch-old/fs/xfs/linux-2.6/xfs_buf.c 210-workthreads.patch-new/fs/xfs/linux-2.6/xfs_buf.c
--- 210-workthreads.patch-old/fs/xfs/linux-2.6/xfs_buf.c 2005-04-22 23:32:19.000000000 +1000
+++ 210-workthreads.patch-new/fs/xfs/linux-2.6/xfs_buf.c 2005-05-02 13:53:53.000000000 +1000
@@ -1895,11 +1895,11 @@ pagebuf_daemon_start(void)
{
int rval;
- pagebuf_logio_workqueue = create_workqueue("xfslogd");
+ pagebuf_logio_workqueue = create_workqueue("xfslogd", PF_SYNCTHREAD);
if (!pagebuf_logio_workqueue)
return -ENOMEM;
- pagebuf_dataio_workqueue = create_workqueue("xfsdatad");
+ pagebuf_dataio_workqueue = create_workqueue("xfsdatad", PF_SYNCTHREAD);
if (!pagebuf_dataio_workqueue) {
destroy_workqueue(pagebuf_logio_workqueue);
return -ENOMEM;
diff -ruNp 210-workthreads.patch-old/include/linux/kthread.h 210-workthreads.patch-new/include/linux/kthread.h
--- 210-workthreads.patch-old/include/linux/kthread.h 2004-11-03 21:51:12.000000000 +1100
+++ 210-workthreads.patch-new/include/linux/kthread.h 2005-05-02 13:53:32.000000000 +1000
@@ -25,20 +25,26 @@
*/
struct task_struct *kthread_create(int (*threadfn)(void *data),
void *data,
+ unsigned long freezer_flags,
const char namefmt[], ...);
/**
* kthread_run: create and wake a thread.
* @threadfn: the function to run until signal_pending(current).
* @data: data ptr for @threadfn.
+ * @freezer_flags: process flags that should be used for freezing.
+ * PF_SYNCTHREAD if needed for syncing data to disk.
+ * PF_NOFREEZE if also needed for writing the image.
+ * 0 otherwise.
* @namefmt: printf-style name for the thread.
*
* Description: Convenient wrapper for kthread_create() followed by
* wake_up_process(). Returns the kthread, or ERR_PTR(-ENOMEM). */
-#define kthread_run(threadfn, data, namefmt, ...) \
+#define kthread_run(threadfn, data, freezer_flags, namefmt, ...) \
({ \
struct task_struct *__k \
- = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
+ = kthread_create(threadfn, data, freezer_flags, \
+ namefmt, ## __VA_ARGS__); \
if (!IS_ERR(__k)) \
wake_up_process(__k); \
__k; \
diff -ruNp 210-workthreads.patch-old/include/linux/workqueue.h 210-workthreads.patch-new/include/linux/workqueue.h
--- 210-workthreads.patch-old/include/linux/workqueue.h 2005-04-22 23:32:24.000000000 +1000
+++ 210-workthreads.patch-new/include/linux/workqueue.h 2005-05-02 13:53:32.000000000 +1000
@@ -51,9 +51,10 @@ struct work_struct {
} while (0)
extern struct workqueue_struct *__create_workqueue(const char *name,
- int singlethread);
-#define create_workqueue(name) __create_workqueue((name), 0)
-#define create_singlethread_workqueue(name) __create_workqueue((name), 1)
+ int singlethread,
+ unsigned long freezer_flag);
+#define create_workqueue(name, flags) __create_workqueue((name), 0, flags)
+#define create_singlethread_workqueue(name, flags) __create_workqueue((name), 1, flags)
extern void destroy_workqueue(struct workqueue_struct *wq);
diff -ruNp 210-workthreads.patch-old/kernel/kmod.c 210-workthreads.patch-new/kernel/kmod.c
--- 210-workthreads.patch-old/kernel/kmod.c 2004-12-10 14:27:00.000000000 +1100
+++ 210-workthreads.patch-new/kernel/kmod.c 2005-05-02 13:53:32.000000000 +1000
@@ -251,6 +251,6 @@ EXPORT_SYMBOL(call_usermodehelper);
void __init usermodehelper_init(void)
{
- khelper_wq = create_singlethread_workqueue("khelper");
+ khelper_wq = create_singlethread_workqueue("khelper", 0);
BUG_ON(!khelper_wq);
}
diff -ruNp 210-workthreads.patch-old/kernel/kthread.c 210-workthreads.patch-new/kernel/kthread.c
--- 210-workthreads.patch-old/kernel/kthread.c 2005-02-03 22:33:50.000000000 +1100
+++ 210-workthreads.patch-new/kernel/kthread.c 2005-05-02 13:53:32.000000000 +1000
@@ -25,6 +25,7 @@ struct kthread_create_info
/* Information passed to kthread() from keventd. */
int (*threadfn)(void *data);
void *data;
+ unsigned long freezer_flags;
struct completion started;
/* Result passed back to kthread_create() from keventd. */
@@ -86,6 +87,10 @@ static int kthread(void *_create)
/* By default we can run anywhere, unlike keventd. */
set_cpus_allowed(current, CPU_MASK_ALL);
+ /* Set our freezer flags */
+ current->flags &= ~(PF_SYNCTHREAD | PF_NOFREEZE);
+ current->flags |= create->freezer_flags;
+
/* OK, tell user we're spawned, wait for stop or wakeup */
__set_current_state(TASK_INTERRUPTIBLE);
complete(&create->started);
@@ -121,6 +126,7 @@ static void keventd_create_kthread(void
struct task_struct *kthread_create(int (*threadfn)(void *data),
void *data,
+ unsigned long freezer_flags,
const char namefmt[],
...)
{
@@ -129,6 +135,7 @@ struct task_struct *kthread_create(int (
create.threadfn = threadfn;
create.data = data;
+ create.freezer_flags = freezer_flags;
init_completion(&create.started);
init_completion(&create.done);
@@ -193,7 +200,7 @@ EXPORT_SYMBOL(kthread_stop);
static __init int helper_init(void)
{
- helper_wq = create_singlethread_workqueue("kthread");
+ helper_wq = create_singlethread_workqueue("kthread", 0);
BUG_ON(!helper_wq);
return 0;
diff -ruNp 210-workthreads.patch-old/kernel/sched.c 210-workthreads.patch-new/kernel/sched.c
--- 210-workthreads.patch-old/kernel/sched.c 2005-04-22 23:32:24.000000000 +1000
+++ 210-workthreads.patch-new/kernel/sched.c 2005-05-02 13:53:32.000000000 +1000
@@ -4379,10 +4379,10 @@ static int migration_call(struct notifie
switch (action) {
case CPU_UP_PREPARE:
- p = kthread_create(migration_thread, hcpu, "migration/%d",cpu);
+ p = kthread_create(migration_thread, hcpu, 0,
+ "migration/%d",cpu);
if (IS_ERR(p))
return NOTIFY_BAD;
- p->flags |= PF_NOFREEZE;
kthread_bind(p, cpu);
/* Must be high prio: stop_machine expects to yield to it. */
rq = task_rq_lock(p, &flags);
diff -ruNp 210-workthreads.patch-old/kernel/softirq.c 210-workthreads.patch-new/kernel/softirq.c
--- 210-workthreads.patch-old/kernel/softirq.c 2005-04-22 23:32:24.000000000 +1000
+++ 210-workthreads.patch-new/kernel/softirq.c 2005-05-02 13:53:32.000000000 +1000
@@ -350,7 +350,6 @@ void __init softirq_init(void)
static int ksoftirqd(void * __bind_cpu)
{
set_user_nice(current, 19);
- current->flags |= PF_NOFREEZE;
set_current_state(TASK_INTERRUPTIBLE);
@@ -364,6 +363,8 @@ static int ksoftirqd(void * __bind_cpu)
__set_current_state(TASK_RUNNING);
+ try_to_freeze(PF_FREEZE);
+
while (local_softirq_pending()) {
/* Preempt disable stops cpu going offline.
If already offline, we'll be on wrong CPU:
@@ -456,7 +457,7 @@ static int __devinit cpu_callback(struct
case CPU_UP_PREPARE:
BUG_ON(per_cpu(tasklet_vec, hotcpu).list);
BUG_ON(per_cpu(tasklet_hi_vec, hotcpu).list);
- p = kthread_create(ksoftirqd, hcpu, "ksoftirqd/%d", hotcpu);
+ p = kthread_create(ksoftirqd, hcpu, PF_NOFREEZE, "ksoftirqd/%d", hotcpu);
if (IS_ERR(p)) {
printk("ksoftirqd for %i failed\n", hotcpu);
return NOTIFY_BAD;
diff -ruNp 210-workthreads.patch-old/kernel/stop_machine.c 210-workthreads.patch-new/kernel/stop_machine.c
--- 210-workthreads.patch-old/kernel/stop_machine.c 2005-04-22 23:32:24.000000000 +1000
+++ 210-workthreads.patch-new/kernel/stop_machine.c 2005-05-02 13:53:32.000000000 +1000
@@ -184,7 +184,7 @@ struct task_struct *__stop_machine_run(i
if (cpu == NR_CPUS)
cpu = _smp_processor_id();
- p = kthread_create(do_stop, &smdata, "kstopmachine");
+ p = kthread_create(do_stop, &smdata, 0, "kstopmachine");
if (!IS_ERR(p)) {
kthread_bind(p, cpu);
wake_up_process(p);
diff -ruNp 210-workthreads.patch-old/kernel/workqueue.c 210-workthreads.patch-new/kernel/workqueue.c
--- 210-workthreads.patch-old/kernel/workqueue.c 2005-04-22 23:32:24.000000000 +1000
+++ 210-workthreads.patch-new/kernel/workqueue.c 2005-05-02 13:53:32.000000000 +1000
@@ -186,8 +186,6 @@ static int worker_thread(void *__cwq)
struct k_sigaction sa;
sigset_t blocked;
- current->flags |= PF_NOFREEZE;
-
set_user_nice(current, -5);
/* Block and flush all signals */
@@ -208,6 +206,7 @@ static int worker_thread(void *__cwq)
schedule();
else
__set_current_state(TASK_RUNNING);
+ try_to_freeze(PF_FREEZE);
remove_wait_queue(&cwq->more_work, &wait);
if (!list_empty(&cwq->worklist))
@@ -277,7 +276,8 @@ void fastcall flush_workqueue(struct wor
}
static struct task_struct *create_workqueue_thread(struct workqueue_struct *wq,
- int cpu)
+ int cpu,
+ unsigned long freezer_flags)
{
struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
struct task_struct *p;
@@ -292,9 +292,11 @@ static struct task_struct *create_workqu
init_waitqueue_head(&cwq->work_done);
if (is_single_threaded(wq))
- p = kthread_create(worker_thread, cwq, "%s", wq->name);
+ p = kthread_create(worker_thread, cwq, freezer_flags,
+ "%s", wq->name);
else
- p = kthread_create(worker_thread, cwq, "%s/%d", wq->name, cpu);
+ p = kthread_create(worker_thread, cwq, freezer_flags,
+ "%s/%d", wq->name, cpu);
if (IS_ERR(p))
return NULL;
cwq->thread = p;
@@ -302,7 +304,8 @@ static struct task_struct *create_workqu
}
struct workqueue_struct *__create_workqueue(const char *name,
- int singlethread)
+ int singlethread,
+ unsigned long freezer_flags)
{
int cpu, destroy = 0;
struct workqueue_struct *wq;
@@ -320,7 +323,7 @@ struct workqueue_struct *__create_workqu
lock_cpu_hotplug();
if (singlethread) {
INIT_LIST_HEAD(&wq->list);
- p = create_workqueue_thread(wq, 0);
+ p = create_workqueue_thread(wq, 0, freezer_flags);
if (!p)
destroy = 1;
else
@@ -330,7 +333,7 @@ struct workqueue_struct *__create_workqu
list_add(&wq->list, &workqueues);
spin_unlock(&workqueue_lock);
for_each_online_cpu(cpu) {
- p = create_workqueue_thread(wq, cpu);
+ p = create_workqueue_thread(wq, cpu, freezer_flags);
if (p) {
kthread_bind(p, cpu);
wake_up_process(p);
@@ -540,7 +543,7 @@ static int __devinit workqueue_cpu_callb
void init_workqueues(void)
{
hotcpu_notifier(workqueue_cpu_callback, 0);
- keventd_wq = create_workqueue("events");
+ keventd_wq = create_workqueue("events", PF_NOFREEZE);
BUG_ON(!keventd_wq);
}
diff -ruNp 210-workthreads.patch-old/mm/pdflush.c 210-workthreads.patch-new/mm/pdflush.c
--- 210-workthreads.patch-old/mm/pdflush.c 2005-02-03 22:33:50.000000000 +1100
+++ 210-workthreads.patch-new/mm/pdflush.c 2005-05-02 13:53:53.000000000 +1000
@@ -213,7 +213,7 @@ int pdflush_operation(void (*fn)(unsigne
static void start_one_pdflush_thread(void)
{
- kthread_run(pdflush, NULL, "pdflush");
+ kthread_run(pdflush, NULL, PF_SYNCTHREAD, "pdflush");
}
static int __init pdflush_init(void)
diff -ruNp 210-workthreads.patch-old/net/sunrpc/sched.c 210-workthreads.patch-new/net/sunrpc/sched.c
--- 210-workthreads.patch-old/net/sunrpc/sched.c 2005-04-22 23:32:26.000000000 +1000
+++ 210-workthreads.patch-new/net/sunrpc/sched.c 2005-05-02 13:53:32.000000000 +1000
@@ -1003,7 +1003,7 @@ rpciod_up(void)
* Create the rpciod thread and wait for it to start.
*/
error = -ENOMEM;
- wq = create_workqueue("rpciod");
+ wq = create_workqueue("rpciod", 0);
if (wq == NULL) {
printk(KERN_WARNING "rpciod_up: create workqueue failed, error=%d\n", error);
rpciod_users--;
[-- Attachment #3: 301-refrigerator.patch --]
[-- Type: text/x-patch, Size: 12695 bytes --]
diff -ruNp 211-refrigerator.patch-old/include/linux/sched.h 211-refrigerator.patch-new/include/linux/sched.h
--- 211-refrigerator.patch-old/include/linux/sched.h 2005-04-22 23:32:23.000000000 +1000
+++ 211-refrigerator.patch-new/include/linux/sched.h 2005-05-02 16:53:47.000000000 +1000
@@ -1248,6 +1248,7 @@ extern void normalize_rt_tasks(void);
extern void refrigerator(unsigned long);
extern int freeze_processes(void);
extern void thaw_processes(void);
+extern unsigned int refrigerator_on;
static inline int try_to_freeze(unsigned long refrigerator_flags)
{
@@ -1261,6 +1262,7 @@ static inline int try_to_freeze(unsigned
static inline void refrigerator(unsigned long flag) {}
static inline int freeze_processes(void) { BUG(); return 0; }
static inline void thaw_processes(void) {}
+#define refrigerator_on (0)
static inline int try_to_freeze(unsigned long refrigerator_flags)
{
diff -ruNp 211-refrigerator.patch-old/kernel/exit.c 211-refrigerator.patch-new/kernel/exit.c
--- 211-refrigerator.patch-old/kernel/exit.c 2005-05-02 16:53:40.000000000 +1000
+++ 211-refrigerator.patch-new/kernel/exit.c 2005-05-02 16:13:38.000000000 +1000
@@ -789,6 +789,8 @@ fastcall NORET_TYPE void do_exit(long co
panic("Attempted to kill init!");
if (tsk->io_context)
exit_io_context();
+ if (unlikely(refrigerator_on))
+ refrigerator(0);
if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
current->ptrace_message = code;
diff -ruNp 211-refrigerator.patch-old/kernel/fork.c 211-refrigerator.patch-new/kernel/fork.c
--- 211-refrigerator.patch-old/kernel/fork.c 2005-04-22 23:32:24.000000000 +1000
+++ 211-refrigerator.patch-new/kernel/fork.c 2005-05-02 16:13:38.000000000 +1000
@@ -1200,6 +1200,9 @@ long do_fork(unsigned long clone_flags,
int trace = 0;
long pid = alloc_pidmap();
+ if (unlikely(refrigerator_on))
+ refrigerator(0);
+
if (pid < 0)
return -EAGAIN;
if (unlikely(current->ptrace)) {
diff -ruNp 211-refrigerator.patch-old/kernel/kmod.c 211-refrigerator.patch-new/kernel/kmod.c
--- 211-refrigerator.patch-old/kernel/kmod.c 2005-05-02 16:53:40.000000000 +1000
+++ 211-refrigerator.patch-new/kernel/kmod.c 2005-05-02 16:13:38.000000000 +1000
@@ -237,7 +237,7 @@ int call_usermodehelper(char *path, char
};
DECLARE_WORK(work, __call_usermodehelper, &sub_info);
- if (!khelper_wq)
+ if ((!khelper_wq) || (refrigerator_on))
return -EBUSY;
if (path[0] == '\0')
diff -ruNp 211-refrigerator.patch-old/kernel/power/process.c 211-refrigerator.patch-new/kernel/power/process.c
--- 211-refrigerator.patch-old/kernel/power/process.c 2004-12-10 14:26:31.000000000 +1100
+++ 211-refrigerator.patch-new/kernel/power/process.c 2005-05-02 16:49:35.000000000 +1000
@@ -1,121 +1,317 @@
/*
- * drivers/power/process.c - Functions for starting/stopping processes on
- * suspend transitions.
+ * kernel/power/process.c
*
- * Originally from swsusp.
+ * Copyright (C) 1998-2001 Gabor Kuti <seasons@fornax.hu>
+ * Copyright (C) 1998,2001,2002 Pavel Machek <pavel@suse.cz>
+ * Copyright (C) 2002-2003 Florent Chabaud <fchabaud@free.fr>
+ * Copyright (C) 2002-2005 Nigel Cunningham <nigel@suspend2.net>
+ *
+ * This file is released under the GPLv2.
+ *
+ * Freeze_and_free contains the routines software suspend uses to freeze other
+ * processes during the suspend cycle.
+ *
+ * Under high I/O load, we need to be careful about the order in which we
+ * freeze processes. If we freeze processes in the wrong order, we could
+ * deadlock others. The freeze_order array this specifies the order in which
+ * critical processes are frozen. All others are suspended after these have
+ * entered the refrigerator.
+ *
+ * Other processes on an SMP system have been taken care of already when we
+ * use these routines. We assume there are no races or locking issues.
*/
+#include <linux/module.h>
+//#include <linux/suspend.h>
+#include <asm/tlbflush.h>
+#include <linux/sched.h>
+
+unsigned int refrigerator_on = 0;
-#undef DEBUG
+static unsigned int sync_freeze = 0;
-#include <linux/smp_lock.h>
-#include <linux/interrupt.h>
-#include <linux/suspend.h>
-#include <linux/module.h>
+atomic_t __nosavedata suspend_cpu_counter = { 0 };
-/*
- * Timeout for stopping processes
- */
-#define TIMEOUT (6 * HZ)
+/* Timeouts when freezing */
+#define FREEZER_TOTAL_TIMEOUT (5 * HZ)
+#define FREEZER_CHECK_TIMEOUT (HZ / 10)
+/**
+ * refrigerator - idle routine for frozen processes
+ * @flag: unsigned long, non zero if signals to be flushed.
+ *
+ * A routine for threads which should not do work during suspend
+ * to enter and spin in until the process is finished.
+ */
-static inline int freezeable(struct task_struct * p)
+void refrigerator(unsigned long flag)
{
- if ((p == current) ||
+ unsigned long flags;
+ long save;
+
+ if (unlikely(current->flags & PF_NOFREEZE)) {
+ current->flags &= ~PF_FREEZE;
+ spin_lock_irqsave(¤t->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(¤t->sighand->siglock, flags);
+ return;
+ }
+
+ /* You need correct to work with real-time processes.
+ OTOH, this way one process may see (via /proc/) some other
+ process in stopped state (and thereby discovered we were
+ suspended. We probably do not care).
+ */
+ if ((flag) && (current->flags & PF_FREEZE)) {
+
+ spin_lock_irqsave(¤t->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(¤t->sighand->siglock, flags);
+ }
+
+ if (refrigerator_on) {
+ save = current->state;
+ current->flags |= PF_FROZEN;
+ while (current->flags & PF_FROZEN) {
+ current->state = TASK_STOPPED;
+ schedule();
+ if (flag) {
+ spin_lock_irqsave(
+ ¤t->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(
+ ¤t->sighand->siglock, flags);
+ }
+ }
+ current->state = save;
+ }
+ current->flags &= ~PF_FREEZE;
+ spin_lock_irqsave(¤t->sighand->siglock, flags);
+ recalc_sigpending();
+ spin_unlock_irqrestore(¤t->sighand->siglock, flags);
+}
+
+/*
+ * to_be_frozen
+ *
+ * Description: Determine whether a process should be frozen yet.
+ * Parameters: struct task_struct * The process to consider.
+ * int Which group of processes to consider.
+ * Returns: int 0 if don't freeze yet, otherwise do.
+ */
+static int to_be_frozen(struct task_struct * p, int type_being_frozen) {
+
+ if ((p == current) ||
(p->flags & PF_NOFREEZE) ||
(p->exit_state == EXIT_ZOMBIE) ||
(p->exit_state == EXIT_DEAD) ||
(p->state == TASK_STOPPED) ||
(p->state == TASK_TRACED))
return 0;
+ if ((!(p->mm)) && (type_being_frozen < 3))
+ return 0;
+ if ((p->flags & PF_SYNCTHREAD) && (type_being_frozen == 1))
+ return 0;
+ if ((p->state == TASK_UNINTERRUPTIBLE) && (type_being_frozen == 3))
+ return 0;
return 1;
}
-/* Refrigerator is place where frozen processes are stored :-). */
-void refrigerator(unsigned long flag)
-{
- /* Hmm, should we be allowed to suspend when there are realtime
- processes around? */
- long save;
- save = current->state;
- current->state = TASK_UNINTERRUPTIBLE;
- pr_debug("%s entered refrigerator\n", current->comm);
- printk("=");
- current->flags &= ~PF_FREEZE;
+/*
+ * num_to_be_frozen
+ *
+ * Description: Determine how many processes of our type are still to be
+ * frozen. As a side effect, update the progress bar too.
+ * Parameters: int Which type we are trying to freeze.
+ */
+static int num_to_be_frozen(int type_being_frozen) {
+
+ struct task_struct *p, *g;
+ int todo_this_type = 0, total_todo = 0;
+ int total_threads = 0;
+
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ if (to_be_frozen(p, type_being_frozen)) {
+ todo_this_type++;
+ total_todo++;
+ } else if (to_be_frozen(p, 3))
+ total_todo++;
+ total_threads++;
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
- spin_lock_irq(¤t->sighand->siglock);
- recalc_sigpending(); /* We sent fake signal, clean it up */
- spin_unlock_irq(¤t->sighand->siglock);
-
- current->flags |= PF_FROZEN;
- while (current->flags & PF_FROZEN)
- schedule();
- pr_debug("%s left refrigerator\n", current->comm);
- current->state = save;
+ return todo_this_type;
}
-/* 0 = success, else # of processes that we failed to stop */
-int freeze_processes(void)
+/*
+ * freeze_threads
+ *
+ * Freeze a set of threads.
+ *
+ * Types:
+ * 1: User threads not syncing.
+ * 2: Remaining user threads.
+ * 3: Kernel threads.
+ */
+
+static int freeze_threads(int type)
{
- int todo;
- unsigned long start_time;
- struct task_struct *g, *p;
-
- printk( "Stopping tasks: " );
- start_time = jiffies;
+ struct task_struct *p, *g;
+ unsigned long start_time = jiffies;
+ int result = 0, still_to_do;
+
do {
- todo = 0;
+ int numsignalled = 0;
+
+ preempt_disable();
+
+ local_irq_disable();
+
read_lock(&tasklist_lock);
+
+ /*
+ * Signal the processes.
+ *
+ * We signal them every time through. Otherwise pdflush -
+ * and maybe other processes - might never enter the
+ * fridge.
+ *
+ * NB: We're inside an SMP pause. Our printks are unsafe.
+ * They're only here for debugging.
+ *
+ */
+
do_each_thread(g, p) {
unsigned long flags;
- if (!freezeable(p))
- continue;
- if ((p->flags & PF_FROZEN) ||
- (p->state == TASK_TRACED) ||
- (p->state == TASK_STOPPED))
+ if (!to_be_frozen(p, type))
continue;
-
- /* FIXME: smp problem here: we may not access other process' flags
- without locking */
+
+ numsignalled++;
p->flags |= PF_FREEZE;
spin_lock_irqsave(&p->sighand->siglock, flags);
signal_wake_up(p, 0);
spin_unlock_irqrestore(&p->sighand->siglock, flags);
- todo++;
} while_each_thread(g, p);
+
read_unlock(&tasklist_lock);
- yield(); /* Yield is okay here */
- if (time_after(jiffies, start_time + TIMEOUT)) {
- printk( "\n" );
- printk(KERN_ERR " stopping tasks failed (%d tasks remaining)\n", todo );
- return todo;
- }
- } while(todo);
+
+ preempt_enable();
+
+ local_irq_enable();
+
+ /*
+ * Sleep.
+ */
+ set_task_state(current, TASK_INTERRUPTIBLE);
+ schedule_timeout(FREEZER_CHECK_TIMEOUT);
+
+ still_to_do = num_to_be_frozen(type);
+ } while(still_to_do && !time_after(jiffies, start_time + FREEZER_TOTAL_TIMEOUT));
+
+ /*
+ * Did we time out? See if we failed to freeze processes as well.
+ *
+ */
+ if ((time_after(jiffies, start_time + FREEZER_TOTAL_TIMEOUT)) && (still_to_do)) {
+ read_lock(&tasklist_lock);
+ do_each_thread(g, p) {
+ if (!to_be_frozen(p, type))
+ continue;
+
+ if (!result) {
+ printk(KERN_ERR "Stopping tasks failed.\n");
+ printk(KERN_ERR "Tasks that refused to be "
+ "refrigerated and haven't since exited:\n");
+ result = 1;
+ }
+
+ if (p->flags & PF_FREEZE) {
+ printk(" - %s (#%d) signalled but "
+ "didn't enter refrigerator.\n",
+ p->comm, p->pid);
+ } else
+ printk(" - %s (#%d) wasn't "
+ "signalled.\n",
+ p->comm, p->pid);
+ } while_each_thread(g, p);
+ read_unlock(&tasklist_lock);
+
+ show_state();
+ }
+
+ return result;
+}
+
+/*
+ * freeze_processes - Freeze processes prior to saving an image of memory.
+ *
+ * Return value: 0 = success, else # of processes that we failed to stop.
+ */
+extern asmlinkage long sys_sync(void);
+
+/* Freeze_processes.
+ * Debugging output is still printed.
+ */
+int freeze_processes(void)
+{
+ int showidlelist, result = 0;
+
+ showidlelist = 1;
+
+ refrigerator_on = 1;
+
+ /* First, freeze all userspace, non syncing threads. */
+ if (freeze_threads(1))
+ goto aborting;
- printk( "|\n" );
- BUG_ON(in_atomic());
- return 0;
+ /* Now freeze processes that were syncing and are still running */
+ if (freeze_threads(2))
+ goto aborting;
+
+ /* Now do our own sync, just in case one wasn't running already */
+ sys_sync();
+
+ sync_freeze = 1;
+
+ /* Freeze kernel threads */
+ if (freeze_threads(3))
+ goto aborting;
+
+out:
+ return result;
+
+aborting:
+ result = -1;
+ thaw_processes();
+ goto out;
}
void thaw_processes(void)
{
- struct task_struct *g, *p;
+ struct task_struct *p, *g;
+
+ sync_freeze = 0;
+ refrigerator_on = 0;
+
+ preempt_disable();
+
+ local_irq_disable();
- printk( "Restarting tasks..." );
read_lock(&tasklist_lock);
+
do_each_thread(g, p) {
- if (!freezeable(p))
- continue;
if (p->flags & PF_FROZEN) {
p->flags &= ~PF_FROZEN;
wake_up_process(p);
- } else
- printk(KERN_INFO " Strange, %s not stopped\n", p->comm );
+ }
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
- schedule();
- printk( " done\n" );
+
+ preempt_enable();
+
+ local_irq_enable();
}
EXPORT_SYMBOL(refrigerator);
[-- Attachment #4: 304-syncthreads --]
[-- Type: text/x-patch, Size: 9093 bytes --]
diff -ruNp 214-syncthreads-old/fs/buffer.c 214-syncthreads-new/fs/buffer.c
--- 214-syncthreads-old/fs/buffer.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/buffer.c 2005-05-02 14:50:03.000000000 +1000
@@ -171,6 +171,10 @@ EXPORT_SYMBOL(sync_blockdev);
*/
int fsync_super(struct super_block *sb)
{
+ int ret;
+
+ current->flags |= PF_SYNCTHREAD;
+
sync_inodes_sb(sb, 0);
DQUOT_SYNC(sb);
lock_super(sb);
@@ -182,7 +186,10 @@ int fsync_super(struct super_block *sb)
sync_blockdev(sb->s_bdev);
sync_inodes_sb(sb, 1);
- return sync_blockdev(sb->s_bdev);
+ ret = sync_blockdev(sb->s_bdev);
+
+ current->flags &= ~PF_SYNCTHREAD;
+ return ret;
}
/*
@@ -193,12 +200,19 @@ int fsync_super(struct super_block *sb)
int fsync_bdev(struct block_device *bdev)
{
struct super_block *sb = get_super(bdev);
+ int ret;
+
+ current->flags |= PF_SYNCTHREAD;
+
if (sb) {
int res = fsync_super(sb);
drop_super(sb);
+ current->flags &= ~PF_SYNCTHREAD;
return res;
}
- return sync_blockdev(bdev);
+ ret = sync_blockdev(bdev);
+ current->flags &= ~PF_SYNCTHREAD;
+ return ret;
}
/**
@@ -278,6 +292,8 @@ EXPORT_SYMBOL(thaw_bdev);
*/
static void do_sync(unsigned long wait)
{
+ current->flags |= PF_SYNCTHREAD;
+
wakeup_bdflush(0);
sync_inodes(0); /* All mappings, inodes and their blockdevs */
DQUOT_SYNC(NULL);
@@ -289,6 +305,8 @@ static void do_sync(unsigned long wait)
printk("Emergency Sync complete\n");
if (unlikely(laptop_mode))
laptop_sync_completion();
+
+ current->flags &= ~PF_SYNCTHREAD;
}
asmlinkage long sys_sync(void)
@@ -314,6 +332,8 @@ int file_fsync(struct file *filp, struct
struct super_block * sb;
int ret, err;
+ current->flags |= PF_SYNCTHREAD;
+
/* sync the inode to buffers */
ret = write_inode_now(inode, 0);
@@ -328,6 +348,8 @@ int file_fsync(struct file *filp, struct
err = sync_blockdev(sb->s_bdev);
if (!ret)
ret = err;
+
+ current->flags &= ~PF_SYNCTHREAD;
return ret;
}
@@ -337,6 +359,8 @@ asmlinkage long sys_fsync(unsigned int f
struct address_space *mapping;
int ret, err;
+ current->flags |= PF_SYNCTHREAD;
+
ret = -EBADF;
file = fget(fd);
if (!file)
@@ -370,6 +394,7 @@ asmlinkage long sys_fsync(unsigned int f
out_putf:
fput(file);
out:
+ current->flags &= ~PF_SYNCTHREAD;
return ret;
}
@@ -379,6 +404,8 @@ asmlinkage long sys_fdatasync(unsigned i
struct address_space *mapping;
int ret, err;
+ current->flags |= PF_SYNCTHREAD;
+
ret = -EBADF;
file = fget(fd);
if (!file)
@@ -405,6 +432,7 @@ asmlinkage long sys_fdatasync(unsigned i
out_putf:
fput(file);
out:
+ current->flags &= ~PF_SYNCTHREAD;
return ret;
}
diff -ruNp 214-syncthreads-old/fs/jbd/journal.c 214-syncthreads-new/fs/jbd/journal.c
--- 214-syncthreads-old/fs/jbd/journal.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/jbd/journal.c 2005-05-02 14:50:03.000000000 +1000
@@ -130,6 +130,7 @@ int kjournald(void *arg)
current_journal = journal;
daemonize("kjournald");
+ current->flags |= PF_SYNCTHREAD;
/* Set up an interval timer which can be used to trigger a
commit wakeup after the commit interval expires */
diff -ruNp 214-syncthreads-old/fs/jffs/intrep.c 214-syncthreads-new/fs/jffs/intrep.c
--- 214-syncthreads-old/fs/jffs/intrep.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/jffs/intrep.c 2005-05-02 14:50:03.000000000 +1000
@@ -3364,6 +3364,7 @@ jffs_garbage_collect_thread(void *ptr)
D1(int i = 1);
daemonize("jffs_gcd");
+ current->flags |= PF_SYNCTHREAD;
c->gc_task = current;
@@ -3399,6 +3400,9 @@ jffs_garbage_collect_thread(void *ptr)
siginfo_t info;
unsigned long signr = 0;
+ if (try_to_freeze(PF_FREEZE))
+ continue;
+
spin_lock_irq(¤t->sighand->siglock);
signr = dequeue_signal(current, ¤t->blocked, &info);
spin_unlock_irq(¤t->sighand->siglock);
diff -ruNp 214-syncthreads-old/fs/jfs/jfs_logmgr.c 214-syncthreads-new/fs/jfs/jfs_logmgr.c
--- 214-syncthreads-old/fs/jfs/jfs_logmgr.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/jfs/jfs_logmgr.c 2005-05-02 14:50:03.000000000 +1000
@@ -2321,6 +2321,7 @@ int jfsIOWait(void *arg)
struct lbuf *bp;
daemonize("jfsIO");
+ current->flags |= PF_SYNCTHREAD;
complete(&jfsIOwait);
diff -ruNp 214-syncthreads-old/fs/jfs/jfs_txnmgr.c 214-syncthreads-new/fs/jfs/jfs_txnmgr.c
--- 214-syncthreads-old/fs/jfs/jfs_txnmgr.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/jfs/jfs_txnmgr.c 2005-05-02 14:50:03.000000000 +1000
@@ -47,7 +47,6 @@
#include <linux/vmalloc.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
-#include <linux/suspend.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include "jfs_incore.h"
@@ -2750,6 +2749,7 @@ int jfs_lazycommit(void *arg)
struct jfs_sb_info *sbi;
daemonize("jfsCommit");
+ current->flags |= PF_SYNCTHREAD;
complete(&jfsIOwait);
diff -ruNp 214-syncthreads-old/fs/lockd/clntlock.c 214-syncthreads-new/fs/lockd/clntlock.c
--- 214-syncthreads-old/fs/lockd/clntlock.c 2004-11-03 21:55:00.000000000 +1100
+++ 214-syncthreads-new/fs/lockd/clntlock.c 2005-05-02 14:50:03.000000000 +1000
@@ -200,6 +200,7 @@ reclaimer(void *ptr)
struct inode *inode;
daemonize("%s-reclaim", host->h_name);
+ current->flags |= PF_SYNCTHREAD;
allow_signal(SIGKILL);
/* This one ensures that our parent doesn't terminate while the
@@ -222,6 +223,7 @@ restart:
fl->fl_u.nfs_fl.flags &= ~NFS_LCK_RECLAIM;
nlmclnt_reclaim(host, fl);
+ try_to_freeze(PF_FREEZE);
if (signalled())
break;
goto restart;
diff -ruNp 214-syncthreads-old/fs/lockd/svc.c 214-syncthreads-new/fs/lockd/svc.c
--- 214-syncthreads-old/fs/lockd/svc.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/lockd/svc.c 2005-05-02 14:50:03.000000000 +1000
@@ -115,6 +115,7 @@ lockd(struct svc_rqst *rqstp)
up(&lockd_start);
daemonize("lockd");
+ current->flags |= PF_SYNCTHREAD;
/* Process request with signals blocked, but allow SIGKILL. */
allow_signal(SIGKILL);
@@ -138,6 +139,8 @@ lockd(struct svc_rqst *rqstp)
while ((nlmsvc_users || !signalled()) && nlmsvc_pid == current->pid) {
long timeout = MAX_SCHEDULE_TIMEOUT;
+ try_to_freeze(PF_SYNCTHREAD);
+
if (signalled()) {
flush_signals(current);
if (nlmsvc_ops) {
diff -ruNp 214-syncthreads-old/fs/nfsd/nfssvc.c 214-syncthreads-new/fs/nfsd/nfssvc.c
--- 214-syncthreads-old/fs/nfsd/nfssvc.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/nfsd/nfssvc.c 2005-05-02 14:50:03.000000000 +1000
@@ -182,6 +182,7 @@ nfsd(struct svc_rqst *rqstp)
/* Lock module and set up kernel thread */
lock_kernel();
daemonize("nfsd");
+ current->flags |= PF_SYNCTHREAD;
/* After daemonize() this kernel thread shares current->fs
* with the init process. We need to create files with a
diff -ruNp 214-syncthreads-old/fs/xfs/linux-2.6/xfs_buf.c 214-syncthreads-new/fs/xfs/linux-2.6/xfs_buf.c
--- 214-syncthreads-old/fs/xfs/linux-2.6/xfs_buf.c 2005-05-02 15:39:36.000000000 +1000
+++ 214-syncthreads-new/fs/xfs/linux-2.6/xfs_buf.c 2005-05-02 14:50:03.000000000 +1000
@@ -1770,7 +1770,7 @@ pagebuf_daemon(
/* Set up the thread */
daemonize("xfsbufd");
- current->flags |= PF_MEMALLOC;
+ current->flags |= PF_MEMALLOC | PF_SYNCTHREAD;
pagebuf_daemon_task = current;
pagebuf_daemon_active = 1;
diff -ruNp 214-syncthreads-old/fs/xfs/linux-2.6/xfs_super.c 214-syncthreads-new/fs/xfs/linux-2.6/xfs_super.c
--- 214-syncthreads-old/fs/xfs/linux-2.6/xfs_super.c 2005-04-22 23:32:19.000000000 +1000
+++ 214-syncthreads-new/fs/xfs/linux-2.6/xfs_super.c 2005-05-02 14:50:03.000000000 +1000
@@ -471,6 +471,7 @@ xfssyncd(
struct vfs_sync_work *work, *n;
daemonize("xfssyncd");
+ current->flags |= PF_SYNCTHREAD;
vfsp->vfs_sync_work.w_vfs = vfsp;
vfsp->vfs_sync_work.w_syncer = vfs_sync_worker;
diff -ruNp 214-syncthreads-old/include/linux/sched.h 214-syncthreads-new/include/linux/sched.h
--- 214-syncthreads-old/include/linux/sched.h 2005-05-02 15:39:37.000000000 +1000
+++ 214-syncthreads-new/include/linux/sched.h 2005-05-02 15:19:04.000000000 +1000
@@ -788,6 +788,8 @@ do { if (atomic_dec_and_test(&(tsk)->usa
#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */
#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */
#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */
+#define PF_SYNCTHREAD 0x01000000 /* this thread can start activity during the
++ early part of freezing processes */
/*
* Only the _current_ task can read/write to tsk->flags, but other
diff -ruNp 214-syncthreads-old/mm/pdflush.c 214-syncthreads-new/mm/pdflush.c
--- 214-syncthreads-old/mm/pdflush.c 2005-05-02 15:39:37.000000000 +1000
+++ 214-syncthreads-new/mm/pdflush.c 2005-05-02 14:50:03.000000000 +1000
@@ -89,7 +89,7 @@ struct pdflush_work {
static int __pdflush(struct pdflush_work *my_work)
{
- current->flags |= PF_FLUSHER;
+ current->flags |= (PF_FLUSHER | PF_SYNCTHREAD);
my_work->fn = NULL;
my_work->who = current;
INIT_LIST_HEAD(&my_work->list);
^ permalink raw reply [flat|nested] 20+ messages in thread* Re: Freezer Patches.
2005-06-01 12:33 Freezer Patches Nigel Cunningham
@ 2005-06-01 13:02 ` Pavel Machek
2005-06-01 22:02 ` Benjamin Herrenschmidt
2005-06-01 22:08 ` Nigel Cunningham
0 siblings, 2 replies; 20+ messages in thread
From: Pavel Machek @ 2005-06-01 13:02 UTC (permalink / raw)
To: Nigel Cunningham
Cc: Pavel Machek, Linux Kernel Mailing List, Benjamin Herrenschmidt
Hi!
> Here are the freezer patches. They were prepared against rc3, but I
> think they still apply fine against rc5. (Ben, these are the same ones I
> sent you the other day).
304 seems ugly and completely useless for mainline
300: stopping softirqd seems dangerous to me... are you sure?
301: patching exit should not be neccessary. Why do you need it?
Pavel
--
64 bytes from 195.113.31.123: icmp_seq=28 ttl=51 time=448769.1 ms
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 13:02 ` Pavel Machek
@ 2005-06-01 22:02 ` Benjamin Herrenschmidt
2005-06-01 22:13 ` Nigel Cunningham
2005-06-01 22:08 ` Nigel Cunningham
1 sibling, 1 reply; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-01 22:02 UTC (permalink / raw)
To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List
On Wed, 2005-06-01 at 15:02 +0200, Pavel Machek wrote:
> Hi!
>
> > Here are the freezer patches. They were prepared against rc3, but I
> > think they still apply fine against rc5. (Ben, these are the same ones I
> > sent you the other day).
> 300: stopping softirqd seems dangerous to me... are you sure?
That sounds bogus indeed.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 22:02 ` Benjamin Herrenschmidt
@ 2005-06-01 22:13 ` Nigel Cunningham
2005-06-01 22:23 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-01 22:13 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Pavel Machek, Linux Kernel Mailing List
Hi.
On Thu, 2005-06-02 at 08:02, Benjamin Herrenschmidt wrote:
> On Wed, 2005-06-01 at 15:02 +0200, Pavel Machek wrote:
> > Hi!
> >
> > > Here are the freezer patches. They were prepared against rc3, but I
> > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > sent you the other day).
>
> > 300: stopping softirqd seems dangerous to me... are you sure?
>
> That sounds bogus indeed.
Ok. Bogus but harmless. I'll try removing it.
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 22:13 ` Nigel Cunningham
@ 2005-06-01 22:23 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-01 22:23 UTC (permalink / raw)
To: ncunningham; +Cc: Pavel Machek, Linux Kernel Mailing List
On Thu, 2005-06-02 at 08:13 +1000, Nigel Cunningham wrote:
> Hi.
>
> On Thu, 2005-06-02 at 08:02, Benjamin Herrenschmidt wrote:
> > On Wed, 2005-06-01 at 15:02 +0200, Pavel Machek wrote:
> > > Hi!
> > >
> > > > Here are the freezer patches. They were prepared against rc3, but I
> > > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > > sent you the other day).
> >
> > > 300: stopping softirqd seems dangerous to me... are you sure?
> >
> > That sounds bogus indeed.
>
> Ok. Bogus but harmless. I'll try removing it.
Not really harmless, you happen to be lucky :)
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 13:02 ` Pavel Machek
2005-06-01 22:02 ` Benjamin Herrenschmidt
@ 2005-06-01 22:08 ` Nigel Cunningham
2005-06-01 22:31 ` Pavel Machek
1 sibling, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-01 22:08 UTC (permalink / raw)
To: Pavel Machek; +Cc: Linux Kernel Mailing List, Benjamin Herrenschmidt
Morning.
On Wed, 2005-06-01 at 23:02, Pavel Machek wrote:
> Hi!
>
> > Here are the freezer patches. They were prepared against rc3, but I
> > think they still apply fine against rc5. (Ben, these are the same ones I
> > sent you the other day).
>
> 304 seems ugly and completely useless for mainline
That's because you don't understand what it's doing.
The new refrigerator implementation works like this:
Userspace processes that begin a sys_*sync gain the process flag
PF_SYNCTHREAD for the duration of their syscall.
We then freeze processes in three distinct groups.
1. Userspace processes (p->mm) that don't have PF_SYNCTHREAD set are
signalled first. This causes them to enter the refrigerator, thereby
stopping them from submitting further I/O that could cause the syncing
threads to potentially spin for ever.
2. Syncing threads are signalled so that when they finish syncing (if
they haven't already), they also enter the refrigerator. Any processes
that were in group 2 but are now in group 1 are also signalled.
It is possible that no process was syncing data. We thus now call
sys_sync ourselves, to flush remaining dirty data to disk.
3. Kernel threads not needed during suspend (kjournald, eg) are frozen.
> 300: stopping softirqd seems dangerous to me... are you sure?
It's been that way for ages without any reports of deadlocks. I'm happy
to change it if it really was dangerous for some reason.
> 301: patching exit should not be neccessary. Why do you need it?
Maybe you're right. I think it's a left over from the old
implementation. I'll try removing the call and see how the freezer
survives some stress testing.
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 22:08 ` Nigel Cunningham
@ 2005-06-01 22:31 ` Pavel Machek
2005-06-01 22:45 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 20+ messages in thread
From: Pavel Machek @ 2005-06-01 22:31 UTC (permalink / raw)
To: Nigel Cunningham; +Cc: Linux Kernel Mailing List, Benjamin Herrenschmidt
Hi!
(Well, it is just after midnight here :-).
> > > Here are the freezer patches. They were prepared against rc3, but I
> > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > sent you the other day).
> >
> > 304 seems ugly and completely useless for mainline
>
> That's because you don't understand what it's doing.
>
> The new refrigerator implementation works like this:
>
> Userspace processes that begin a sys_*sync gain the process flag
> PF_SYNCTHREAD for the duration of their syscall.
swsusp1 should not need any special casing of sync, right? We can
simply do sys_sync(), then freeze, or something like that. We could
even remove sys_sync() completely; it is not needed for correctness.
Pavel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 22:31 ` Pavel Machek
@ 2005-06-01 22:45 ` Benjamin Herrenschmidt
2005-06-01 23:02 ` Pavel Machek
0 siblings, 1 reply; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-01 22:45 UTC (permalink / raw)
To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List
On Thu, 2005-06-02 at 00:31 +0200, Pavel Machek wrote:
> Hi!
>
> (Well, it is just after midnight here :-).
>
> > > > Here are the freezer patches. They were prepared against rc3, but I
> > > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > > sent you the other day).
> > >
> > > 304 seems ugly and completely useless for mainline
> >
> > That's because you don't understand what it's doing.
> >
> > The new refrigerator implementation works like this:
> >
> > Userspace processes that begin a sys_*sync gain the process flag
> > PF_SYNCTHREAD for the duration of their syscall.
>
> swsusp1 should not need any special casing of sync, right? We can
> simply do sys_sync(), then freeze, or something like that. We could
> even remove sys_sync() completely; it is not needed for correctness.
It's still quite nice to have ... I put it in my pre-freeze callback in
fact for both STR and STD :) We really want it for STD but I think it
doesn't work properly after freeze.
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 22:45 ` Benjamin Herrenschmidt
@ 2005-06-01 23:02 ` Pavel Machek
2005-06-02 0:35 ` Benjamin Herrenschmidt
2005-06-02 1:45 ` Nigel Cunningham
0 siblings, 2 replies; 20+ messages in thread
From: Pavel Machek @ 2005-06-01 23:02 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Nigel Cunningham, Linux Kernel Mailing List
On Čt 02-06-05 08:45:33, Benjamin Herrenschmidt wrote:
> On Thu, 2005-06-02 at 00:31 +0200, Pavel Machek wrote:
> > Hi!
> >
> > (Well, it is just after midnight here :-).
> >
> > > > > Here are the freezer patches. They were prepared against rc3, but I
> > > > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > > > sent you the other day).
> > > >
> > > > 304 seems ugly and completely useless for mainline
> > >
> > > That's because you don't understand what it's doing.
> > >
> > > The new refrigerator implementation works like this:
> > >
> > > Userspace processes that begin a sys_*sync gain the process flag
> > > PF_SYNCTHREAD for the duration of their syscall.
> >
> > swsusp1 should not need any special casing of sync, right? We can
> > simply do sys_sync(), then freeze, or something like that. We could
> > even remove sys_sync() completely; it is not needed for correctness.
>
> It's still quite nice to have ... I put it in my pre-freeze callback in
> fact for both STR and STD :) We really want it for STD but I think it
> doesn't work properly after freeze.
I agree that sync() is nice to have, but I'm not going to slow down
fork/exit for it. And besides, sys_sync() just before suspend works
just fine.
Pavel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 23:02 ` Pavel Machek
@ 2005-06-02 0:35 ` Benjamin Herrenschmidt
2005-06-02 1:46 ` Nigel Cunningham
2005-06-02 1:45 ` Nigel Cunningham
1 sibling, 1 reply; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-02 0:35 UTC (permalink / raw)
To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List
> I agree that sync() is nice to have, but I'm not going to slow down
> fork/exit for it. And besides, sys_sync() just before suspend works
> just fine.
Yes, that's why I put it in my pre-freeze :)
I'll see about making my pre/post freeze stuff (APM emu + sync basically
now) generic to avoid the callbacks.
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 0:35 ` Benjamin Herrenschmidt
@ 2005-06-02 1:46 ` Nigel Cunningham
2005-06-02 1:49 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-02 1:46 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Pavel Machek, Linux Kernel Mailing List
Hi.
On Thu, 2005-06-02 at 10:35, Benjamin Herrenschmidt wrote:
> > I agree that sync() is nice to have, but I'm not going to slow down
> > fork/exit for it. And besides, sys_sync() just before suspend works
> > just fine.
>
> Yes, that's why I put it in my pre-freeze :)
>
> I'll see about making my pre/post freeze stuff (APM emu + sync basically
> now) generic to avoid the callbacks.
Ummm. Don't do it if kthreads are already frozen. You'll deadlock against kjournald.
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 1:46 ` Nigel Cunningham
@ 2005-06-02 1:49 ` Benjamin Herrenschmidt
0 siblings, 0 replies; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-02 1:49 UTC (permalink / raw)
To: ncunningham; +Cc: Pavel Machek, Linux Kernel Mailing List
On Thu, 2005-06-02 at 11:46 +1000, Nigel Cunningham wrote:
> Hi.
>
> On Thu, 2005-06-02 at 10:35, Benjamin Herrenschmidt wrote:
> > > I agree that sync() is nice to have, but I'm not going to slow down
> > > fork/exit for it. And besides, sys_sync() just before suspend works
> > > just fine.
> >
> > Yes, that's why I put it in my pre-freeze :)
> >
> > I'll see about making my pre/post freeze stuff (APM emu + sync basically
> > now) generic to avoid the callbacks.
>
> Ummm. Don't do it if kthreads are already frozen. You'll deadlock against kjournald.
Which is why I do it pre-freeze.
With a 2 stage freezing though, it would make sense to first freeze
userland, then sync, then freeze kthreads. That would make the sync
faster (as it won't be "blocked" by pending userland IOs as I experience
regulary here) and more reliable.
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-01 23:02 ` Pavel Machek
2005-06-02 0:35 ` Benjamin Herrenschmidt
@ 2005-06-02 1:45 ` Nigel Cunningham
2005-06-02 1:48 ` Benjamin Herrenschmidt
2005-06-02 7:14 ` Pavel Machek
1 sibling, 2 replies; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-02 1:45 UTC (permalink / raw)
To: Pavel Machek; +Cc: Benjamin Herrenschmidt, Linux Kernel Mailing List
Hi.
On Thu, 2005-06-02 at 09:02, Pavel Machek wrote:
> On Čt 02-06-05 08:45:33, Benjamin Herrenschmidt wrote:
> > On Thu, 2005-06-02 at 00:31 +0200, Pavel Machek wrote:
> > > Hi!
> > >
> > > (Well, it is just after midnight here :-).
> > >
> > > > > > Here are the freezer patches. They were prepared against rc3, but I
> > > > > > think they still apply fine against rc5. (Ben, these are the same ones I
> > > > > > sent you the other day).
> > > > >
> > > > > 304 seems ugly and completely useless for mainline
> > > >
> > > > That's because you don't understand what it's doing.
> > > >
> > > > The new refrigerator implementation works like this:
> > > >
> > > > Userspace processes that begin a sys_*sync gain the process flag
> > > > PF_SYNCTHREAD for the duration of their syscall.
> > >
> > > swsusp1 should not need any special casing of sync, right? We can
> > > simply do sys_sync(), then freeze, or something like that. We could
> > > even remove sys_sync() completely; it is not needed for correctness.
Wrong. I guess you're only trying it on a machine that isn't actually
doing anything :). I've forgotten whether it was this freezer
implementation or the last, but we've been testing freezing processes
when the load average exceeds 100. If you have a thread that is syncing
and another that's submitting I/O continually (think dd, for example),
you want this.
> > It's still quite nice to have ... I put it in my pre-freeze callback in
> > fact for both STR and STD :) We really want it for STD but I think it
> > doesn't work properly after freeze.
>
> I agree that sync() is nice to have, but I'm not going to slow down
> fork/exit for it. And besides, sys_sync() just before suspend works
> just fine.
Again, try it under load... and stop talking about fork and exit like
they're real hot paths. (Unless you regularly submit your machines to
fork bombs :)).
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 1:45 ` Nigel Cunningham
@ 2005-06-02 1:48 ` Benjamin Herrenschmidt
2005-06-02 7:14 ` Pavel Machek
1 sibling, 0 replies; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-02 1:48 UTC (permalink / raw)
To: ncunningham; +Cc: Pavel Machek, Linux Kernel Mailing List
> Again, try it under load... and stop talking about fork and exit like
> they're real hot paths. (Unless you regularly submit your machines to
> fork bombs :)).
They are real hot path
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 1:45 ` Nigel Cunningham
2005-06-02 1:48 ` Benjamin Herrenschmidt
@ 2005-06-02 7:14 ` Pavel Machek
2005-06-02 7:26 ` Nigel Cunningham
1 sibling, 1 reply; 20+ messages in thread
From: Pavel Machek @ 2005-06-02 7:14 UTC (permalink / raw)
To: Nigel Cunningham; +Cc: Benjamin Herrenschmidt, Linux Kernel Mailing List
Hi!
> > > > swsusp1 should not need any special casing of sync, right? We can
> > > > simply do sys_sync(), then freeze, or something like that. We could
> > > > even remove sys_sync() completely; it is not needed for correctness.
>
> Wrong. I guess you're only trying it on a machine that isn't actually
> doing anything :). I've forgotten whether it was this freezer
> implementation or the last, but we've been testing freezing processes
> when the load average exceeds 100. If you have a thread that is syncing
> and another that's submitting I/O continually (think dd, for example),
> you want this.
If sys_sync() is not working, *fix sys_sync()*. [BTW I see that
problem before and I think it is being worked on.] I'm *not* going to
work around it in refrigerator.
Pavel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 7:14 ` Pavel Machek
@ 2005-06-02 7:26 ` Nigel Cunningham
2005-06-02 7:31 ` Pavel Machek
0 siblings, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-02 7:26 UTC (permalink / raw)
To: Pavel Machek; +Cc: Benjamin Herrenschmidt, Linux Kernel Mailing List
Hi.
On Thu, 2005-06-02 at 17:14, Pavel Machek wrote:
> Hi!
>
> > > > > swsusp1 should not need any special casing of sync, right? We can
> > > > > simply do sys_sync(), then freeze, or something like that. We could
> > > > > even remove sys_sync() completely; it is not needed for correctness.
> >
> > Wrong. I guess you're only trying it on a machine that isn't actually
> > doing anything :). I've forgotten whether it was this freezer
> > implementation or the last, but we've been testing freezing processes
> > when the load average exceeds 100. If you have a thread that is syncing
> > and another that's submitting I/O continually (think dd, for example),
> > you want this.
>
> If sys_sync() is not working, *fix sys_sync()*. [BTW I see that
> problem before and I think it is being worked on.] I'm *not* going to
> work around it in refrigerator.
I'm not saying sys_sync is broken. I _am_ saying that if you have
processes submitting I/O while you're trying to sync, syncing will take
longer and you may well still end up with dirty buffers at the end. On
top of this, you may think freezing has failed because processes don't
enter the refrigerator within your timelimit (assuming you have one).
The simple, logic solution is to stop threads that are submitting I/O
before you stop threads that are syncing I/O.
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 7:26 ` Nigel Cunningham
@ 2005-06-02 7:31 ` Pavel Machek
2005-06-02 7:36 ` Benjamin Herrenschmidt
0 siblings, 1 reply; 20+ messages in thread
From: Pavel Machek @ 2005-06-02 7:31 UTC (permalink / raw)
To: Nigel Cunningham; +Cc: Benjamin Herrenschmidt, Linux Kernel Mailing List
Hi!
> > If sys_sync() is not working, *fix sys_sync()*. [BTW I see that
> > problem before and I think it is being worked on.] I'm *not* going to
> > work around it in refrigerator.
>
> I'm not saying sys_sync is broken. I _am_ saying that if you have
> processes submitting I/O while you're trying to sync, syncing will take
> longer and you may well still end up with dirty buffers at the end. On
> top of this, you may think freezing has failed because processes don't
> enter the refrigerator within your timelimit (assuming you have
> one).
Then simple launch sys_sync(), let it finish, *then* do
refrigeration. That way sys_sync() does not count to the timelimit.
Now, sys_sync() takes too long on some setups. That needs to be fixed,
anyway; users don't like to wait for 15 minutes after typing
"sync". Do not work around it in refrigerator.
Pavel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 7:31 ` Pavel Machek
@ 2005-06-02 7:36 ` Benjamin Herrenschmidt
2005-06-02 8:18 ` Nigel Cunningham
0 siblings, 1 reply; 20+ messages in thread
From: Benjamin Herrenschmidt @ 2005-06-02 7:36 UTC (permalink / raw)
To: Pavel Machek; +Cc: Nigel Cunningham, Linux Kernel Mailing List
On Thu, 2005-06-02 at 09:31 +0200, Pavel Machek wrote:
> Hi!
>
> > > If sys_sync() is not working, *fix sys_sync()*. [BTW I see that
> > > problem before and I think it is being worked on.] I'm *not* going to
> > > work around it in refrigerator.
> >
> > I'm not saying sys_sync is broken. I _am_ saying that if you have
> > processes submitting I/O while you're trying to sync, syncing will take
> > longer and you may well still end up with dirty buffers at the end. On
> > top of this, you may think freezing has failed because processes don't
> > enter the refrigerator within your timelimit (assuming you have
> > one).
>
> Then simple launch sys_sync(), let it finish, *then* do
> refrigeration. That way sys_sync() does not count to the timelimit.
>
> Now, sys_sync() takes too long on some setups. That needs to be fixed,
> anyway; users don't like to wait for 15 minutes after typing
> "sync". Do not work around it in refrigerator.
Whatever you guys decide to do (I actually do sys_sync() before freezing
on pmac and yes, it takes sometimes way too long), to be uber-safe, we
could/should _also_ do sync after freezing userland processes and before
freezing kernel threads (that is, splitting here). In fact, that would
help also avoid deadlocks where a frozen kernel thread is holding a
semaphore preventing a process from freezing.
That way, if we sys_sync() once processes are sleeping and before kernel
threads are, we pretty-much make sure no new dirty buffer will appear.
Anyway, that's mostly food for thoughts at this point
Ben.
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 7:36 ` Benjamin Herrenschmidt
@ 2005-06-02 8:18 ` Nigel Cunningham
2005-06-02 21:47 ` Pavel Machek
0 siblings, 1 reply; 20+ messages in thread
From: Nigel Cunningham @ 2005-06-02 8:18 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: Pavel Machek, Linux Kernel Mailing List
Hi Ben.
On Thu, 2005-06-02 at 17:36, Benjamin Herrenschmidt wrote:
> Whatever you guys decide to do (I actually do sys_sync() before freezing
> on pmac and yes, it takes sometimes way too long), to be uber-safe, we
> could/should _also_ do sync after freezing userland processes and before
> freezing kernel threads (that is, splitting here). In fact, that would
> help also avoid deadlocks where a frozen kernel thread is holding a
> semaphore preventing a process from freezing.
>
> That way, if we sys_sync() once processes are sleeping and before kernel
> threads are, we pretty-much make sure no new dirty buffer will appear.
>
> Anyway, that's mostly food for thoughts at this point
I fully agree, and that's what I'm already doing. Nothing I can do about
Pavel not seeing logic, so guess I just have to hope everyone else does
:)
Regards,
Nigel
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: Freezer Patches.
2005-06-02 8:18 ` Nigel Cunningham
@ 2005-06-02 21:47 ` Pavel Machek
0 siblings, 0 replies; 20+ messages in thread
From: Pavel Machek @ 2005-06-02 21:47 UTC (permalink / raw)
To: Nigel Cunningham; +Cc: Benjamin Herrenschmidt, Linux Kernel Mailing List
Hi!
> > Whatever you guys decide to do (I actually do sys_sync() before freezing
> > on pmac and yes, it takes sometimes way too long), to be uber-safe, we
> > could/should _also_ do sync after freezing userland processes and before
> > freezing kernel threads (that is, splitting here). In fact, that would
> > help also avoid deadlocks where a frozen kernel thread is holding a
> > semaphore preventing a process from freezing.
> >
> > That way, if we sys_sync() once processes are sleeping and before kernel
> > threads are, we pretty-much make sure no new dirty buffer will appear.
> >
> > Anyway, that's mostly food for thoughts at this point
>
> I fully agree, and that's what I'm already doing. Nothing I can do about
> Pavel not seeing logic, so guess I just have to hope everyone else does
> :)
I think I see your logic, and it is wrong. Anyway, just do not touch
fork/exit hot paths.
Pavel
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2005-06-02 21:52 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-06-01 12:33 Freezer Patches Nigel Cunningham
2005-06-01 13:02 ` Pavel Machek
2005-06-01 22:02 ` Benjamin Herrenschmidt
2005-06-01 22:13 ` Nigel Cunningham
2005-06-01 22:23 ` Benjamin Herrenschmidt
2005-06-01 22:08 ` Nigel Cunningham
2005-06-01 22:31 ` Pavel Machek
2005-06-01 22:45 ` Benjamin Herrenschmidt
2005-06-01 23:02 ` Pavel Machek
2005-06-02 0:35 ` Benjamin Herrenschmidt
2005-06-02 1:46 ` Nigel Cunningham
2005-06-02 1:49 ` Benjamin Herrenschmidt
2005-06-02 1:45 ` Nigel Cunningham
2005-06-02 1:48 ` Benjamin Herrenschmidt
2005-06-02 7:14 ` Pavel Machek
2005-06-02 7:26 ` Nigel Cunningham
2005-06-02 7:31 ` Pavel Machek
2005-06-02 7:36 ` Benjamin Herrenschmidt
2005-06-02 8:18 ` Nigel Cunningham
2005-06-02 21:47 ` Pavel Machek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox