blk-aam, automatic acoustic management
Subsystems (2)
PATCH 1/1 blk-aam, automatic acoustic management
Hi,
I posted an alpha copy of this patch some time ago, here's a more polished and extended version. Basically, it allows a disk to be in three states:
- idle. for ide, this is implemented as a spin down of the disk.
- quiet. slower seeks, more quiet, consumes less power.
- fast. faster seeks, more loud, consumes more power.
Transition between these three states is controlled by how much io the disk is doing, and for how long. The disk starts in low power mode, an io rate of 'high_mark' ios/sec over a period of 'high_cycle' or more sets it into fast mode. 'low_mark' ios/sec or less over a period of 'low_cycle' or more sets the disk back to quiet mode. Zero ios over a period of 'idle_cycle' spins the disk down.
Everything is in /proc/aam/hdX:
axboe@apu:/home/axboe $ ls /proc/aam/hda/
enabled high_mark low_cycle status high_cycle idle_cycle low_mark verbose
enabled
whether it's enabled or not. default: on
verbose
whether transition between the 3 states should generate a log message. ala:
hda: iorate=149, switching to fast operation
...
hda: iorate=13, switching to quiet operation
...
hda: switching to spin down
hda: spun up by activity (bash)
status
current status in (sample_time ios/sec mode) format
root@apu:/proc/aam/hda # cat status
14460 0 low
Goes well with the laptop mode patch posted before. It's a bit of an experiement, so.... The code itself is solid, though. Patch is against 2.4.21-rc2 (with laptop mode applied).
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux 2.4 for PowerPC
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.877 -> 1.878
# drivers/block/Config.in 1.6 -> 1.7
# drivers/ide/ide-probe.c 1.28 -> 1.29
# include/linux/blkdev.h 1.24 -> 1.25
# drivers/ide/ide-disk.c 1.18 -> 1.19
# drivers/block/ll_rw_blk.c 1.42 -> 1.43
# Documentation/Configure.help 1.124 -> 1.125
# drivers/ide/ide-io.c 1.4 -> 1.5
# drivers/block/Makefile 1.5 -> 1.6
# (new) -> 1.1 drivers/block/blk-aam.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/14 axboe@apu.(none) 1.878
# Automatic acoustic management
# --------------------------------------------
#
Documentation/Configure.help +22 -0
@@ -561,6 +561,28 @@ If unsure, say N. +Automatic acoustic management +CONFIG_BLK_AAM + If you say yes here, the kernel can manage the acoustic level of your + drives. Currently only IDE drives are supported. If the rate of IO + rises above the specificed level, the drive is switched to fast (or + louder) mode. Drive is switched back to slow (or quiet) mode if the + IO rate drops below the specified level. See + + /proc/aam/hdX/ + + for the tuning knobs. + + This will work on any IDE drive that supports acoustic management, however + the primary target is power consumption on laptops. The lower acoustic + level is just an added bonus. Seeks are typically 20% faster in loud mode + than in quiet mode. + + Selecting this option is safe on drives that don't support acoustic + management, it just won't do anything. + + Say Y on a laptop or quiet work station kernel. + Per partition statistics in /proc/partitions CONFIG_BLK_STATS If you say yes here, your kernel will keep statistical information
drivers/block/Config.in +2 -0
@@ -48,6 +48,8 @@ fi dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM +bool 'Automatic acoustic management' CONFIG_BLK_AAM + bool 'Per partition statistics in /proc/partitions' CONFIG_BLK_STATS endmenu
drivers/block/Makefile +2 -1
@@ -10,7 +10,7 @@ O_TARGET := block.o -export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o acsi.o +export-objs := ll_rw_blk.o blkpg.o loop.o DAC960.o genhd.o acsi.o blk-aam.o obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o
@@ -31,6 +31,7 @@ obj-$(CONFIG_BLK_DEV_DAC960) += DAC960.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o +obj-$(CONFIG_BLK_AAM) += blk-aam.o subdir-$(CONFIG_PARIDE) += paride
drivers/block/blk-aam.c new file +478 -0
478 lines not on this page · raw message
drivers/block/ll_rw_blk.c +21 -0
@@ -31,6 +31,7 @@#include <linux/highmem.h> #include <linux/slab.h> #include <linux/module.h> +#include <linux/proc_fs.h> /* * MAC Floppy IWM hooks
@@ -125,6 +126,10 @@static struct timer_list writeback_timer; +#ifdef CONFIG_BLK_AAM +static struct proc_dir_entry *blk_aam_root; +#endif +static inline int get_max_sectors (kdev_t dev) {if (!max_sectors[MAJOR (dev)])
@@ -379,6 +384,11 @@spin_unlock_irqrestore (&io_request_lock, flags); } +void blk_queue_set_name (request_queue_t *q,const char *name) +{ +strncpy (q->name, name,sizeof (q->name)); +} +/** blk_grow_request_list * @q: The &request_queue_t * @nr_requests: how many requests are desired
@@ -495,6 +505,10 @@ q->plug_tq.routine = &generic_unplug_device; q->plug_tq.data = q; q->plugged =0 ; + q->power =NULL ; + q->proc =NULL ; +memset (q->name,0 ,sizeof (q->name)); +/* * These booleans describe the queue properties. We set the * default (and most common) values here. Other drivers can
@@ -804,6 +818,8 @@ {drive_stat_acct (req->rq_dev, req->cmd, req->nr_sectors,1 ); +blk_power_acct (q); +if (!q->plugged && q->head_active && insert_here == &q->queue_head) {spin_unlock_irq (&io_request_lock);BUG ();
@@ -1427,6 +1443,10 @@init_timer (&writeback_timer); writeback_timer.function = blk_writeback_timer; +#ifdef CONFIG_BLK_AAM + blk_aam_root =proc_mkdir ("aam" ,0 ); +#endif +#ifdef CONFIG_AMIGA_Z2RAM z2_init ();#endif
@@ -1542,3 +1562,4 @@EXPORT_SYMBOL (blk_max_pfn);EXPORT_SYMBOL (blk_seg_merge_ok);EXPORT_SYMBOL (blk_nohighio); +EXPORT_SYMBOL (blk_queue_set_name);
drivers/ide/ide-disk.c +24 -0
@@ -1552,6 +1552,24 @@return 0 ; } +static void idedisk_power_fn (request_queue_t *q) +{ +ide_drive_t *drive = q->queuedata; +struct blk_power *p = q->power; + +switch (p->power_state) { +case BLK_POWER_HIGH : +set_acoustic (drive,0xfe ); +break ; +case BLK_POWER_LOW : +set_acoustic (drive,0x80 ); +break ; +case BLK_POWER_IDLE : +do_idedisk_standby (drive); +break ; + } +} +static int probe_lba_addressing (ide_drive_t *drive,int arg) { drive->addressing =0 ;
@@ -1734,6 +1752,12 @@ drive->no_io_32bit = id->dword_io ?1 :0 ;if (drive->id->cfs_enable_2 &0x3000 )write_cache (drive, (id->cfs_enable_2 &0x3000 )); + +/* +* acoustic management supported +*/ +if ((id->command_set_2 &0x200 ) && (id->cfs_enable_2 &0x200 )) +blk_set_power_fn (&drive->queue, idedisk_power_fn); }static int idedisk_cleanup (ide_drive_t *drive)
drivers/ide/ide-io.c +3 -1
@@ -893,7 +893,9 @@*/ void do_ide_request (request_queue_t *q) { -ide_do_request (q->queuedata,IDE_NO_IRQ ); +ide_drive_t *drive = q->queuedata; + +ide_do_request (HWGROUP (drive),IDE_NO_IRQ ); }/*
drivers/ide/ide-probe.c +3 -1
@@ -970,8 +970,10 @@ {request_queue_t *q = &drive->queue; - q->queuedata =HWGROUP (drive);blk_init_queue (q, do_ide_request); + q->queuedata = drive; + +blk_queue_set_name (q, drive->name); }#undef __IRQ_HELL_SPIN
include/linux/blkdev.h +69 -0
105 lines not on this page · raw message
Signature · 1 line
Jens Axboe