laptop-mode for 2.6, version 2
Subsystems (5)
PATCH 1/1 laptop-mode for 2.6, version 2
Hi Jens,
Here's a new version of the laptop-mode patch (and control script). I've
made a couple of improvements because of your comments. The block_dump
functionality (including block dirtying) is back, and my alternative
functionality has gone. There's just one bit of the block dumping patch that I couldn't place, the bit in filemap.c. The 2.6 code is so different here that I really couldn't figure out what I should do with it. Do you have any idea where this has gone (and if it is still needed)?
Bart
#!/bin/sh
#
# start of stop laptop mode, best run by a power management daemon when # ac gets connected/disconnected from a laptop # # FIXME: assumes HZ == 100
# age time, in seconds. should be put into a sysconfig file MAX_AGE=600
# kernel default dirty buffer age DEF_AGE=30 DEF_UPDATE=5
if [ ! -e /proc/sys/vm/laptop_mode ]; then
echo "Kernel is not patched with laptop_mode patch." exit 1
fi
if [ ! -w /proc/sys/vm/laptop_mode ]; then
echo "You do not have enough privileges to enable laptop mode." exit 1
fi
case "$1" in
start)
AGE=$((100*$MAX_AGE))
echo -n "Starting laptop mode"
echo "1" > /proc/sys/vm/laptop_mode
echo "$AGE" > /proc/sys/vm/dirty_expire_centisecs
echo "$AGE" > /proc/sys/vm/dirty_writeback_centisecs
echo "."
;;
stop)
U_AGE=$((100*$DEF_UPDATE))
B_AGE=$((100*$DEF_AGE))
echo -n "Stopping laptop mode"
echo "0" > /proc/sys/vm/laptop_mode
echo "$B_AGE" > /proc/sys/vm/dirty_writeback_centisecs
echo "$U_AGE" > /proc/sys/vm/dirty_expire_centisecs
echo "."
;;
*)
echo "$0 {start|stop}"
;;esac
exit 0
drivers/block/ll_rw_blk.c +18 -0
@@ -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);
@@ -2582,6 +2583,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 +2607,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 +2703,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 ; }
fs/buffer.c +14 -0
@@ -1259,7 +1259,11 @@if (!buffer_uptodate (bh))buffer_error ();if (!buffer_dirty (bh) && !test_set_buffer_dirty (bh)) + {__set_page_dirty_nobuffers (bh->b_page); +if (unlikely (block_dump)) +printk ("%s(%d): dirtied buffer\n" , current->comm, current->pid); + } }/*
@@ -2669,6 +2673,16 @@if (test_set_buffer_req (bh) && rw ==WRITE )clear_buffer_write_io_error (bh); +if (unlikely (block_dump)) + { +char b[BDEVNAME_SIZE ]; +printk ("%s(%d): %s block %lu/%u on %s\n" , + current->comm, current->pid, + rw ==WRITE ?"WRITE" : (rw ==READA ?"READA" :"READ" ), + bh->b_blocknr,atomic_read (&bh->b_count), +bdevname (bh->b_bdev,b)); + } +/* * from here on down, it's all bio -- do the initial mapping, * submit_bio -> generic_make_request may further map this bio around
include/linux/sysctl.h +2 -0
@@ -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 */ };
include/linux/writeback.h +4 -1
@@ -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 ;
kernel/sysctl.c +20 -0
@@ -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 } };
mm/page-writeback.c +32 -3
@@ -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,12 @@ }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 +383,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 )
Quoted 9 lines · Bart Samwel
Hi Jens,
Here's a new version of the laptop-mode patch (and control script). I've made a couple of improvements because of your comments. The
block_dumpfunctionality (including block dirtying) is back, and my alternative functionality has gone. There's just one bit of the block dumping patch that I couldn't place, the bit infilemap.c. The 2.6 code is so different here that I really couldn't figure out what I should do with it. Do you have any idea where this has gone (and if it is still needed)?
It looks better, getting there! Some comments further down.
Quoted 53 lines
diff -baur --speed-large-files
linux-2.6.0/drivers/block/ll_rw_blk.clinux-2.6.0-withlaptopmode/drivers/block/ll_rw_blk.cdrivers/block/ll_rw_blk.c +18
-0@@ -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);@@ -2582,6 +2583,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 +2607,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 +2703,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.clinux-2.6.0-withlaptopmode/fs/buffer.c
fs/buffer.c line 1266
Quoted 8 lines
fs/buffer.c +4
-0@@ -1259,7 +1259,11 @@if (!buffer_uptodate (bh))buffer_error ();if (!buffer_dirty (bh) && !test_set_buffer_dirty (bh)) + {__set_page_dirty_nobuffers (bh->b_page); +if (unlikely (block_dump)) +printk ("%s(%d): dirtied buffer\n" , current->comm, current->pid); + }
Probably want to move this to the actual set_page_dirty() function(s).
Quoted 10 lines
fs/buffer.c +3
-0}/* @@ -2669,6 +2673,16 @@if (test_set_buffer_req (bh) && rw ==WRITE )clear_buffer_write_io_error (bh); +if (unlikely (block_dump)) + { +char b[BDEVNAME_SIZE ];
fs/buffer.c line 2688
Quoted 10 lines
fs/buffer.c +7
-0+printk ("%s(%d): %s block %lu/%u on %s\n" , + current->comm, current->pid, + rw ==WRITE ?"WRITE" : (rw ==READA ?"READA" :"READ" ), + bh->b_blocknr,atomic_read (&bh->b_count), +bdevname (bh->b_bdev,b)); + } +/* * from here on down, it's all bio -- do the initial mapping, * submit_bio -> generic_make_request may further map this bio around
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.
Quoted 141 lines
diff -baur --speed-large-files
linux-2.6.0/include/linux/sysctl.hlinux-2.6.0-withlaptopmode/include/linux/sysctl.hinclude/linux/sysctl.h +2
-0@@ -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.hlinux-2.6.0-withlaptopmode/include/linux/writeback.hinclude/linux/writeback.h +4
-1@@ -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.clinux-2.6.0-withlaptopmode/kernel/sysctl.ckernel/sysctl.c +20
-0@@ -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.clinux-2.6.0-withlaptopmode/mm/page-writeback.cmm/page-writeback.c +25
-3@@ -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,12 @@ }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 +383,15 @@return 0 ; } +/* +* Set the kupdate timer to run it as soon as possible.
mm/page-writeback.c line 397
Quoted 10 lines
mm/page-writeback.c +7
-0+*/ +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 )
The rest looks ok, apart from style.
Signature · 1 line
Jens Axboe
PATCH 1/1 laptop-mode for 2.6, version 3
Quoted 1 line · Jens Axboe
It looks better, getting there!
Thx!
[block_dump code in set_buffer_dirty()]
Quoted 1 line
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()]
Quoted 4 lines
You don't want this in
submit_bh(), that hardly matters at all anymore. It wants to be insubmit_bio(). And you should follow the brace placement style. And just dump device+offset,b_countis not interesting.
Done. This gives some extra output as well, which is good.
Quoted 1 line
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
drivers/block/ll_rw_blk.c +27 -0
@@ -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); elsemod_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 ; }
fs/buffer.c +5 -2
@@ -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); }
include/linux/sysctl.h +2 -0
@@ -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 */ };
include/linux/writeback.h +4 -1
@@ -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 ;
kernel/sysctl.c +20 -0
@@ -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 } };
mm/page-writeback.c +33 -3
@@ -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; }
Re: [PATCH] laptop-mode for 2.6, version 3
Minor nitpicks below
Em Wed, Dec 24, 2003 at 04:25:48PM +0100, Bart Samwel escreveu:
Quoted 15 lines
diff -baur --speed-large-files
linux-2.6.0/mm/page-writeback.clinux-2.6.0-withlaptopmode/mm/page-writeback.cmm/page-writeback.c +1
-0@@ -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 ;
mm/page-writeback.c line 94
Quoted 10 lines
mm/page-writeback.c +10
-0+/* +* 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 ; +
No need to set a global variable to 0, if you don't set it'll go to the .bss section and the kernel will zero it out for us, and we reclaim 2 * sizeof(int) from the kernel image. This is common style in most parts of the kernel.
- Arnaldo
PATCH 1/1 laptop-mode for 2.6, version 4 + smart_spindown
Quoted 1 line · Arnaldo Carvalho de Melo
Minor nitpicks below
[...]
Quoted 5 lines
Quoted 1 line
+int
laptop_mode= 0;No need to set a global variable to 0, if you don't set it'll go to the
.bss section and the kernel will zero it out for us, and we reclaim 2 * sizeof(int) from the kernel image. This is common style in most parts of the kernel.
Thanks, I've fixed this. Here is the resulting patch.
I've got another problem getting this stuff to work. The problem lies with my HD: it just doesn't respect the spindown time, I've got it set to hdparm -S 4 and it just doesn't spin down, even though there's no activity whatsoever! hdparm -B 254 gives me:
/dev/hdb:
setting Advanced Power Management level to 0xFE (254) HDIO_DRIVE_CMD failed: Input/output error
It's funny, because hdparm -I gives me:
Commands/features:
Enabled Supported:
[...]
* Power Management feature set
So, it should support this. Apparently it doesn't. :( The drive is a WD 800BB. Does anyone have any clue what could cause this?
Anyway, I've built myself a solution called "smart_spindown". This script monitors the read activity on a drive, and if there hasn't been any read activity in a while it spins down the drive. The amount of read-inactivity needed is subjected to an exponential backoff algorithm: when spun-down periods last shorter, the amount of inactivity needed for triggering a spindown increases. When the system is low on activity, the script is more aggressive w.r.t. spinning down the disk, and when you're using the system it usually doesn't spin down the disk. The algorithm can be tuned to your personal needs, so you can set it to be more aggressive if you want to.
Interestingly, I found out that this script removes my need for laptop_mode. I've added an option to the beginning called NO_LAPTOP_MODE, if you set that to true it will sync just before spinning the disk down. This even adds a bit of spun-down time, as the sync takes place just before spinning down the disk instead of just after the last read. The only downside to this is that it syncs ALL disks, not only the disk that it monitors. However, this is really getting me spun-down times of about 595 seconds, while my expires are set to 600 seconds. This makes me a very happy bunny indeed!
Short explanation of how the script can be used:
* Edit the script to set:
1. the disk name (DISK=)
2. the stats file (STATSFILE=), if your sysfs isn't mounted on /sys.
3. the device name (DEVNAME=), if the device isn't /dev/$DISK.
* Tune the OUTLEVEL1 and OUTLEVEL2 values to set the verbosity.
* Tune other parameters as needed. See the comments in the script.
* Run it as root, or as someone who can run hdparm. :)
If you want to use the script as a replacement of laptop_mode, you must adjust the VM parameters yourself, like it is done in the laptop_mode control script; see the comments above NO_LAPTOP_MODE in the script.
Bart
drivers/block/ll_rw_blk.c +27 -0
@@ -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); elsemod_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 ; }
fs/buffer.c +5 -2
@@ -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); }
include/linux/sysctl.h +2 -0
@@ -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 */ };
include/linux/writeback.h +4 -1
@@ -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 ;
kernel/sysctl.c +20 -0
@@ -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 } };
mm/page-writeback.c +33 -3
@@ -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; + +/* +* Flag that puts the machine in "laptop mode". +*/ +int laptop_mode; +/* 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; }
#! /bin/bash
#
# smart_spindown rev. 1 # # Copyright (C) 2003 by Bart Samwel # # You may do with this file (and parts thereof) whatever you want, as long # as my copyright notice is retained. # # # How it works: This program monitors the read activity on a disk. If there # is no read activity for a while, the disk is spun down. The time without # read activity that is required is dynamic, using a backoff factor. When # the recent spun-down periods are relatively short, this means that the # machine might be busy with something, so the script tries to wait for # longer periods without activity before spinning down again. When spun-down # periods are long, the backoff factor is decreased, and the disk is spun # down after shorter periods without read activity. # # This script REQUIRES that laptop_mode is enabled on your kernel. This is # because it assumes that after a couple of seconds without read activity, # all dirty blocks will be flushed. If this is not done, the disc will # spin up at random times # # Configuration #
# Output levels. Level 2 is verbose, level 1 is normal output. # Enable all levels you would like to see. OUTLEVEL1=true
OUTLEVEL2=false
# Disk to monitor.
DISK=hdb
# Device name for the disk.
DEVNAME=/dev/$DISK
# Stats file: the file used to monitor the disk's read activity. # The first entry in this stats file must represent the read activity. STATSFILE=/sys/block/$DISK/stat
# Multiplication factor for the backoff after a spinup, in percentages. # Default is 300 = factor 3.
BACKOFF_INCREASE_PCT=300
# Multiplication factor for the backoff at every poll that shows that
# the disk is spun down. This determines how fast the backoff value # decreases. BACKOFF_DECREASE_PCT=96
# The base "no reads" wait time (in seconds). This is multiplied by
# the backoff factor to determine the real "no reads" wait time. WAITTIME=20
# The maximum "no reads" wait time (in seconds).
# This also limits the backoff factor: the backoff factor cannot increase
# above a value that makes the "no reads" wait time larger than MAXWAIT. # Default is 120 seconds. MAXWAIT=120
# Time (in seconds) between polls to see if the disk is active again. # Default is 10 seconds.
POLLTIME=10
# Enable this if you don't use laptop_mode. This will make the script
# sync before spinning down the disc. To make this work, you must # ensure that: # 1. /proc/sys/vm/dirty_expire_centisecs is set to a high value. You can # use 60000 for 10 minutes. # 2. /proc/sys/vm/dirty_writeback_centisecs is set to the same value. # 3. Your ext3 filesystems are mounted with "commit=n", where n is the # number of seconds between commit. Use 600 for 10 minutes. NO_LAPTOP_MODE=false
#
# Let's go!
#
# Number of poll times that the disc was found to be spun down. POLLSSPUNDOWN=0
# Number of spindowns performed
SPINDOWNS=0
# Number of times (*100) the WAITTIME of no-reads required before spindown BACKOFF_FACTOR=100
# Stats: Total time the disk has been up.
UPTIME=0
# Total duration of last spun-down period.
LASTDOWNTIME=0
# Total duration of the last spun-up period.
LASTUPTIME=0
# Duration of the last poll. Always equal to POLLTIME except the first
# time around. LASTPOLLTIME=0
# Make sure the stuff we use is in the cache. I've seen it happen
# that the script spun the disk down, and then "sleep" wasn't in # the cache and the disk spun right up again. :) true false sleep 1
$OUTLEVEL1 && echo Monitoring spindown opportunities for disk $DISK. if ($OUTLEVEL1) ; then
hdparm -C $DEVNAME |grep active >/dev/null
if [ "$?" == "0" ] ; then
echo Drive is currently spun up. ;
else
echo Drive is currently spun down. ;
fi ;
fi
while [[ /sbin/true ]]; do
hdparm -C $DEVNAME |grep active >/dev/null
if [ "$?" == "0" ] ; then
THISWAIT=$(($WAITTIME*$BACKOFF_FACTOR/100)) ;
if [[ $THISWAIT -gt $MAXWAIT ]] ; then
THISWAIT=$MAXWAIT ;
fi ;
# Increase the backoff irrespective of whether we failed
# or not. The backoff should drop again by the lack of
# spinups afterwards.
BACKOFF_FACTOR=$(($BACKOFF_FACTOR*$BACKOFF_INCREASE_PCT/100)) ;
if [[ $(($BACKOFF_FACTOR*$WAITTIME/100)) -gt $MAXWAIT ]] ; then
BACKOFF_FACTOR=$(($MAXWAIT*100/$WAITTIME)) ;
fi ;
UPTIME=$(($UPTIME+$LASTPOLLTIME)) ;
LASTUPTIME=$(($LASTUPTIME+$LASTPOLLTIME)) ;
if [ "$LASTDOWNTIME" != "0" ] ; then
$OUTLEVEL1 && echo Drive spun up after $LASTDOWNTIME seconds. ;
fi
PREVIOUS_READS=-1 ;
NUM_EQUALS=0 ;
$OUTLEVEL2 && echo Waiting for $THISWAIT seconds of read inactivity... ;
PREVIOUS_READS=`cat $STATSFILE |awk '{ print $1; }'` ;
while [[ $(($NUM_EQUALS*5)) -lt $THISWAIT ]]; do
sleep 5 ;
UPTIME=$(($UPTIME+5)) ;
LASTUPTIME=$(($LASTUPTIME+5)) ;
NEXT_READS=`cat $STATSFILE |awk '{ print $1; }'` ;
if [[ $PREVIOUS_READS -ne $NEXT_READS ]] ; then
NUM_EQUALS=0 ;
PREVIOUS_READS=$NEXT_READS
$OUTLEVEL2 && echo Restarting... ;
else
NUM_EQUALS=$(($NUM_EQUALS+1)) ;
$OUTLEVEL2 && echo Seconds of quiet: $(($NUM_EQUALS*5)) ;
fi
done
# We've just had $THISWAIT seconds of read inactivity. Writes can be
# cached, reads always spin up the disk; the inactivity indicates
# that we're ready to go to sleep. Laptop mode will have synced all
# writes for us after the last read, so we don't have to explicitly
# sync.
if ( $NO_LAPTOP_MODE ) ; then
sync ;
fi ;
hdparm -q -y $DEVNAME ;
SPINDOWNS=$(($SPINDOWNS+1)) ;
$OUTLEVEL1 && echo Drive spun down after $LASTUPTIME seconds \(with $THISWAIT seconds of inactivity\). ;
LASTUPTIME=0 ;
LASTDOWNTIME=0 ;
else
POLLSSPUNDOWN=$(($POLLSSPUNDOWN+1)) ;
if [[ $SPINDOWNS -eq 0 ]] ; then
SPINDOWNS=1 ;
fi
LASTDOWNTIME=$(($LASTDOWNTIME+$LASTPOLLTIME)) ;
BACKOFF_FACTOR=$(($BACKOFF_FACTOR*$BACKOFF_DECREASE_PCT/100)) ;
if [ $BACKOFF_FACTOR -lt 100 ] ; then
BACKOFF_FACTOR=100 ;
fi
fi ;
if ( $OUTLEVEL2 ) ; then
echo -n spindowns: $SPINDOWNS, time up/down: $UPTIME/$(($POLLSSPUNDOWN*$POLLTIME)), backoff $BACKOFF_FACTOR, down for $LASTDOWNTIME \(avg $(($POLLSSPUNDOWN*$POLLTIME/$SPINDOWNS))\). ;
fi ;
sleep $POLLTIME ;
LASTPOLLTIME=$POLLTIME ;done
Re: [PATCH] laptop-mode for 2.6, version 4 + smart_spindown
Quoted 11 lines
I've got another problem getting this stuff to work. The problem lies with my HD: it just doesn't respect the spindown time, I've got it set to hdparm -S 4 and it just doesn't spin down, even though there's no activity whatsoever! hdparm -B 254 gives me:
/dev/hdb:
setting Advanced Power Management level to0xFE(254)HDIO_DRIVE_CMDfailed: Input/output errorIt's funny, because hdparm -I gives me:
Quoted 7 lines
Commands/features:
Enabled Supported:
[...]
* Power Management feature setSo, it should support this. Apparently it doesn't. :( The drive is a WD 800BB. Does anyone have any clue what could cause this?
No, but I've definitely seen other drives, (old Toshiba ~100 MB ones), which respect 'spin down immediately' commands, and don't support the spin down inactivity timer. I can't remember whether they report Power Management feature set supported or not, though.
John.
Re: [PATCH] laptop-mode for 2.6, version 4 + smart_spindown
Quoted 4 lines · John Bradford
No, but I've definitely seen other drives, (old Toshiba ~100 MB ones), which respect 'spin down immediately' commands, and don't support the spin down inactivity timer. I can't remember whether they report Power Management feature set supported or not, though.
Hmmm, I think I've found the problem, hidden in the drive info. hdparm -I also says:
Capabilities:
[...]
Standby timer values: spec'd by Standard, with device specific
minimum
I think it's the device specific minimum that got me, -S 4 equals 20 seconds, which is probably a lower value than the drive is capable of supporting. A bit nasty that the drive accepts the -S 4 setting, but just doesn't do anything with it. An error would have been nice. Anyway, the smart_spindown script does work for lower values, so I guess I'll use that instead. It has some added benefits as well, so I'm not too disappointed.
Bart
A couple of questions about laptop-mode for 2.6, version 4
In reply to Bart SamwelQuoted 6 lines · Bart Samwel
Thanks, I've fixed this. Here is the resulting patch.
I've got another problem getting this stuff to work. The problem lies with my HD: it just doesn't respect the spindown time, I've got it set to hdparm -S 4 and it just doesn't spin down, even though there's no activity whatsoever! hdparm -B 254 gives me:
Hi,
since laptop-mode was a feature from 2.4 wich I was missing in 2.6, I've decided to give it a try.
However, I have not a clue about kernel programming (and neither about filesystems implementations), so looking at the source code is useless to me (as I do not understand anything :-[). So, please forgive-me if I'm asking obvious questions:
1.- I've used the patch posted in the message I'm replying (From: Bart Samwel, Date: Thu, 25 Dec 2003 16:12:38 +0100). Hope this is the correct one.
2.- I plan to use cpudyn (http://mnm.uib.es/~gallir/cpudyn) to spin down the disks (as I did in 2.4). If I have understood it correctly, that functionality is what the smart_spindown script does. I guess there will be no problems with that.
3.- As I use mainly ext3 partitions, I read in the first post regarding laptop-mode with ext3, that I had to mount my filesystems with commit=$MAX_AGE (beeing that $MAX_AGE, the value used in linux-2.4/Documentation/laptop-mode.sh). Is this correct?
If the previous answer is yes, what do you think would be the best way to do so? I don't like modifying /etc/fstab, because if I boot another (non laptop-mode) kernel (or I want to disable laptop-mode when doing something important); I guess nasty things could happen if I forget to remount my ext3 filesystems appropiately.
I was thinking in modifying laptop-mode.sh to read /proc/mounts and remount ext3 partitions with the appropiate parameter (on start and also on stop). But I quite don't like this method, it seems "ugly" to me (and does not solve the problem of mounting filesystems after activating/deactivating laptop-mode).
Do you have a better idea? I know this last question is a userspace problem, but AFAICS it's tightly related to the way laptop-mode is implemented in the kernel (always suposing the answer to 3.- is yes).
Thanks in advance!
Signature · 1 line
Kiko
Quoted 7 lines · On Wed, 24 Dec 2003 06:33:11 +0100 Bart Samwel <[email protected]> wrote:
Here's a new version of the laptop-mode patch (and control script). I've made a couple of improvements because of your comments. The
block_dumpfunctionality (including block dirtying) is back, and my alternative functionality has gone. There's just one bit of the block dumping patch that I couldn't place, the bit infilemap.c. The 2.6 code is so different here that I really couldn't figure out what I should do with it. Do you have any idea where this has gone (and if it is still needed)?
Here is hacker patch do laptop mode on reiserfs file system. Any comments are welcome.
Signature · 3 lines
Hu Gang / Steve RLU# : 204016 [1999] (Registered Linux user) GPG Public Key: http://soulinfo.com/~hugang/HuGang.asc
Quoted 11 lines · Hugang
Quoted 7 lines · On Wed, 24 Dec 2003 06:33:11 +0100 Bart Samwel <[email protected]> wrote:
Here's a new version of the laptop-mode patch (and control script). I've made a couple of improvements because of your comments. The
block_dumpfunctionality (including block dirtying) is back, and my alternative functionality has gone. There's just one bit of the block dumping patch that I couldn't place, the bit infilemap.c. The 2.6 code is so different here that I really couldn't figure out what I should do with it. Do you have any idea where this has gone (and if it is still needed)?
Quoted 3 lines
Here is hacker patch do laptop mode on reiserfs file system. Any comments are welcome.
From patch:
+int reiserfs_default_max_commit_age = -1;
+
I am not sure that global variable is a good idea here. What if several file systems are mounted? You should either pass value as an argument to the journal initialization code, or just initialize SB_JOURNAL_MAX_COMMIT_AGE(sb) when parsing options.
Quoted 3 lines
Signature · 2 lines
-- Hu Gang / Steve
Nikita.
Quoted 7 lines · On Wed, 24 Dec 2003 17:24:04 +0300 Nikita Danilov <[email protected]> wrote:
(quoted diff) +2
-0+int reiserfs_default_max_commit_age = -1; +I am not sure that global variable is a good idea here. What if several file systems are mounted? You should either pass value as an argument to the journal initialization code, or just initialize
SB_JOURNAL_MAX_COMMIT_AGE(sb)when parsing options.
this patch do it, pls check.
thanks.
Signature · 3 lines
Hu Gang / Steve RLU# : 204016 [1999] (Registered Linux user) GPG Public Key: http://soulinfo.com/~hugang/HuGang.asc
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 7 lines · On Thu, 25 Dec 2003 12:17:43 +0300 Nikita Danilov <[email protected]> wrote:
Quoted 4 lines
unsigned long blocks; unsigned long mount_options = REISERFS_SB(s)->s_mount_opt; unsigned long safe_mask = 0;+ unsigned int
commit_max_age= -1;Assigning -1 to the unsigned int looks strange. Let's use 0, it is invalid anyway.
Yes, must change to -1, fixed.
Quoted 18 lines
I think that it would be better to first
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)= valin the
parse_options()(after checking for validity), and injournal_init()do something likeif (
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)== 0) {
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)=le32_to_cpu(jh->jh_journal.jp_journal_max_commit_age);
}This will also get rid of
drivers/block/ll_rw_blk.c +4
-0+if (commit_max_age !=-1 ) { +SB_JOURNAL_MAX_COMMIT_AGE (s) = commit_max_age; + } +
Quoted 4 lines
piece in
reiserfs_remount.Otherwise patch looks ok. Have you tested it?
In the parse_options() can not assigning commit max age to super block, the journal memory not malloc, so I pass a it to journal_init.
Yes, It works in my laptop for 1 days. Every thinks is fine.
Thanks.
Signature · 3 lines
Hu Gang / Steve RLU# : 204016 [1999] (Registered Linux user) GPG Public Key: http://soulinfo.com/~hugang/HuGang.asc
Quoted 30 lines · Hugang
Quoted 7 lines · On Thu, 25 Dec 2003 12:17:43 +0300 Nikita Danilov <[email protected]> wrote:
Quoted 4 lines
unsigned long blocks; unsigned long mount_options = REISERFS_SB(s)->s_mount_opt; unsigned long safe_mask = 0;+ unsigned int
commit_max_age= -1;Assigning -1 to the unsigned int looks strange. Let's use 0, it is invalid anyway.
Yes, must change to -1, fixed.
Quoted 18 lines
I think that it would be better to first
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)= valin the
parse_options()(after checking for validity), and injournal_init()do something likeif (
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)== 0) {
SB_JOURNAL_MAX_COMMIT_AGE(p_s_sb)=le32_to_cpu(jh->jh_journal.jp_journal_max_commit_age);
}This will also get rid of
drivers/block/ll_rw_blk.c +4
-0+if (commit_max_age !=-1 ) { +SB_JOURNAL_MAX_COMMIT_AGE (s) = commit_max_age; + } +
Quoted 8 lines
Quoted 4 lines
piece in
reiserfs_remount.Otherwise patch looks ok. Have you tested it?
In the
parse_options()can not assigning commit max age to super block, the journal memory not malloc, so I pass a it tojournal_init.Yes, It works in my laptop for 1 days. Every thinks is fine.
+ if ( val > 0 ) {
+ *commit_max_age = val;
+ }
here warning should be issued, and mount refused, if val == 0.
Quoted 2 lines
Thanks.
Nikita.
Quoted 5 lines · On Thu, 25 Dec 2003 13:27:30 +0300 Nikita Danilov <[email protected]> wrote:
(quoted diff) +3
-0+ if ( val > 0 ) { + *commit_max_age = val; + }here warning should be issued, and mount refused, if val == 0.
Adding a message for it. here is it.
thanks.
--
Hu Gang / Steve
RLU# : 204016 [1999] (Registered Linux user)
GPG Public Key: http://soulinfo.com/~hugang/HuGang.asc