diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2010-07-25 07:29:21 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 12:53:56 -0400 |
commit | 253c34e9b10c30d3064be654b5b78fbc1a8b1896 (patch) | |
tree | 1ee077a52fd1036fe26ddfe8cabd5a5315dc1285 /mm | |
parent | fff5b85aa4225a7be157f208277a055822039a9e (diff) |
writeback: prevent unnecessary bdi threads wakeups
Finally, we can get rid of unnecessary wake-ups in bdi threads, which are very
bad for battery-driven devices.
There are two types of activities bdi threads do:
1. process bdi works from the 'bdi->work_list'
2. periodic write-back
So there are 2 sources of wake-up events for bdi threads:
1. 'bdi_queue_work()' - submits bdi works
2. '__mark_inode_dirty()' - adds dirty I/O to bdi's
The former already has bdi wake-up code. The latter does not, and this patch
adds it.
'__mark_inode_dirty()' is hot-path function, but this patch adds another
'spin_lock(&bdi->wb_lock)' there. However, it is taken only in rare cases when
the bdi has no dirty inodes. So adding this spinlock should be fine and should
not affect performance.
This patch makes sure bdi threads and the forker thread do not wake-up if there
is nothing to do. The forker thread will nevertheless wake up at least every
5 min. to check whether it has to kill a bdi thread. This can also be optimized,
but is not worth it.
This patch also tidies up the warning about unregistered bid, and turns it from
an ugly crocodile to a simple 'WARN()' statement.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'mm')
-rw-r--r-- | mm/backing-dev.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 9c1c199f88ce..a9a08d88a745 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -439,10 +439,17 @@ static int bdi_forker_thread(void *ptr) | |||
439 | break; | 439 | break; |
440 | 440 | ||
441 | case NO_ACTION: | 441 | case NO_ACTION: |
442 | if (dirty_writeback_interval) | 442 | if (!wb_has_dirty_io(me) || !dirty_writeback_interval) |
443 | schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10)); | 443 | /* |
444 | * There are no dirty data. The only thing we | ||
445 | * should now care about is checking for | ||
446 | * inactive bdi threads and killing them. Thus, | ||
447 | * let's sleep for longer time, save energy and | ||
448 | * be friendly for battery-driven devices. | ||
449 | */ | ||
450 | schedule_timeout(bdi_longest_inactive()); | ||
444 | else | 451 | else |
445 | schedule(); | 452 | schedule_timeout(msecs_to_jiffies(dirty_writeback_interval * 10)); |
446 | try_to_freeze(); | 453 | try_to_freeze(); |
447 | /* Back to the main loop */ | 454 | /* Back to the main loop */ |
448 | continue; | 455 | continue; |