1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/blkdev.h>
17#include <linux/cgroup.h>
18#include <linux/elevator.h>
19#include <linux/ktime.h>
20#include <linux/rbtree.h>
21#include <linux/ioprio.h>
22#include <linux/sbitmap.h>
23#include <linux/delay.h>
24
25#include "bfq-iosched.h"
26
27#if defined(CONFIG_BFQ_GROUP_IOSCHED) && defined(CONFIG_DEBUG_BLK_CGROUP)
28
29
30enum bfqg_stats_flags {
31 BFQG_stats_waiting = 0,
32 BFQG_stats_idling,
33 BFQG_stats_empty,
34};
35
36#define BFQG_FLAG_FNS(name) \
37static void bfqg_stats_mark_##name(struct bfqg_stats *stats) \
38{ \
39 stats->flags |= (1 << BFQG_stats_##name); \
40} \
41static void bfqg_stats_clear_##name(struct bfqg_stats *stats) \
42{ \
43 stats->flags &= ~(1 << BFQG_stats_##name); \
44} \
45static int bfqg_stats_##name(struct bfqg_stats *stats) \
46{ \
47 return (stats->flags & (1 << BFQG_stats_##name)) != 0; \
48} \
49
50BFQG_FLAG_FNS(waiting)
51BFQG_FLAG_FNS(idling)
52BFQG_FLAG_FNS(empty)
53#undef BFQG_FLAG_FNS
54
55
56static void bfqg_stats_update_group_wait_time(struct bfqg_stats *stats)
57{
58 u64 now;
59
60 if (!bfqg_stats_waiting(stats))
61 return;
62
63 now = ktime_get_ns();
64 if (now > stats->start_group_wait_time)
65 blkg_stat_add(&stats->group_wait_time,
66 now - stats->start_group_wait_time);
67 bfqg_stats_clear_waiting(stats);
68}
69
70
71static void bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg,
72 struct bfq_group *curr_bfqg)
73{
74 struct bfqg_stats *stats = &bfqg->stats;
75
76 if (bfqg_stats_waiting(stats))
77 return;
78 if (bfqg == curr_bfqg)
79 return;
80 stats->start_group_wait_time = ktime_get_ns();
81 bfqg_stats_mark_waiting(stats);
82}
83
84
85static void bfqg_stats_end_empty_time(struct bfqg_stats *stats)
86{
87 u64 now;
88
89 if (!bfqg_stats_empty(stats))
90 return;
91
92 now = ktime_get_ns();
93 if (now > stats->start_empty_time)
94 blkg_stat_add(&stats->empty_time,
95 now - stats->start_empty_time);
96 bfqg_stats_clear_empty(stats);
97}
98
99void bfqg_stats_update_dequeue(struct bfq_group *bfqg)
100{
101 blkg_stat_add(&bfqg->stats.dequeue, 1);
102}
103
104void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg)
105{
106 struct bfqg_stats *stats = &bfqg->stats;
107
108 if (blkg_rwstat_total(&stats->queued))
109 return;
110
111
112
113
114
115
116 if (bfqg_stats_empty(stats))
117 return;
118
119 stats->start_empty_time = ktime_get_ns();
120 bfqg_stats_mark_empty(stats);
121}
122
123void bfqg_stats_update_idle_time(struct bfq_group *bfqg)
124{
125 struct bfqg_stats *stats = &bfqg->stats;
126
127 if (bfqg_stats_idling(stats)) {
128 u64 now = ktime_get_ns();
129
130 if (now > stats->start_idle_time)
131 blkg_stat_add(&stats->idle_time,
132 now - stats->start_idle_time);
133 bfqg_stats_clear_idling(stats);
134 }
135}
136
137void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg)
138{
139 struct bfqg_stats *stats = &bfqg->stats;
140
141 stats->start_idle_time = ktime_get_ns();
142 bfqg_stats_mark_idling(stats);
143}
144
145void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg)
146{
147 struct bfqg_stats *stats = &bfqg->stats;
148
149 blkg_stat_add(&stats->avg_queue_size_sum,
150 blkg_rwstat_total(&stats->queued));
151 blkg_stat_add(&stats->avg_queue_size_samples, 1);
152 bfqg_stats_update_group_wait_time(stats);
153}
154
155void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
156 unsigned int op)
157{
158 blkg_rwstat_add(&bfqg->stats.queued, op, 1);
159 bfqg_stats_end_empty_time(&bfqg->stats);
160 if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue))
161 bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq));
162}
163
164void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op)
165{
166 blkg_rwstat_add(&bfqg->stats.queued, op, -1);
167}
168
169void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op)
170{
171 blkg_rwstat_add(&bfqg->stats.merged, op, 1);
172}
173
174void bfqg_stats_update_completion(struct bfq_group *bfqg, u64 start_time_ns,
175 u64 io_start_time_ns, unsigned int op)
176{
177 struct bfqg_stats *stats = &bfqg->stats;
178 u64 now = ktime_get_ns();
179
180 if (now > io_start_time_ns)
181 blkg_rwstat_add(&stats->service_time, op,
182 now - io_start_time_ns);
183 if (io_start_time_ns > start_time_ns)
184 blkg_rwstat_add(&stats->wait_time, op,
185 io_start_time_ns - start_time_ns);
186}
187
188#else
189
190void bfqg_stats_update_io_add(struct bfq_group *bfqg, struct bfq_queue *bfqq,
191 unsigned int op) { }
192void bfqg_stats_update_io_remove(struct bfq_group *bfqg, unsigned int op) { }
193void bfqg_stats_update_io_merged(struct bfq_group *bfqg, unsigned int op) { }
194void bfqg_stats_update_completion(struct bfq_group *bfqg, u64 start_time_ns,
195 u64 io_start_time_ns, unsigned int op) { }
196void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { }
197void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { }
198void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
199void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
200void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
201
202#endif
203
204#ifdef CONFIG_BFQ_GROUP_IOSCHED
205
206
207
208
209
210
211
212static struct bfq_group *pd_to_bfqg(struct blkg_policy_data *pd)
213{
214 return pd ? container_of(pd, struct bfq_group, pd) : NULL;
215}
216
217struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg)
218{
219 return pd_to_blkg(&bfqg->pd);
220}
221
222static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg)
223{
224 return pd_to_bfqg(blkg_to_pd(blkg, &blkcg_policy_bfq));
225}
226
227
228
229
230
231
232
233
234static struct bfq_group *bfqg_parent(struct bfq_group *bfqg)
235{
236 struct blkcg_gq *pblkg = bfqg_to_blkg(bfqg)->parent;
237
238 return pblkg ? blkg_to_bfqg(pblkg) : NULL;
239}
240
241struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
242{
243 struct bfq_entity *group_entity = bfqq->entity.parent;
244
245 return group_entity ? container_of(group_entity, struct bfq_group,
246 entity) :
247 bfqq->bfqd->root_group;
248}
249
250
251
252
253
254
255static void bfqg_get(struct bfq_group *bfqg)
256{
257 bfqg->ref++;
258}
259
260static void bfqg_put(struct bfq_group *bfqg)
261{
262 bfqg->ref--;
263
264 if (bfqg->ref == 0)
265 kfree(bfqg);
266}
267
268static void bfqg_and_blkg_get(struct bfq_group *bfqg)
269{
270
271 bfqg_get(bfqg);
272
273 blkg_get(bfqg_to_blkg(bfqg));
274}
275
276void bfqg_and_blkg_put(struct bfq_group *bfqg)
277{
278 blkg_put(bfqg_to_blkg(bfqg));
279
280 bfqg_put(bfqg);
281}
282
283
284static void bfqg_stats_reset(struct bfqg_stats *stats)
285{
286#ifdef CONFIG_DEBUG_BLK_CGROUP
287
288 blkg_rwstat_reset(&stats->merged);
289 blkg_rwstat_reset(&stats->service_time);
290 blkg_rwstat_reset(&stats->wait_time);
291 blkg_stat_reset(&stats->time);
292 blkg_stat_reset(&stats->avg_queue_size_sum);
293 blkg_stat_reset(&stats->avg_queue_size_samples);
294 blkg_stat_reset(&stats->dequeue);
295 blkg_stat_reset(&stats->group_wait_time);
296 blkg_stat_reset(&stats->idle_time);
297 blkg_stat_reset(&stats->empty_time);
298#endif
299}
300
301
302static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from)
303{
304 if (!to || !from)
305 return;
306
307#ifdef CONFIG_DEBUG_BLK_CGROUP
308
309 blkg_rwstat_add_aux(&to->merged, &from->merged);
310 blkg_rwstat_add_aux(&to->service_time, &from->service_time);
311 blkg_rwstat_add_aux(&to->wait_time, &from->wait_time);
312 blkg_stat_add_aux(&from->time, &from->time);
313 blkg_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum);
314 blkg_stat_add_aux(&to->avg_queue_size_samples,
315 &from->avg_queue_size_samples);
316 blkg_stat_add_aux(&to->dequeue, &from->dequeue);
317 blkg_stat_add_aux(&to->group_wait_time, &from->group_wait_time);
318 blkg_stat_add_aux(&to->idle_time, &from->idle_time);
319 blkg_stat_add_aux(&to->empty_time, &from->empty_time);
320#endif
321}
322
323
324
325
326
327
328static void bfqg_stats_xfer_dead(struct bfq_group *bfqg)
329{
330 struct bfq_group *parent;
331
332 if (!bfqg)
333 return;
334
335 parent = bfqg_parent(bfqg);
336
337 lockdep_assert_held(&bfqg_to_blkg(bfqg)->q->queue_lock);
338
339 if (unlikely(!parent))
340 return;
341
342 bfqg_stats_add_aux(&parent->stats, &bfqg->stats);
343 bfqg_stats_reset(&bfqg->stats);
344}
345
346void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg)
347{
348 struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
349
350 entity->weight = entity->new_weight;
351 entity->orig_weight = entity->new_weight;
352 if (bfqq) {
353 bfqq->ioprio = bfqq->new_ioprio;
354 bfqq->ioprio_class = bfqq->new_ioprio_class;
355
356
357
358
359 bfqg_and_blkg_get(bfqg);
360 }
361 entity->parent = bfqg->my_entity;
362 entity->sched_data = &bfqg->sched_data;
363}
364
365static void bfqg_stats_exit(struct bfqg_stats *stats)
366{
367#ifdef CONFIG_DEBUG_BLK_CGROUP
368 blkg_rwstat_exit(&stats->merged);
369 blkg_rwstat_exit(&stats->service_time);
370 blkg_rwstat_exit(&stats->wait_time);
371 blkg_rwstat_exit(&stats->queued);
372 blkg_stat_exit(&stats->time);
373 blkg_stat_exit(&stats->avg_queue_size_sum);
374 blkg_stat_exit(&stats->avg_queue_size_samples);
375 blkg_stat_exit(&stats->dequeue);
376 blkg_stat_exit(&stats->group_wait_time);
377 blkg_stat_exit(&stats->idle_time);
378 blkg_stat_exit(&stats->empty_time);
379#endif
380}
381
382static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
383{
384#ifdef CONFIG_DEBUG_BLK_CGROUP
385 if (blkg_rwstat_init(&stats->merged, gfp) ||
386 blkg_rwstat_init(&stats->service_time, gfp) ||
387 blkg_rwstat_init(&stats->wait_time, gfp) ||
388 blkg_rwstat_init(&stats->queued, gfp) ||
389 blkg_stat_init(&stats->time, gfp) ||
390 blkg_stat_init(&stats->avg_queue_size_sum, gfp) ||
391 blkg_stat_init(&stats->avg_queue_size_samples, gfp) ||
392 blkg_stat_init(&stats->dequeue, gfp) ||
393 blkg_stat_init(&stats->group_wait_time, gfp) ||
394 blkg_stat_init(&stats->idle_time, gfp) ||
395 blkg_stat_init(&stats->empty_time, gfp)) {
396 bfqg_stats_exit(stats);
397 return -ENOMEM;
398 }
399#endif
400
401 return 0;
402}
403
404static struct bfq_group_data *cpd_to_bfqgd(struct blkcg_policy_data *cpd)
405{
406 return cpd ? container_of(cpd, struct bfq_group_data, pd) : NULL;
407}
408
409static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg)
410{
411 return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq));
412}
413
414static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp)
415{
416 struct bfq_group_data *bgd;
417
418 bgd = kzalloc(sizeof(*bgd), gfp);
419 if (!bgd)
420 return NULL;
421 return &bgd->pd;
422}
423
424static void bfq_cpd_init(struct blkcg_policy_data *cpd)
425{
426 struct bfq_group_data *d = cpd_to_bfqgd(cpd);
427
428 d->weight = cgroup_subsys_on_dfl(io_cgrp_subsys) ?
429 CGROUP_WEIGHT_DFL : BFQ_WEIGHT_LEGACY_DFL;
430}
431
432static void bfq_cpd_free(struct blkcg_policy_data *cpd)
433{
434 kfree(cpd_to_bfqgd(cpd));
435}
436
437static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node)
438{
439 struct bfq_group *bfqg;
440
441 bfqg = kzalloc_node(sizeof(*bfqg), gfp, node);
442 if (!bfqg)
443 return NULL;
444
445 if (bfqg_stats_init(&bfqg->stats, gfp)) {
446 kfree(bfqg);
447 return NULL;
448 }
449
450
451 bfqg_get(bfqg);
452 return &bfqg->pd;
453}
454
455static void bfq_pd_init(struct blkg_policy_data *pd)
456{
457 struct blkcg_gq *blkg = pd_to_blkg(pd);
458 struct bfq_group *bfqg = blkg_to_bfqg(blkg);
459 struct bfq_data *bfqd = blkg->q->elevator->elevator_data;
460 struct bfq_entity *entity = &bfqg->entity;
461 struct bfq_group_data *d = blkcg_to_bfqgd(blkg->blkcg);
462
463 entity->orig_weight = entity->weight = entity->new_weight = d->weight;
464 entity->my_sched_data = &bfqg->sched_data;
465 bfqg->my_entity = entity;
466
467
468
469 bfqg->bfqd = bfqd;
470 bfqg->active_entities = 0;
471 bfqg->rq_pos_tree = RB_ROOT;
472}
473
474static void bfq_pd_free(struct blkg_policy_data *pd)
475{
476 struct bfq_group *bfqg = pd_to_bfqg(pd);
477
478 bfqg_stats_exit(&bfqg->stats);
479 bfqg_put(bfqg);
480}
481
482static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
483{
484 struct bfq_group *bfqg = pd_to_bfqg(pd);
485
486 bfqg_stats_reset(&bfqg->stats);
487}
488
489static void bfq_group_set_parent(struct bfq_group *bfqg,
490 struct bfq_group *parent)
491{
492 struct bfq_entity *entity;
493
494 entity = &bfqg->entity;
495 entity->parent = parent->my_entity;
496 entity->sched_data = &parent->sched_data;
497}
498
499static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd,
500 struct blkcg *blkcg)
501{
502 struct blkcg_gq *blkg;
503
504 blkg = blkg_lookup(blkcg, bfqd->queue);
505 if (likely(blkg))
506 return blkg_to_bfqg(blkg);
507 return NULL;
508}
509
510struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
511 struct blkcg *blkcg)
512{
513 struct bfq_group *bfqg, *parent;
514 struct bfq_entity *entity;
515
516 bfqg = bfq_lookup_bfqg(bfqd, blkcg);
517
518 if (unlikely(!bfqg))
519 return NULL;
520
521
522
523
524
525
526 entity = &bfqg->entity;
527 for_each_entity(entity) {
528 bfqg = container_of(entity, struct bfq_group, entity);
529 if (bfqg != bfqd->root_group) {
530 parent = bfqg_parent(bfqg);
531 if (!parent)
532 parent = bfqd->root_group;
533 bfq_group_set_parent(bfqg, parent);
534 }
535 }
536
537 return bfqg;
538}
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
555 struct bfq_group *bfqg)
556{
557 struct bfq_entity *entity = &bfqq->entity;
558
559
560
561
562
563
564
565 if (bfqq == bfqd->in_service_queue)
566 bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
567 false, BFQQE_PREEMPTED);
568
569 if (bfq_bfqq_busy(bfqq))
570 bfq_deactivate_bfqq(bfqd, bfqq, false, false);
571 else if (entity->on_st)
572 bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
573 bfqg_and_blkg_put(bfqq_group(bfqq));
574
575 entity->parent = bfqg->my_entity;
576 entity->sched_data = &bfqg->sched_data;
577
578 bfqg_and_blkg_get(bfqg);
579
580 if (bfq_bfqq_busy(bfqq)) {
581 if (unlikely(!bfqd->nonrot_with_queueing))
582 bfq_pos_tree_add_move(bfqd, bfqq);
583 bfq_activate_bfqq(bfqd, bfqq);
584 }
585
586 if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
587 bfq_schedule_dispatch(bfqd);
588}
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
605 struct bfq_io_cq *bic,
606 struct blkcg *blkcg)
607{
608 struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
609 struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
610 struct bfq_group *bfqg;
611 struct bfq_entity *entity;
612
613 bfqg = bfq_find_set_group(bfqd, blkcg);
614
615 if (unlikely(!bfqg))
616 bfqg = bfqd->root_group;
617
618 if (async_bfqq) {
619 entity = &async_bfqq->entity;
620
621 if (entity->sched_data != &bfqg->sched_data) {
622 bic_set_bfqq(bic, NULL, 0);
623 bfq_log_bfqq(bfqd, async_bfqq,
624 "bic_change_group: %p %d",
625 async_bfqq, async_bfqq->ref);
626 bfq_put_queue(async_bfqq);
627 }
628 }
629
630 if (sync_bfqq) {
631 entity = &sync_bfqq->entity;
632 if (entity->sched_data != &bfqg->sched_data)
633 bfq_bfqq_move(bfqd, sync_bfqq, bfqg);
634 }
635
636 return bfqg;
637}
638
639void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
640{
641 struct bfq_data *bfqd = bic_to_bfqd(bic);
642 struct bfq_group *bfqg = NULL;
643 uint64_t serial_nr;
644
645 rcu_read_lock();
646 serial_nr = __bio_blkcg(bio)->css.serial_nr;
647
648
649
650
651
652 if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr))
653 goto out;
654
655 bfqg = __bfq_bic_change_cgroup(bfqd, bic, __bio_blkcg(bio));
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706 blkg_path(bfqg_to_blkg(bfqg), bfqg->blkg_path, sizeof(bfqg->blkg_path));
707 bic->blkcg_serial_nr = serial_nr;
708out:
709 rcu_read_unlock();
710}
711
712
713
714
715
716static void bfq_flush_idle_tree(struct bfq_service_tree *st)
717{
718 struct bfq_entity *entity = st->first_idle;
719
720 for (; entity ; entity = st->first_idle)
721 __bfq_deactivate_entity(entity, false);
722}
723
724
725
726
727
728
729static void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
730 struct bfq_entity *entity)
731{
732 struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
733
734 bfq_bfqq_move(bfqd, bfqq, bfqd->root_group);
735}
736
737
738
739
740
741
742
743
744static void bfq_reparent_active_entities(struct bfq_data *bfqd,
745 struct bfq_group *bfqg,
746 struct bfq_service_tree *st)
747{
748 struct rb_root *active = &st->active;
749 struct bfq_entity *entity = NULL;
750
751 if (!RB_EMPTY_ROOT(&st->active))
752 entity = bfq_entity_of(rb_first(active));
753
754 for (; entity ; entity = bfq_entity_of(rb_first(active)))
755 bfq_reparent_leaf_entity(bfqd, entity);
756
757 if (bfqg->sched_data.in_service_entity)
758 bfq_reparent_leaf_entity(bfqd,
759 bfqg->sched_data.in_service_entity);
760}
761
762
763
764
765
766
767
768
769
770static void bfq_pd_offline(struct blkg_policy_data *pd)
771{
772 struct bfq_service_tree *st;
773 struct bfq_group *bfqg = pd_to_bfqg(pd);
774 struct bfq_data *bfqd = bfqg->bfqd;
775 struct bfq_entity *entity = bfqg->my_entity;
776 unsigned long flags;
777 int i;
778
779 spin_lock_irqsave(&bfqd->lock, flags);
780
781 if (!entity)
782 goto put_async_queues;
783
784
785
786
787
788 for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
789 st = bfqg->sched_data.service_tree + i;
790
791
792
793
794
795
796 bfq_flush_idle_tree(st);
797
798
799
800
801
802
803
804
805
806
807
808
809
810 bfq_reparent_active_entities(bfqd, bfqg, st);
811 }
812
813 __bfq_deactivate_entity(entity, false);
814
815put_async_queues:
816 bfq_put_async_queues(bfqd, bfqg);
817
818 spin_unlock_irqrestore(&bfqd->lock, flags);
819
820
821
822
823
824
825 bfqg_stats_xfer_dead(bfqg);
826}
827
828void bfq_end_wr_async(struct bfq_data *bfqd)
829{
830 struct blkcg_gq *blkg;
831
832 list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) {
833 struct bfq_group *bfqg = blkg_to_bfqg(blkg);
834
835 bfq_end_wr_async_queues(bfqd, bfqg);
836 }
837 bfq_end_wr_async_queues(bfqd, bfqd->root_group);
838}
839
840static int bfq_io_show_weight(struct seq_file *sf, void *v)
841{
842 struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
843 struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
844 unsigned int val = 0;
845
846 if (bfqgd)
847 val = bfqgd->weight;
848
849 seq_printf(sf, "%u\n", val);
850
851 return 0;
852}
853
854static int bfq_io_set_weight_legacy(struct cgroup_subsys_state *css,
855 struct cftype *cftype,
856 u64 val)
857{
858 struct blkcg *blkcg = css_to_blkcg(css);
859 struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
860 struct blkcg_gq *blkg;
861 int ret = -ERANGE;
862
863 if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT)
864 return ret;
865
866 ret = 0;
867 spin_lock_irq(&blkcg->lock);
868 bfqgd->weight = (unsigned short)val;
869 hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
870 struct bfq_group *bfqg = blkg_to_bfqg(blkg);
871
872 if (!bfqg)
873 continue;
874
875
876
877
878
879
880 if ((unsigned short)val != bfqg->entity.new_weight) {
881 bfqg->entity.new_weight = (unsigned short)val;
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897 smp_wmb();
898 bfqg->entity.prio_changed = 1;
899 }
900 }
901 spin_unlock_irq(&blkcg->lock);
902
903 return ret;
904}
905
906static ssize_t bfq_io_set_weight(struct kernfs_open_file *of,
907 char *buf, size_t nbytes,
908 loff_t off)
909{
910 u64 weight;
911
912 int ret = kstrtoull(strim(buf), 0, &weight);
913
914 if (ret)
915 return ret;
916
917 ret = bfq_io_set_weight_legacy(of_css(of), NULL, weight);
918 return ret ?: nbytes;
919}
920
921#ifdef CONFIG_DEBUG_BLK_CGROUP
922static int bfqg_print_stat(struct seq_file *sf, void *v)
923{
924 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat,
925 &blkcg_policy_bfq, seq_cft(sf)->private, false);
926 return 0;
927}
928
929static int bfqg_print_rwstat(struct seq_file *sf, void *v)
930{
931 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_rwstat,
932 &blkcg_policy_bfq, seq_cft(sf)->private, true);
933 return 0;
934}
935
936static u64 bfqg_prfill_stat_recursive(struct seq_file *sf,
937 struct blkg_policy_data *pd, int off)
938{
939 u64 sum = blkg_stat_recursive_sum(pd_to_blkg(pd),
940 &blkcg_policy_bfq, off);
941 return __blkg_prfill_u64(sf, pd, sum);
942}
943
944static u64 bfqg_prfill_rwstat_recursive(struct seq_file *sf,
945 struct blkg_policy_data *pd, int off)
946{
947 struct blkg_rwstat sum = blkg_rwstat_recursive_sum(pd_to_blkg(pd),
948 &blkcg_policy_bfq,
949 off);
950 return __blkg_prfill_rwstat(sf, pd, &sum);
951}
952
953static int bfqg_print_stat_recursive(struct seq_file *sf, void *v)
954{
955 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
956 bfqg_prfill_stat_recursive, &blkcg_policy_bfq,
957 seq_cft(sf)->private, false);
958 return 0;
959}
960
961static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v)
962{
963 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
964 bfqg_prfill_rwstat_recursive, &blkcg_policy_bfq,
965 seq_cft(sf)->private, true);
966 return 0;
967}
968
969static u64 bfqg_prfill_sectors(struct seq_file *sf, struct blkg_policy_data *pd,
970 int off)
971{
972 u64 sum = blkg_rwstat_total(&pd->blkg->stat_bytes);
973
974 return __blkg_prfill_u64(sf, pd, sum >> 9);
975}
976
977static int bfqg_print_stat_sectors(struct seq_file *sf, void *v)
978{
979 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
980 bfqg_prfill_sectors, &blkcg_policy_bfq, 0, false);
981 return 0;
982}
983
984static u64 bfqg_prfill_sectors_recursive(struct seq_file *sf,
985 struct blkg_policy_data *pd, int off)
986{
987 struct blkg_rwstat tmp = blkg_rwstat_recursive_sum(pd->blkg, NULL,
988 offsetof(struct blkcg_gq, stat_bytes));
989 u64 sum = atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_READ]) +
990 atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_WRITE]);
991
992 return __blkg_prfill_u64(sf, pd, sum >> 9);
993}
994
995static int bfqg_print_stat_sectors_recursive(struct seq_file *sf, void *v)
996{
997 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
998 bfqg_prfill_sectors_recursive, &blkcg_policy_bfq, 0,
999 false);
1000 return 0;
1001}
1002
1003static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf,
1004 struct blkg_policy_data *pd, int off)
1005{
1006 struct bfq_group *bfqg = pd_to_bfqg(pd);
1007 u64 samples = blkg_stat_read(&bfqg->stats.avg_queue_size_samples);
1008 u64 v = 0;
1009
1010 if (samples) {
1011 v = blkg_stat_read(&bfqg->stats.avg_queue_size_sum);
1012 v = div64_u64(v, samples);
1013 }
1014 __blkg_prfill_u64(sf, pd, v);
1015 return 0;
1016}
1017
1018
1019static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v)
1020{
1021 blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
1022 bfqg_prfill_avg_queue_size, &blkcg_policy_bfq,
1023 0, false);
1024 return 0;
1025}
1026#endif
1027
1028struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
1029{
1030 int ret;
1031
1032 ret = blkcg_activate_policy(bfqd->queue, &blkcg_policy_bfq);
1033 if (ret)
1034 return NULL;
1035
1036 return blkg_to_bfqg(bfqd->queue->root_blkg);
1037}
1038
1039struct blkcg_policy blkcg_policy_bfq = {
1040 .dfl_cftypes = bfq_blkg_files,
1041 .legacy_cftypes = bfq_blkcg_legacy_files,
1042
1043 .cpd_alloc_fn = bfq_cpd_alloc,
1044 .cpd_init_fn = bfq_cpd_init,
1045 .cpd_bind_fn = bfq_cpd_init,
1046 .cpd_free_fn = bfq_cpd_free,
1047
1048 .pd_alloc_fn = bfq_pd_alloc,
1049 .pd_init_fn = bfq_pd_init,
1050 .pd_offline_fn = bfq_pd_offline,
1051 .pd_free_fn = bfq_pd_free,
1052 .pd_reset_stats_fn = bfq_pd_reset_stats,
1053};
1054
1055struct cftype bfq_blkcg_legacy_files[] = {
1056 {
1057 .name = "bfq.weight",
1058 .flags = CFTYPE_NOT_ON_ROOT,
1059 .seq_show = bfq_io_show_weight,
1060 .write_u64 = bfq_io_set_weight_legacy,
1061 },
1062
1063
1064 {
1065 .name = "bfq.io_service_bytes",
1066 .private = (unsigned long)&blkcg_policy_bfq,
1067 .seq_show = blkg_print_stat_bytes,
1068 },
1069 {
1070 .name = "bfq.io_serviced",
1071 .private = (unsigned long)&blkcg_policy_bfq,
1072 .seq_show = blkg_print_stat_ios,
1073 },
1074#ifdef CONFIG_DEBUG_BLK_CGROUP
1075 {
1076 .name = "bfq.time",
1077 .private = offsetof(struct bfq_group, stats.time),
1078 .seq_show = bfqg_print_stat,
1079 },
1080 {
1081 .name = "bfq.sectors",
1082 .seq_show = bfqg_print_stat_sectors,
1083 },
1084 {
1085 .name = "bfq.io_service_time",
1086 .private = offsetof(struct bfq_group, stats.service_time),
1087 .seq_show = bfqg_print_rwstat,
1088 },
1089 {
1090 .name = "bfq.io_wait_time",
1091 .private = offsetof(struct bfq_group, stats.wait_time),
1092 .seq_show = bfqg_print_rwstat,
1093 },
1094 {
1095 .name = "bfq.io_merged",
1096 .private = offsetof(struct bfq_group, stats.merged),
1097 .seq_show = bfqg_print_rwstat,
1098 },
1099 {
1100 .name = "bfq.io_queued",
1101 .private = offsetof(struct bfq_group, stats.queued),
1102 .seq_show = bfqg_print_rwstat,
1103 },
1104#endif
1105
1106
1107 {
1108 .name = "bfq.io_service_bytes_recursive",
1109 .private = (unsigned long)&blkcg_policy_bfq,
1110 .seq_show = blkg_print_stat_bytes_recursive,
1111 },
1112 {
1113 .name = "bfq.io_serviced_recursive",
1114 .private = (unsigned long)&blkcg_policy_bfq,
1115 .seq_show = blkg_print_stat_ios_recursive,
1116 },
1117#ifdef CONFIG_DEBUG_BLK_CGROUP
1118 {
1119 .name = "bfq.time_recursive",
1120 .private = offsetof(struct bfq_group, stats.time),
1121 .seq_show = bfqg_print_stat_recursive,
1122 },
1123 {
1124 .name = "bfq.sectors_recursive",
1125 .seq_show = bfqg_print_stat_sectors_recursive,
1126 },
1127 {
1128 .name = "bfq.io_service_time_recursive",
1129 .private = offsetof(struct bfq_group, stats.service_time),
1130 .seq_show = bfqg_print_rwstat_recursive,
1131 },
1132 {
1133 .name = "bfq.io_wait_time_recursive",
1134 .private = offsetof(struct bfq_group, stats.wait_time),
1135 .seq_show = bfqg_print_rwstat_recursive,
1136 },
1137 {
1138 .name = "bfq.io_merged_recursive",
1139 .private = offsetof(struct bfq_group, stats.merged),
1140 .seq_show = bfqg_print_rwstat_recursive,
1141 },
1142 {
1143 .name = "bfq.io_queued_recursive",
1144 .private = offsetof(struct bfq_group, stats.queued),
1145 .seq_show = bfqg_print_rwstat_recursive,
1146 },
1147 {
1148 .name = "bfq.avg_queue_size",
1149 .seq_show = bfqg_print_avg_queue_size,
1150 },
1151 {
1152 .name = "bfq.group_wait_time",
1153 .private = offsetof(struct bfq_group, stats.group_wait_time),
1154 .seq_show = bfqg_print_stat,
1155 },
1156 {
1157 .name = "bfq.idle_time",
1158 .private = offsetof(struct bfq_group, stats.idle_time),
1159 .seq_show = bfqg_print_stat,
1160 },
1161 {
1162 .name = "bfq.empty_time",
1163 .private = offsetof(struct bfq_group, stats.empty_time),
1164 .seq_show = bfqg_print_stat,
1165 },
1166 {
1167 .name = "bfq.dequeue",
1168 .private = offsetof(struct bfq_group, stats.dequeue),
1169 .seq_show = bfqg_print_stat,
1170 },
1171#endif
1172 { }
1173};
1174
1175struct cftype bfq_blkg_files[] = {
1176 {
1177 .name = "bfq.weight",
1178 .flags = CFTYPE_NOT_ON_ROOT,
1179 .seq_show = bfq_io_show_weight,
1180 .write = bfq_io_set_weight,
1181 },
1182 {}
1183};
1184
1185#else
1186
1187void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
1188 struct bfq_group *bfqg) {}
1189
1190void bfq_init_entity(struct bfq_entity *entity, struct bfq_group *bfqg)
1191{
1192 struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
1193
1194 entity->weight = entity->new_weight;
1195 entity->orig_weight = entity->new_weight;
1196 if (bfqq) {
1197 bfqq->ioprio = bfqq->new_ioprio;
1198 bfqq->ioprio_class = bfqq->new_ioprio_class;
1199 }
1200 entity->sched_data = &bfqg->sched_data;
1201}
1202
1203void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio) {}
1204
1205void bfq_end_wr_async(struct bfq_data *bfqd)
1206{
1207 bfq_end_wr_async_queues(bfqd, bfqd->root_group);
1208}
1209
1210struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd, struct blkcg *blkcg)
1211{
1212 return bfqd->root_group;
1213}
1214
1215struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
1216{
1217 return bfqq->bfqd->root_group;
1218}
1219
1220struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
1221{
1222 struct bfq_group *bfqg;
1223 int i;
1224
1225 bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node);
1226 if (!bfqg)
1227 return NULL;
1228
1229 for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
1230 bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
1231
1232 return bfqg;
1233}
1234#endif
1235