aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mm/backing-dev.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 7441bd93b732..8fe3ebd6ac00 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -412,6 +412,7 @@ static void wb_exit(struct bdi_writeback *wb)
412 * protected. 412 * protected.
413 */ 413 */
414static DEFINE_SPINLOCK(cgwb_lock); 414static DEFINE_SPINLOCK(cgwb_lock);
415static struct workqueue_struct *cgwb_release_wq;
415 416
416/** 417/**
417 * wb_congested_get_create - get or create a wb_congested 418 * wb_congested_get_create - get or create a wb_congested
@@ -522,7 +523,7 @@ static void cgwb_release(struct percpu_ref *refcnt)
522{ 523{
523 struct bdi_writeback *wb = container_of(refcnt, struct bdi_writeback, 524 struct bdi_writeback *wb = container_of(refcnt, struct bdi_writeback,
524 refcnt); 525 refcnt);
525 schedule_work(&wb->release_work); 526 queue_work(cgwb_release_wq, &wb->release_work);
526} 527}
527 528
528static void cgwb_kill(struct bdi_writeback *wb) 529static void cgwb_kill(struct bdi_writeback *wb)
@@ -784,6 +785,21 @@ static void cgwb_bdi_register(struct backing_dev_info *bdi)
784 spin_unlock_irq(&cgwb_lock); 785 spin_unlock_irq(&cgwb_lock);
785} 786}
786 787
788static int __init cgwb_init(void)
789{
790 /*
791 * There can be many concurrent release work items overwhelming
792 * system_wq. Put them in a separate wq and limit concurrency.
793 * There's no point in executing many of these in parallel.
794 */
795 cgwb_release_wq = alloc_workqueue("cgwb_release", 0, 1);
796 if (!cgwb_release_wq)
797 return -ENOMEM;
798
799 return 0;
800}
801subsys_initcall(cgwb_init);
802
787#else /* CONFIG_CGROUP_WRITEBACK */ 803#else /* CONFIG_CGROUP_WRITEBACK */
788 804
789static int cgwb_bdi_init(struct backing_dev_info *bdi) 805static int cgwb_bdi_init(struct backing_dev_info *bdi)