aboutsummaryrefslogtreecommitdiffstats
path: root/block/blk-throttle.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/blk-throttle.c')
-rw-r--r--block/blk-throttle.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index 381b09bb562b..e36cc10a346c 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -20,6 +20,11 @@ static int throtl_quantum = 32;
20/* Throttling is performed over 100ms slice and after that slice is renewed */ 20/* Throttling is performed over 100ms slice and after that slice is renewed */
21static unsigned long throtl_slice = HZ/10; /* 100 ms */ 21static unsigned long throtl_slice = HZ/10; /* 100 ms */
22 22
23/* A workqueue to queue throttle related work */
24static struct workqueue_struct *kthrotld_workqueue;
25static void throtl_schedule_delayed_work(struct throtl_data *td,
26 unsigned long delay);
27
23struct throtl_rb_root { 28struct throtl_rb_root {
24 struct rb_root rb; 29 struct rb_root rb;
25 struct rb_node *left; 30 struct rb_node *left;
@@ -168,7 +173,15 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td,
168 * tree of blkg (instead of traversing through hash list all 173 * tree of blkg (instead of traversing through hash list all
169 * the time. 174 * the time.
170 */ 175 */
171 tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); 176
177 /*
178 * This is the common case when there are no blkio cgroups.
179 * Avoid lookup in this case
180 */
181 if (blkcg == &blkio_root_cgroup)
182 tg = &td->root_tg;
183 else
184 tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key));
172 185
173 /* Fill in device details for root group */ 186 /* Fill in device details for root group */
174 if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { 187 if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) {
@@ -337,10 +350,9 @@ static void throtl_schedule_next_dispatch(struct throtl_data *td)
337 update_min_dispatch_time(st); 350 update_min_dispatch_time(st);
338 351
339 if (time_before_eq(st->min_disptime, jiffies)) 352 if (time_before_eq(st->min_disptime, jiffies))
340 throtl_schedule_delayed_work(td->queue, 0); 353 throtl_schedule_delayed_work(td, 0);
341 else 354 else
342 throtl_schedule_delayed_work(td->queue, 355 throtl_schedule_delayed_work(td, (st->min_disptime - jiffies));
343 (st->min_disptime - jiffies));
344} 356}
345 357
346static inline void 358static inline void
@@ -807,10 +819,10 @@ void blk_throtl_work(struct work_struct *work)
807} 819}
808 820
809/* Call with queue lock held */ 821/* Call with queue lock held */
810void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay) 822static void
823throtl_schedule_delayed_work(struct throtl_data *td, unsigned long delay)
811{ 824{
812 825
813 struct throtl_data *td = q->td;
814 struct delayed_work *dwork = &td->throtl_work; 826 struct delayed_work *dwork = &td->throtl_work;
815 827
816 if (total_nr_queued(td) > 0) { 828 if (total_nr_queued(td) > 0) {
@@ -819,12 +831,11 @@ void throtl_schedule_delayed_work(struct request_queue *q, unsigned long delay)
819 * Cancel that and schedule a new one. 831 * Cancel that and schedule a new one.
820 */ 832 */
821 __cancel_delayed_work(dwork); 833 __cancel_delayed_work(dwork);
822 kblockd_schedule_delayed_work(q, dwork, delay); 834 queue_delayed_work(kthrotld_workqueue, dwork, delay);
823 throtl_log(td, "schedule work. delay=%lu jiffies=%lu", 835 throtl_log(td, "schedule work. delay=%lu jiffies=%lu",
824 delay, jiffies); 836 delay, jiffies);
825 } 837 }
826} 838}
827EXPORT_SYMBOL(throtl_schedule_delayed_work);
828 839
829static void 840static void
830throtl_destroy_tg(struct throtl_data *td, struct throtl_grp *tg) 841throtl_destroy_tg(struct throtl_data *td, struct throtl_grp *tg)
@@ -912,7 +923,7 @@ static void throtl_update_blkio_group_read_bps(void *key,
912 smp_mb__after_atomic_inc(); 923 smp_mb__after_atomic_inc();
913 924
914 /* Schedule a work now to process the limit change */ 925 /* Schedule a work now to process the limit change */
915 throtl_schedule_delayed_work(td->queue, 0); 926 throtl_schedule_delayed_work(td, 0);
916} 927}
917 928
918static void throtl_update_blkio_group_write_bps(void *key, 929static void throtl_update_blkio_group_write_bps(void *key,
@@ -926,7 +937,7 @@ static void throtl_update_blkio_group_write_bps(void *key,
926 smp_mb__before_atomic_inc(); 937 smp_mb__before_atomic_inc();
927 atomic_inc(&td->limits_changed); 938 atomic_inc(&td->limits_changed);
928 smp_mb__after_atomic_inc(); 939 smp_mb__after_atomic_inc();
929 throtl_schedule_delayed_work(td->queue, 0); 940 throtl_schedule_delayed_work(td, 0);
930} 941}
931 942
932static void throtl_update_blkio_group_read_iops(void *key, 943static void throtl_update_blkio_group_read_iops(void *key,
@@ -940,7 +951,7 @@ static void throtl_update_blkio_group_read_iops(void *key,
940 smp_mb__before_atomic_inc(); 951 smp_mb__before_atomic_inc();
941 atomic_inc(&td->limits_changed); 952 atomic_inc(&td->limits_changed);
942 smp_mb__after_atomic_inc(); 953 smp_mb__after_atomic_inc();
943 throtl_schedule_delayed_work(td->queue, 0); 954 throtl_schedule_delayed_work(td, 0);
944} 955}
945 956
946static void throtl_update_blkio_group_write_iops(void *key, 957static void throtl_update_blkio_group_write_iops(void *key,
@@ -954,7 +965,7 @@ static void throtl_update_blkio_group_write_iops(void *key,
954 smp_mb__before_atomic_inc(); 965 smp_mb__before_atomic_inc();
955 atomic_inc(&td->limits_changed); 966 atomic_inc(&td->limits_changed);
956 smp_mb__after_atomic_inc(); 967 smp_mb__after_atomic_inc();
957 throtl_schedule_delayed_work(td->queue, 0); 968 throtl_schedule_delayed_work(td, 0);
958} 969}
959 970
960void throtl_shutdown_timer_wq(struct request_queue *q) 971void throtl_shutdown_timer_wq(struct request_queue *q)
@@ -1127,6 +1138,10 @@ void blk_throtl_exit(struct request_queue *q)
1127 1138
1128static int __init throtl_init(void) 1139static int __init throtl_init(void)
1129{ 1140{
1141 kthrotld_workqueue = alloc_workqueue("kthrotld", WQ_MEM_RECLAIM, 0);
1142 if (!kthrotld_workqueue)
1143 panic("Failed to create kthrotld\n");
1144
1130 blkio_policy_register(&blkio_policy_throtl); 1145 blkio_policy_register(&blkio_policy_throtl);
1131 return 0; 1146 return 0;
1132} 1147}