blk-mq-cpumap.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /*
  2. * CPU <-> hardware queue mapping helpers
  3. *
  4. * Copyright (C) 2013-2014 Jens Axboe
  5. */
  6. #include <linux/kernel.h>
  7. #include <linux/threads.h>
  8. #include <linux/module.h>
  9. #include <linux/mm.h>
  10. #include <linux/smp.h>
  11. #include <linux/cpu.h>
  12. #include <linux/blk-mq.h>
  13. #include "blk.h"
  14. #include "blk-mq.h"
  15. static int cpu_to_queue_index(unsigned int nr_cpus, unsigned int nr_queues,
  16. const int cpu)
  17. {
  18. return cpu * nr_queues / nr_cpus;
  19. }
  20. static int get_first_sibling(unsigned int cpu)
  21. {
  22. unsigned int ret;
  23. ret = cpumask_first(topology_sibling_cpumask(cpu));
  24. if (ret < nr_cpu_ids)
  25. return ret;
  26. return cpu;
  27. }
  28. int blk_mq_map_queues(struct blk_mq_tag_set *set)
  29. {
  30. unsigned int *map = set->mq_map;
  31. unsigned int nr_queues = set->nr_hw_queues;
  32. unsigned int i, queue, first_sibling;
  33. cpumask_var_t cpus;
  34. queue = 0;
  35. for_each_possible_cpu(i) {
  36. /*
  37. * Easy case - we have equal or more hardware queues. Or
  38. * there are no thread siblings to take into account. Do
  39. * 1:1 if enough, or sequential mapping if less.
  40. */
  41. if (nr_queues >= nr_cpu_ids) {
  42. map[i] = cpu_to_queue_index(nr_cpu_ids, nr_queues,
  43. queue);
  44. queue++;
  45. continue;
  46. }
  47. /*
  48. * Less then nr_cpus queues, and we have some number of
  49. * threads per cores. Map sibling threads to the same
  50. * queue.
  51. */
  52. first_sibling = get_first_sibling(i);
  53. if (first_sibling == i) {
  54. map[i] = cpu_to_queue_index(nr_cpu_ids, nr_queues,
  55. queue);
  56. queue++;
  57. } else
  58. map[i] = map[first_sibling];
  59. }
  60. free_cpumask_var(cpus);
  61. return 0;
  62. }
  63. /*
  64. * We have no quick way of doing reverse lookups. This is only used at
  65. * queue init time, so runtime isn't important.
  66. */
  67. int blk_mq_hw_queue_to_node(unsigned int *mq_map, unsigned int index)
  68. {
  69. int i;
  70. for_each_possible_cpu(i) {
  71. if (index == mq_map[i])
  72. return local_memory_node(cpu_to_node(i));
  73. }
  74. return NUMA_NO_NODE;
  75. }