ip_vs_rr.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * IPVS: Round-Robin Scheduling module
  3. *
  4. * Version: $Id: ip_vs_rr.c,v 1.9 2002/09/15 08:14:08 wensong Exp $
  5. *
  6. * Authors: Wensong Zhang <wensong@linuxvirtualserver.org>
  7. * Peter Kese <peter.kese@ijs.si>
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU General Public License
  11. * as published by the Free Software Foundation; either version
  12. * 2 of the License, or (at your option) any later version.
  13. *
  14. * Fixes/Changes:
  15. * Wensong Zhang : changed the ip_vs_rr_schedule to return dest
  16. * Julian Anastasov : fixed the NULL pointer access bug in debugging
  17. * Wensong Zhang : changed some comestics things for debugging
  18. * Wensong Zhang : changed for the d-linked destination list
  19. * Wensong Zhang : added the ip_vs_rr_update_svc
  20. * Wensong Zhang : added any dest with weight=0 is quiesced
  21. *
  22. */
  23. #include <linux/module.h>
  24. #include <linux/kernel.h>
  25. #include <net/ip_vs.h>
  26. static int ip_vs_rr_init_svc(struct ip_vs_service *svc)
  27. {
  28. svc->sched_data = &svc->destinations;
  29. return 0;
  30. }
  31. static int ip_vs_rr_done_svc(struct ip_vs_service *svc)
  32. {
  33. return 0;
  34. }
  35. static int ip_vs_rr_update_svc(struct ip_vs_service *svc)
  36. {
  37. svc->sched_data = &svc->destinations;
  38. return 0;
  39. }
  40. /*
  41. * Round-Robin Scheduling
  42. */
  43. static struct ip_vs_dest *
  44. ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
  45. {
  46. struct list_head *p, *q;
  47. struct ip_vs_dest *dest;
  48. IP_VS_DBG(6, "ip_vs_rr_schedule(): Scheduling...\n");
  49. write_lock(&svc->sched_lock);
  50. p = (struct list_head *)svc->sched_data;
  51. p = p->next;
  52. q = p;
  53. do {
  54. /* skip list head */
  55. if (q == &svc->destinations) {
  56. q = q->next;
  57. continue;
  58. }
  59. dest = list_entry(q, struct ip_vs_dest, n_list);
  60. if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
  61. atomic_read(&dest->weight) > 0)
  62. /* HIT */
  63. goto out;
  64. q = q->next;
  65. } while (q != p);
  66. write_unlock(&svc->sched_lock);
  67. return NULL;
  68. out:
  69. svc->sched_data = q;
  70. write_unlock(&svc->sched_lock);
  71. IP_VS_DBG(6, "RR: server %u.%u.%u.%u:%u "
  72. "activeconns %d refcnt %d weight %d\n",
  73. NIPQUAD(dest->addr), ntohs(dest->port),
  74. atomic_read(&dest->activeconns),
  75. atomic_read(&dest->refcnt), atomic_read(&dest->weight));
  76. return dest;
  77. }
  78. static struct ip_vs_scheduler ip_vs_rr_scheduler = {
  79. .name = "rr", /* name */
  80. .refcnt = ATOMIC_INIT(0),
  81. .module = THIS_MODULE,
  82. .init_service = ip_vs_rr_init_svc,
  83. .done_service = ip_vs_rr_done_svc,
  84. .update_service = ip_vs_rr_update_svc,
  85. .schedule = ip_vs_rr_schedule,
  86. };
  87. static int __init ip_vs_rr_init(void)
  88. {
  89. INIT_LIST_HEAD(&ip_vs_rr_scheduler.n_list);
  90. return register_ip_vs_scheduler(&ip_vs_rr_scheduler);
  91. }
  92. static void __exit ip_vs_rr_cleanup(void)
  93. {
  94. unregister_ip_vs_scheduler(&ip_vs_rr_scheduler);
  95. }
  96. module_init(ip_vs_rr_init);
  97. module_exit(ip_vs_rr_cleanup);
  98. MODULE_LICENSE("GPL");