Skip to content

Commit

Permalink
block: queue work on power efficient wq
Browse files Browse the repository at this point in the history
Block layer uses workqueues for multiple purposes. There is no real dependency
of scheduling these on the cpu which scheduled them.

On a idle system, it is observed that and idle cpu wakes up many times just to
service this work. It would be better if we can schedule it on a cpu which the
scheduler believes to be the most appropriate one.

This patch replaces normal workqueues with power efficient versions.

Cc: Jens Axboe <[email protected]>
Signed-off-by: Viresh Kumar <[email protected]>
Signed-off-by: Tejun Heo <[email protected]>
  • Loading branch information
vireshk authored and htejun committed May 14, 2013
1 parent bbb47bd commit 695588f
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 6 deletions.
3 changes: 2 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3180,7 +3180,8 @@ int __init blk_dev_init(void)

/* used for unplugging and affects IO latency/throughput - HIGHPRI */
kblockd_workqueue = alloc_workqueue("kblockd",
WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
WQ_MEM_RECLAIM | WQ_HIGHPRI |
WQ_POWER_EFFICIENT, 0);
if (!kblockd_workqueue)
panic("Failed to create kblockd\n");

Expand Down
3 changes: 2 additions & 1 deletion block/blk-ioc.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ void put_io_context(struct io_context *ioc)
if (atomic_long_dec_and_test(&ioc->refcount)) {
spin_lock_irqsave(&ioc->lock, flags);
if (!hlist_empty(&ioc->icq_list))
schedule_work(&ioc->release_work);
queue_work(system_power_efficient_wq,
&ioc->release_work);
else
free_ioc = true;
spin_unlock_irqrestore(&ioc->lock, flags);
Expand Down
12 changes: 8 additions & 4 deletions block/genhd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1489,9 +1489,11 @@ static void __disk_unblock_events(struct gendisk *disk, bool check_now)
intv = disk_events_poll_jiffies(disk);
set_timer_slack(&ev->dwork.timer, intv / 4);
if (check_now)
queue_delayed_work(system_freezable_wq, &ev->dwork, 0);
queue_delayed_work(system_freezable_power_efficient_wq,
&ev->dwork, 0);
else if (intv)
queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
queue_delayed_work(system_freezable_power_efficient_wq,
&ev->dwork, intv);
out_unlock:
spin_unlock_irqrestore(&ev->lock, flags);
}
Expand Down Expand Up @@ -1534,7 +1536,8 @@ void disk_flush_events(struct gendisk *disk, unsigned int mask)
spin_lock_irq(&ev->lock);
ev->clearing |= mask;
if (!ev->block)
mod_delayed_work(system_freezable_wq, &ev->dwork, 0);
mod_delayed_work(system_freezable_power_efficient_wq,
&ev->dwork, 0);
spin_unlock_irq(&ev->lock);
}

Expand Down Expand Up @@ -1627,7 +1630,8 @@ static void disk_check_events(struct disk_events *ev,

intv = disk_events_poll_jiffies(disk);
if (!ev->block && intv)
queue_delayed_work(system_freezable_wq, &ev->dwork, intv);
queue_delayed_work(system_freezable_power_efficient_wq,
&ev->dwork, intv);

spin_unlock_irq(&ev->lock);

Expand Down

0 comments on commit 695588f

Please sign in to comment.