public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Bart Samwel <bart@samwel.tk>
To: Jens Axboe <axboe@suse.de>
Cc: linux-kernel@vger.kernel.org
Subject: [PATCH] laptop-mode for 2.6, version 3
Date: Wed, 24 Dec 2003 16:25:48 +0100	[thread overview]
Message-ID: <3FE9AFFC.2080302@samwel.tk> (raw)
In-Reply-To: <20031224111640.GL1601@suse.de>

[-- Attachment #1: Type: text/plain, Size: 760 bytes --]

Jens Axboe wrote:
 > It looks better, getting there!

Thx!

[block_dump code in set_buffer_dirty()]
 > Probably want to move this to the actual set_page_dirty() function(s).

Done. Works better, seeing a bit more output as well.

[block_dump code in submit_bh()]
 > You don't want this in submit_bh(), that hardly matters at all anymore.
 > It wants to be in submit_bio(). And you should follow the brace
 > placement style. And just dump device+offset, b_count is not
 > interesting.

Done. This gives some extra output as well, which is good.

 > The rest looks ok, apart from style.

I've changed it to use the correct bracing style. Is it OK now?

Thanks for the feedback. Do you see any more problems with the current 
patch, or is it OK like this?

Bart

[-- Attachment #2: laptop-mode-2.6.0-3.patch --]
[-- Type: text/plain, Size: 7061 bytes --]

diff -baur --speed-large-files linux-2.6.0/drivers/block/ll_rw_blk.c linux-2.6.0-withlaptopmode/drivers/block/ll_rw_blk.c
--- linux-2.6.0/drivers/block/ll_rw_blk.c	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/drivers/block/ll_rw_blk.c	2003-12-24 15:54:37.000000000 +0100
@@ -27,6 +27,7 @@
 #include <linux/completion.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
+#include <linux/writeback.h>
 
 static void blk_unplug_work(void *data);
 static void blk_unplug_timeout(unsigned long data);
@@ -2307,6 +2308,15 @@
 		mod_page_state(pgpgout, count);
 	else
 		mod_page_state(pgpgin, count);
+
+	if (unlikely(block_dump)) {
+		char b[BDEVNAME_SIZE];
+		printk("%s(%d): %s block %lu on %s\n",
+			current->comm, current->pid,
+			(rw & WRITE) ? "WRITE" : (rw == READA ? "READA" : "READ"),
+			bio->bi_sector, bdevname(bio->bi_bdev,b));
+	}
+
 	generic_make_request(bio);
 	return 1;
 }
@@ -2582,6 +2592,14 @@
 
 EXPORT_SYMBOL(end_that_request_chunk);
 
+static struct timer_list writeback_timer;
+
+static void blk_writeback_timer(unsigned long data)
+{
+	wakeup_bdflush(0);
+	wakeup_kupdate();
+}
+
 /*
  * queue lock must be held
  */
@@ -2598,6 +2616,11 @@
 			disk_stat_add(disk, write_ticks, duration);
 			break;
 		    case READ:
+			/*
+			 * schedule the writeout of pending dirty data when the disk is idle
+			 */
+			if (unlikely(laptop_mode))
+				mod_timer(&writeback_timer, jiffies + 5 * HZ);
 			disk_stat_inc(disk, reads);
 			disk_stat_add(disk, read_ticks, duration);
 			break;
@@ -2689,6 +2712,10 @@
 
 	for (i = 0; i < ARRAY_SIZE(congestion_wqh); i++)
 		init_waitqueue_head(&congestion_wqh[i]);
+	
+	init_timer(&writeback_timer);
+	writeback_timer.function = blk_writeback_timer;
+	
 	return 0;
 }
 
diff -baur --speed-large-files linux-2.6.0/fs/buffer.c linux-2.6.0-withlaptopmode/fs/buffer.c
--- linux-2.6.0/fs/buffer.c	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/fs/buffer.c	2003-12-24 15:46:30.000000000 +0100
@@ -855,10 +855,13 @@
 		struct buffer_head *bh = head;
 
 		do {
-			if (buffer_uptodate(bh))
+			if (buffer_uptodate(bh)) {
 				set_buffer_dirty(bh);
-			else
+				if (unlikely(block_dump))
+					printk("%s(%d): dirtied buffer\n", current->comm, current->pid);
+			} else {
 				buffer_error();
+			}
 			bh = bh->b_this_page;
 		} while (bh != head);
 	}
diff -baur --speed-large-files linux-2.6.0/include/linux/sysctl.h linux-2.6.0-withlaptopmode/include/linux/sysctl.h
--- linux-2.6.0/include/linux/sysctl.h	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/include/linux/sysctl.h	2003-12-24 03:17:36.000000000 +0100
@@ -154,6 +154,8 @@
 	VM_SWAPPINESS=19,	/* Tendency to steal mapped memory */
 	VM_LOWER_ZONE_PROTECTION=20,/* Amount of protection of lower zones */
 	VM_MIN_FREE_KBYTES=21,	/* Minimum free kilobytes to maintain */
+	VM_LAPTOP_MODE=22,      /* vm laptop mode */
+	VM_BLOCK_DUMP=23,       /* block dump mode */
 };
 
 
diff -baur --speed-large-files linux-2.6.0/include/linux/writeback.h linux-2.6.0-withlaptopmode/include/linux/writeback.h
--- linux-2.6.0/include/linux/writeback.h	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/include/linux/writeback.h	2003-12-24 06:01:47.000000000 +0100
@@ -71,12 +71,15 @@
  * mm/page-writeback.c
  */
 int wakeup_bdflush(long nr_pages);
+int wakeup_kupdate(void);
 
-/* These 5 are exported to sysctl. */
+/* These are exported to sysctl. */
 extern int dirty_background_ratio;
 extern int vm_dirty_ratio;
 extern int dirty_writeback_centisecs;
 extern int dirty_expire_centisecs;
+extern int block_dump;
+extern int laptop_mode;
 
 struct ctl_table;
 struct file;
diff -baur --speed-large-files linux-2.6.0/kernel/sysctl.c linux-2.6.0-withlaptopmode/kernel/sysctl.c
--- linux-2.6.0/kernel/sysctl.c	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/kernel/sysctl.c	2003-12-24 06:24:53.000000000 +0100
@@ -700,6 +700,26 @@
 		.strategy	= &sysctl_intvec,
 		.extra1		= &zero,
 	},
+	{
+		.ctl_name	= VM_LAPTOP_MODE,
+		.procname	= "laptop_mode",
+		.data		= &laptop_mode,
+		.maxlen		= sizeof(laptop_mode),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
+	{
+		.ctl_name	= VM_BLOCK_DUMP,
+		.procname	= "block_dump",
+		.data		= &block_dump,
+		.maxlen		= sizeof(block_dump),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+		.strategy	= &sysctl_intvec,
+		.extra1		= &zero,
+	},
 	{ .ctl_name = 0 }
 };
 
diff -baur --speed-large-files linux-2.6.0/mm/page-writeback.c linux-2.6.0-withlaptopmode/mm/page-writeback.c
--- linux-2.6.0/mm/page-writeback.c	2003-12-24 05:19:46.000000000 +0100
+++ linux-2.6.0-withlaptopmode/mm/page-writeback.c	2003-12-24 15:49:55.000000000 +0100
@@ -28,6 +28,7 @@
 #include <linux/smp.h>
 #include <linux/sysctl.h>
 #include <linux/cpu.h>
+#include <linux/quotaops.h>
 
 /*
  * The maximum number of pages to writeout in a single bdflush/kupdate
@@ -81,6 +82,16 @@
  */
 int dirty_expire_centisecs = 30 * 100;
 
+/*
+ * Flag that makes the machine dump writes/reads and block dirtyings.
+ */
+int block_dump = 0;
+
+/*
+ * Flag that puts the machine in "laptop mode".
+ */
+int laptop_mode = 0;
+
 /* End of sysctl-exported parameters */
 
 
@@ -167,7 +178,7 @@
 
 		get_dirty_limits(&ps, &background_thresh, &dirty_thresh);
 		nr_reclaimable = ps.nr_dirty + ps.nr_unstable;
-		if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+		if (laptop_mode || nr_reclaimable + ps.nr_writeback <= dirty_thresh)
 			break;
 
 		dirty_exceeded = 1;
@@ -192,10 +203,11 @@
 		blk_congestion_wait(WRITE, HZ/10);
 	}
 
-	if (nr_reclaimable + ps.nr_writeback <= dirty_thresh)
+	if (laptop_mode || nr_reclaimable + ps.nr_writeback <= dirty_thresh)
 		dirty_exceeded = 0;
 
-	if (!writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
+	if (!laptop_mode &&
+	    !writeback_in_progress(bdi) && nr_reclaimable > background_thresh)
 		pdflush_operation(background_writeout, 0);
 }
 
@@ -327,6 +339,8 @@
 	oldest_jif = jiffies - (dirty_expire_centisecs * HZ) / 100;
 	start_jif = jiffies;
 	next_jif = start_jif + (dirty_writeback_centisecs * HZ) / 100;
+	if (laptop_mode)
+		wbc.older_than_this = NULL;
 	nr_to_write = ps.nr_dirty + ps.nr_unstable +
 			(inodes_stat.nr_inodes - inodes_stat.nr_unused);
 	while (nr_to_write > 0) {
@@ -343,6 +357,11 @@
 	}
 	if (time_before(next_jif, jiffies + HZ))
 		next_jif = jiffies + HZ;
+	if (laptop_mode) {
+		sync_inodes(0);
+		sync_filesystems(0);
+		DQUOT_SYNC(NULL);
+	}
 	if (dirty_writeback_centisecs)
 		mod_timer(&wb_timer, next_jif);
 }
@@ -363,6 +382,15 @@
 	return 0;
 }
 
+/*
+ * Set the kupdate timer to run it as soon as possible.
+ */
+int wakeup_kupdate(void)
+{
+	mod_timer(&wb_timer, jiffies);
+	return 0;
+}
+
 static void wb_timer_fn(unsigned long unused)
 {
 	if (pdflush_operation(wb_kupdate, 0) < 0)
@@ -525,6 +553,8 @@
 				__mark_inode_dirty(mapping->host,
 							I_DIRTY_PAGES);
 		}
+		if (unlikely(block_dump))
+			printk("%s(%d): dirtied page\n", current->comm, current->pid);
 	}
 	return ret;
 }

  reply	other threads:[~2003-12-24 15:26 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-12-24  5:33 [PATCH] laptop-mode for 2.6, version 2 Bart Samwel
2003-12-24 11:16 ` Jens Axboe
2003-12-24 15:25   ` Bart Samwel [this message]
2003-12-25 10:06     ` [PATCH] laptop-mode for 2.6, version 3 Arnaldo Carvalho de Melo
2003-12-25 15:12       ` [PATCH] laptop-mode for 2.6, version 4 + smart_spindown Bart Samwel
2003-12-25 17:04         ` John Bradford
2003-12-25 21:39           ` Bart Samwel
2003-12-27 10:57         ` A couple of questions about laptop-mode for 2.6, version 4 Kiko Piris
2003-12-24 13:51 ` [PATCH] laptop-mode for 2.6, version 2 Hugang
2003-12-24 14:24   ` Nikita Danilov
2003-12-25  2:59     ` Hugang
     [not found]       ` <16362.43831.569086.825899@laputa.namesys.com>
2003-12-25  9:40         ` Hugang
2003-12-25 10:27           ` Nikita Danilov
2003-12-25 10:59             ` Hugang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3FE9AFFC.2080302@samwel.tk \
    --to=bart@samwel.tk \
    --cc=axboe@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox