mq-deadline-cgroup.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/blk-cgroup.h>
  3. #include <linux/ioprio.h>
  4. #include "mq-deadline-cgroup.h"
  5. static struct blkcg_policy dd_blkcg_policy;
  6. static struct blkcg_policy_data *dd_cpd_alloc(gfp_t gfp)
  7. {
  8. struct dd_blkcg *pd;
  9. pd = kzalloc(sizeof(*pd), gfp);
  10. if (!pd)
  11. return NULL;
  12. pd->stats = alloc_percpu_gfp(typeof(*pd->stats),
  13. GFP_KERNEL | __GFP_ZERO);
  14. if (!pd->stats) {
  15. kfree(pd);
  16. return NULL;
  17. }
  18. return &pd->cpd;
  19. }
  20. static void dd_cpd_free(struct blkcg_policy_data *cpd)
  21. {
  22. struct dd_blkcg *dd_blkcg = container_of(cpd, typeof(*dd_blkcg), cpd);
  23. free_percpu(dd_blkcg->stats);
  24. kfree(dd_blkcg);
  25. }
  26. static struct dd_blkcg *dd_blkcg_from_pd(struct blkg_policy_data *pd)
  27. {
  28. return container_of(blkcg_to_cpd(pd->blkg->blkcg, &dd_blkcg_policy),
  29. struct dd_blkcg, cpd);
  30. }
  31. /*
  32. * Convert an association between a block cgroup and a request queue into a
  33. * pointer to the mq-deadline information associated with a (blkcg, queue) pair.
  34. */
  35. struct dd_blkcg *dd_blkcg_from_bio(struct bio *bio)
  36. {
  37. struct blkg_policy_data *pd;
  38. pd = blkg_to_pd(bio->bi_blkg, &dd_blkcg_policy);
  39. if (!pd)
  40. return NULL;
  41. return dd_blkcg_from_pd(pd);
  42. }
  43. static size_t dd_pd_stat(struct blkg_policy_data *pd, char *buf, size_t size)
  44. {
  45. static const char *const prio_class_name[] = {
  46. [IOPRIO_CLASS_NONE] = "NONE",
  47. [IOPRIO_CLASS_RT] = "RT",
  48. [IOPRIO_CLASS_BE] = "BE",
  49. [IOPRIO_CLASS_IDLE] = "IDLE",
  50. };
  51. struct dd_blkcg *blkcg = dd_blkcg_from_pd(pd);
  52. int res = 0;
  53. u8 prio;
  54. for (prio = 0; prio < ARRAY_SIZE(blkcg->stats->stats); prio++)
  55. res += scnprintf(buf + res, size - res,
  56. " [%s] dispatched=%u inserted=%u merged=%u",
  57. prio_class_name[prio],
  58. ddcg_sum(blkcg, dispatched, prio) +
  59. ddcg_sum(blkcg, merged, prio) -
  60. ddcg_sum(blkcg, completed, prio),
  61. ddcg_sum(blkcg, inserted, prio) -
  62. ddcg_sum(blkcg, completed, prio),
  63. ddcg_sum(blkcg, merged, prio));
  64. return res;
  65. }
  66. static struct blkg_policy_data *dd_pd_alloc(gfp_t gfp, struct request_queue *q,
  67. struct blkcg *blkcg)
  68. {
  69. struct dd_blkg *pd;
  70. pd = kzalloc(sizeof(*pd), gfp);
  71. if (!pd)
  72. return NULL;
  73. return &pd->pd;
  74. }
  75. static void dd_pd_free(struct blkg_policy_data *pd)
  76. {
  77. struct dd_blkg *dd_blkg = container_of(pd, typeof(*dd_blkg), pd);
  78. kfree(dd_blkg);
  79. }
  80. static struct blkcg_policy dd_blkcg_policy = {
  81. .cpd_alloc_fn = dd_cpd_alloc,
  82. .cpd_free_fn = dd_cpd_free,
  83. .pd_alloc_fn = dd_pd_alloc,
  84. .pd_free_fn = dd_pd_free,
  85. .pd_stat_fn = dd_pd_stat,
  86. };
  87. int dd_activate_policy(struct request_queue *q)
  88. {
  89. return blkcg_activate_policy(q, &dd_blkcg_policy);
  90. }
  91. void dd_deactivate_policy(struct request_queue *q)
  92. {
  93. blkcg_deactivate_policy(q, &dd_blkcg_policy);
  94. }
  95. int __init dd_blkcg_init(void)
  96. {
  97. return blkcg_policy_register(&dd_blkcg_policy);
  98. }
  99. void __exit dd_blkcg_exit(void)
  100. {
  101. blkcg_policy_unregister(&dd_blkcg_policy);
  102. }