aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
Diffstat (limited to 'block')
-rw-r--r--block/blk-throttle.c84
1 files changed, 42 insertions, 42 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index dbeef303f27b..b279110ba287 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -26,15 +26,15 @@ static struct blkcg_policy blkcg_policy_throtl;
26/* A workqueue to queue throttle related work */ 26/* A workqueue to queue throttle related work */
27static struct workqueue_struct *kthrotld_workqueue; 27static struct workqueue_struct *kthrotld_workqueue;
28 28
29struct throtl_rb_root { 29struct throtl_service_queue {
30 struct rb_root rb; 30 struct rb_root pending_tree; /* RB tree of active tgs */
31 struct rb_node *left; 31 struct rb_node *first_pending; /* first node in the tree */
32 unsigned int count; 32 unsigned int nr_pending; /* # queued in the tree */
33 unsigned long min_disptime; 33 unsigned long first_pending_disptime; /* disptime of the first tg */
34}; 34};
35 35
36#define THROTL_RB_ROOT (struct throtl_rb_root) { .rb = RB_ROOT, .left = NULL, \ 36#define THROTL_SERVICE_QUEUE_INITIALIZER \
37 .count = 0, .min_disptime = 0} 37 (struct throtl_service_queue){ .pending_tree = RB_ROOT }
38 38
39#define rb_entry_tg(node) rb_entry((node), struct throtl_grp, rb_node) 39#define rb_entry_tg(node) rb_entry((node), struct throtl_grp, rb_node)
40 40
@@ -50,7 +50,7 @@ struct throtl_grp {
50 /* must be the first member */ 50 /* must be the first member */
51 struct blkg_policy_data pd; 51 struct blkg_policy_data pd;
52 52
53 /* active throtl group service_tree member */ 53 /* active throtl group service_queue member */
54 struct rb_node rb_node; 54 struct rb_node rb_node;
55 55
56 /* 56 /*
@@ -93,7 +93,7 @@ struct throtl_grp {
93struct throtl_data 93struct throtl_data
94{ 94{
95 /* service tree for active throtl groups */ 95 /* service tree for active throtl groups */
96 struct throtl_rb_root tg_service_tree; 96 struct throtl_service_queue service_queue;
97 97
98 struct request_queue *queue; 98 struct request_queue *queue;
99 99
@@ -296,17 +296,17 @@ static struct throtl_grp *throtl_lookup_create_tg(struct throtl_data *td,
296 return tg; 296 return tg;
297} 297}
298 298
299static struct throtl_grp *throtl_rb_first(struct throtl_rb_root *root) 299static struct throtl_grp *throtl_rb_first(struct throtl_service_queue *sq)
300{ 300{
301 /* Service tree is empty */ 301 /* Service tree is empty */
302 if (!root->count) 302 if (!sq->nr_pending)
303 return NULL; 303 return NULL;
304 304
305 if (!root->left) 305 if (!sq->first_pending)
306 root->left = rb_first(&root->rb); 306 sq->first_pending = rb_first(&sq->pending_tree);
307 307
308 if (root->left) 308 if (sq->first_pending)
309 return rb_entry_tg(root->left); 309 return rb_entry_tg(sq->first_pending);
310 310
311 return NULL; 311 return NULL;
312} 312}
@@ -317,29 +317,29 @@ static void rb_erase_init(struct rb_node *n, struct rb_root *root)
317 RB_CLEAR_NODE(n); 317 RB_CLEAR_NODE(n);
318} 318}
319 319
320static void throtl_rb_erase(struct rb_node *n, struct throtl_rb_root *root) 320static void throtl_rb_erase(struct rb_node *n, struct throtl_service_queue *sq)
321{ 321{
322 if (root->left == n) 322 if (sq->first_pending == n)
323 root->left = NULL; 323 sq->first_pending = NULL;
324 rb_erase_init(n, &root->rb); 324 rb_erase_init(n, &sq->pending_tree);
325 --root->count; 325 --sq->nr_pending;
326} 326}
327 327
328static void update_min_dispatch_time(struct throtl_rb_root *st) 328static void update_min_dispatch_time(struct throtl_service_queue *sq)
329{ 329{
330 struct throtl_grp *tg; 330 struct throtl_grp *tg;
331 331
332 tg = throtl_rb_first(st); 332 tg = throtl_rb_first(sq);
333 if (!tg) 333 if (!tg)
334 return; 334 return;
335 335
336 st->min_disptime = tg->disptime; 336 sq->first_pending_disptime = tg->disptime;
337} 337}
338 338
339static void 339static void tg_service_queue_add(struct throtl_service_queue *sq,
340tg_service_tree_add(struct throtl_rb_root *st, struct throtl_grp *tg) 340 struct throtl_grp *tg)
341{ 341{
342 struct rb_node **node = &st->rb.rb_node; 342 struct rb_node **node = &sq->pending_tree.rb_node;
343 struct rb_node *parent = NULL; 343 struct rb_node *parent = NULL;
344 struct throtl_grp *__tg; 344 struct throtl_grp *__tg;
345 unsigned long key = tg->disptime; 345 unsigned long key = tg->disptime;
@@ -358,19 +358,19 @@ tg_service_tree_add(struct throtl_rb_root *st, struct throtl_grp *tg)
358 } 358 }
359 359
360 if (left) 360 if (left)
361 st->left = &tg->rb_node; 361 sq->first_pending = &tg->rb_node;
362 362
363 rb_link_node(&tg->rb_node, parent, node); 363 rb_link_node(&tg->rb_node, parent, node);
364 rb_insert_color(&tg->rb_node, &st->rb); 364 rb_insert_color(&tg->rb_node, &sq->pending_tree);
365} 365}
366 366
367static void __throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg) 367static void __throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg)
368{ 368{
369 struct throtl_rb_root *st = &td->tg_service_tree; 369 struct throtl_service_queue *sq = &td->service_queue;
370 370
371 tg_service_tree_add(st, tg); 371 tg_service_queue_add(sq, tg);
372 throtl_mark_tg_on_rr(tg); 372 throtl_mark_tg_on_rr(tg);
373 st->count++; 373 sq->nr_pending++;
374} 374}
375 375
376static void throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg) 376static void throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg)
@@ -381,7 +381,7 @@ static void throtl_enqueue_tg(struct throtl_data *td, struct throtl_grp *tg)
381 381
382static void __throtl_dequeue_tg(struct throtl_data *td, struct throtl_grp *tg) 382static void __throtl_dequeue_tg(struct throtl_data *td, struct throtl_grp *tg)
383{ 383{
384 throtl_rb_erase(&tg->rb_node, &td->tg_service_tree); 384 throtl_rb_erase(&tg->rb_node, &td->service_queue);
385 throtl_clear_tg_on_rr(tg); 385 throtl_clear_tg_on_rr(tg);
386} 386}
387 387
@@ -403,18 +403,18 @@ static void throtl_schedule_delayed_work(struct throtl_data *td,
403 403
404static void throtl_schedule_next_dispatch(struct throtl_data *td) 404static void throtl_schedule_next_dispatch(struct throtl_data *td)
405{ 405{
406 struct throtl_rb_root *st = &td->tg_service_tree; 406 struct throtl_service_queue *sq = &td->service_queue;
407 407
408 /* any pending children left? */ 408 /* any pending children left? */
409 if (!st->count) 409 if (!sq->nr_pending)
410 return; 410 return;
411 411
412 update_min_dispatch_time(st); 412 update_min_dispatch_time(sq);
413 413
414 if (time_before_eq(st->min_disptime, jiffies)) 414 if (time_before_eq(sq->first_pending_disptime, jiffies))
415 throtl_schedule_delayed_work(td, 0); 415 throtl_schedule_delayed_work(td, 0);
416 else 416 else
417 throtl_schedule_delayed_work(td, (st->min_disptime - jiffies)); 417 throtl_schedule_delayed_work(td, sq->first_pending_disptime - jiffies);
418} 418}
419 419
420static inline void 420static inline void
@@ -794,10 +794,10 @@ static int throtl_select_dispatch(struct throtl_data *td, struct bio_list *bl)
794{ 794{
795 unsigned int nr_disp = 0; 795 unsigned int nr_disp = 0;
796 struct throtl_grp *tg; 796 struct throtl_grp *tg;
797 struct throtl_rb_root *st = &td->tg_service_tree; 797 struct throtl_service_queue *sq = &td->service_queue;
798 798
799 while (1) { 799 while (1) {
800 tg = throtl_rb_first(st); 800 tg = throtl_rb_first(sq);
801 801
802 if (!tg) 802 if (!tg)
803 break; 803 break;
@@ -1145,7 +1145,7 @@ void blk_throtl_drain(struct request_queue *q)
1145 __releases(q->queue_lock) __acquires(q->queue_lock) 1145 __releases(q->queue_lock) __acquires(q->queue_lock)
1146{ 1146{
1147 struct throtl_data *td = q->td; 1147 struct throtl_data *td = q->td;
1148 struct throtl_rb_root *st = &td->tg_service_tree; 1148 struct throtl_service_queue *sq = &td->service_queue;
1149 struct throtl_grp *tg; 1149 struct throtl_grp *tg;
1150 struct bio_list bl; 1150 struct bio_list bl;
1151 struct bio *bio; 1151 struct bio *bio;
@@ -1154,7 +1154,7 @@ void blk_throtl_drain(struct request_queue *q)
1154 1154
1155 bio_list_init(&bl); 1155 bio_list_init(&bl);
1156 1156
1157 while ((tg = throtl_rb_first(st))) { 1157 while ((tg = throtl_rb_first(sq))) {
1158 throtl_dequeue_tg(td, tg); 1158 throtl_dequeue_tg(td, tg);
1159 1159
1160 while ((bio = bio_list_peek(&tg->bio_lists[READ]))) 1160 while ((bio = bio_list_peek(&tg->bio_lists[READ])))
@@ -1179,7 +1179,7 @@ int blk_throtl_init(struct request_queue *q)
1179 if (!td) 1179 if (!td)
1180 return -ENOMEM; 1180 return -ENOMEM;
1181 1181
1182 td->tg_service_tree = THROTL_RB_ROOT; 1182 td->service_queue = THROTL_SERVICE_QUEUE_INITIALIZER;
1183 INIT_DELAYED_WORK(&td->dispatch_work, blk_throtl_dispatch_work_fn); 1183 INIT_DELAYED_WORK(&td->dispatch_work, blk_throtl_dispatch_work_fn);
1184 1184
1185 q->td = td; 1185 q->td = td;