Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196802
b: refs/heads/master
c: 31373d0
h: refs/heads/master
v: v3
  • Loading branch information
Matthew Garrett authored and Jens Axboe committed Apr 6, 2010
1 parent 2627fca commit 5ae49ef
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9195291e5f05e01d67f9a09c756b8aca8f009089
refs/heads/master: 31373d09da5b7fe21fe6f781e92bd534a3495f00
5 changes: 4 additions & 1 deletion trunk/block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ void blk_cleanup_queue(struct request_queue *q)
*/
blk_sync_queue(q);

del_timer_sync(&q->backing_dev_info.laptop_mode_wb_timer);
mutex_lock(&q->sysfs_lock);
queue_flag_set_unlocked(QUEUE_FLAG_DEAD, q);
mutex_unlock(&q->sysfs_lock);
Expand Down Expand Up @@ -511,6 +512,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
return NULL;
}

setup_timer(&q->backing_dev_info.laptop_mode_wb_timer,
laptop_mode_timer_fn, (unsigned long) q);
init_timer(&q->unplug_timer);
setup_timer(&q->timeout, blk_rq_timed_out_timer, (unsigned long) q);
INIT_LIST_HEAD(&q->timeout_list);
Expand Down Expand Up @@ -2101,7 +2104,7 @@ static void blk_finish_request(struct request *req, int error)
BUG_ON(blk_queued_rq(req));

if (unlikely(laptop_mode) && blk_fs_request(req))
laptop_io_completion();
laptop_io_completion(&req->q->backing_dev_info);

blk_delete_timer(req);

Expand Down
3 changes: 3 additions & 0 deletions trunk/include/linux/backing-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/writeback.h>
#include <asm/atomic.h>

Expand Down Expand Up @@ -88,6 +89,8 @@ struct backing_dev_info {

struct device *dev;

struct timer_list laptop_mode_wb_timer;

#ifdef CONFIG_DEBUG_FS
struct dentry *debug_dir;
struct dentry *debug_stats;
Expand Down
4 changes: 3 additions & 1 deletion trunk/include/linux/writeback.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,10 @@ static inline void inode_sync_wait(struct inode *inode)
/*
* mm/page-writeback.c
*/
void laptop_io_completion(void);
void laptop_io_completion(struct backing_dev_info *info);
void laptop_sync_completion(void);
void laptop_mode_sync(struct work_struct *work);
void laptop_mode_timer_fn(unsigned long data);
void throttle_vm_writeout(gfp_t gfp_mask);

/* These are exported to sysctl. */
Expand Down
39 changes: 20 additions & 19 deletions trunk/mm/page-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,10 +683,6 @@ void throttle_vm_writeout(gfp_t gfp_mask)
}
}

static void laptop_timer_fn(unsigned long unused);

static DEFINE_TIMER(laptop_mode_wb_timer, laptop_timer_fn, 0, 0);

/*
* sysctl handler for /proc/sys/vm/dirty_writeback_centisecs
*/
Expand All @@ -697,31 +693,29 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write,
return 0;
}

static void do_laptop_sync(struct work_struct *work)
void laptop_mode_timer_fn(unsigned long data)
{
wakeup_flusher_threads(0);
kfree(work);
}
struct request_queue *q = (struct request_queue *)data;
int nr_pages = global_page_state(NR_FILE_DIRTY) +
global_page_state(NR_UNSTABLE_NFS);

static void laptop_timer_fn(unsigned long unused)
{
struct work_struct *work;
/*
* We want to write everything out, not just down to the dirty
* threshold
*/

work = kmalloc(sizeof(*work), GFP_ATOMIC);
if (work) {
INIT_WORK(work, do_laptop_sync);
schedule_work(work);
}
if (bdi_has_dirty_io(&q->backing_dev_info))
bdi_start_writeback(&q->backing_dev_info, NULL, nr_pages);
}

/*
* We've spun up the disk and we're in laptop mode: schedule writeback
* of all dirty data a few seconds from now. If the flush is already scheduled
* then push it back - the user is still using the disk.
*/
void laptop_io_completion(void)
void laptop_io_completion(struct backing_dev_info *info)
{
mod_timer(&laptop_mode_wb_timer, jiffies + laptop_mode);
mod_timer(&info->laptop_mode_wb_timer, jiffies + laptop_mode);
}

/*
Expand All @@ -731,7 +725,14 @@ void laptop_io_completion(void)
*/
void laptop_sync_completion(void)
{
del_timer(&laptop_mode_wb_timer);
struct backing_dev_info *bdi;

rcu_read_lock();

list_for_each_entry_rcu(bdi, &bdi_list, bdi_list)
del_timer(&bdi->laptop_mode_wb_timer);

rcu_read_unlock();
}

/*
Expand Down

0 comments on commit 5ae49ef

Please sign in to comment.