600-net-core-add-RPS-balancer.patch 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. From 3e969c9695b45e1a052d43b367096ec99f2f0aac Mon Sep 17 00:00:00 2001
  2. From: John Crispin <[email protected]>
  3. Date: Thu, 10 Aug 2017 15:58:29 +0200
  4. Subject: [PATCH] net: core: add RPS balancer
  5. This patch adds a hash bucket based rps hash balancer.
  6. Signed-off-by: John Crispin <[email protected]>
  7. ---
  8. net/core/dev.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
  9. 1 file changed, 56 insertions(+), 1 deletion(-)
  10. --- a/net/core/dev.c
  11. +++ b/net/core/dev.c
  12. @@ -3626,6 +3626,58 @@ set_rps_cpu(struct net_device *dev, stru
  13. return rflow;
  14. }
  15. +#define RPS_TBL_SIZE_SHIFT 10
  16. +#define RPS_TBL_SIZE (1 << RPS_TBL_SIZE_SHIFT)
  17. +struct rps_table {
  18. + int core;
  19. + struct timer_list expire;
  20. +};
  21. +static struct rps_table rps_table[RPS_TBL_SIZE];
  22. +static int rps_table_last_core;
  23. +
  24. +static void rps_table_expire(unsigned long data)
  25. +{
  26. + struct rps_table *entry = (struct rps_table *) data;
  27. +
  28. + entry->core = -1;
  29. +}
  30. +
  31. +static int rps_table_core(struct rps_map *map)
  32. +{
  33. + int i;
  34. +
  35. + for (i = 0; i < map->len; i++) {
  36. + int cpu = map->cpus[(rps_table_last_core + i + 1) % map->len];
  37. + if (cpu_online(cpu)) {
  38. + rps_table_last_core = cpu;
  39. + return cpu;
  40. + }
  41. + }
  42. + return map->cpus[0];
  43. +}
  44. +
  45. +static int rps_table_lookup(struct rps_map *map, u32 hash)
  46. +{
  47. + int bucket = hash & 0x3ff;
  48. +
  49. + if (rps_table[bucket].core < 0)
  50. + rps_table[bucket].core = rps_table_core(map);
  51. + mod_timer(&rps_table[bucket].expire, jiffies + HZ);
  52. +
  53. + return rps_table[bucket].core;
  54. +}
  55. +
  56. +static void rps_table_init(void)
  57. +{
  58. + int i;
  59. +
  60. + for (i = 0; i < RPS_TBL_SIZE; i++) {
  61. + rps_table[i].core = -1;
  62. + setup_timer(&rps_table[i].expire, rps_table_expire,
  63. + (unsigned long) &rps_table[i]);
  64. + }
  65. +}
  66. +
  67. /*
  68. * get_rps_cpu is called from netif_receive_skb and returns the target
  69. * CPU from the RPS map of the receiving queue for a given skb.
  70. @@ -3715,7 +3767,7 @@ static int get_rps_cpu(struct net_device
  71. try_rps:
  72. if (map) {
  73. - tcpu = map->cpus[reciprocal_scale(hash, map->len)];
  74. + tcpu = rps_table_lookup(map, hash);
  75. if (cpu_online(tcpu)) {
  76. cpu = tcpu;
  77. goto done;
  78. @@ -8800,6 +8852,10 @@ static int __init net_dev_init(void)
  79. sd->backlog.weight = weight_p;
  80. }
  81. +#ifdef CONFIG_RPS
  82. + rps_table_init();
  83. +#endif
  84. +
  85. dev_boot_phase = 0;
  86. /* The loopback device is special if any other network devices