linux/net/ipv4/ipvs/ip_vs_wlc.c
<<
>>
Prefs
   1/*
   2 * IPVS:        Weighted Least-Connection Scheduling module
   3 *
   4 * Version:     $Id: ip_vs_wlc.c,v 1.13 2003/04/18 09:03:16 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 * Changes:
  15 *     Wensong Zhang            :     changed the ip_vs_wlc_schedule to return dest
  16 *     Wensong Zhang            :     changed to use the inactconns in scheduling
  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_wlc_update_svc
  20 *     Wensong Zhang            :     added any dest with weight=0 is quiesced
  21 *
  22 */
  23
  24#include <linux/module.h>
  25#include <linux/kernel.h>
  26
  27#include <net/ip_vs.h>
  28
  29
  30static int
  31ip_vs_wlc_init_svc(struct ip_vs_service *svc)
  32{
  33        return 0;
  34}
  35
  36
  37static int
  38ip_vs_wlc_done_svc(struct ip_vs_service *svc)
  39{
  40        return 0;
  41}
  42
  43
  44static int
  45ip_vs_wlc_update_svc(struct ip_vs_service *svc)
  46{
  47        return 0;
  48}
  49
  50
  51static inline unsigned int
  52ip_vs_wlc_dest_overhead(struct ip_vs_dest *dest)
  53{
  54        /*
  55         * We think the overhead of processing active connections is 256
  56         * times higher than that of inactive connections in average. (This
  57         * 256 times might not be accurate, we will change it later) We
  58         * use the following formula to estimate the overhead now:
  59         *                dest->activeconns*256 + dest->inactconns
  60         */
  61        return (atomic_read(&dest->activeconns) << 8) +
  62                atomic_read(&dest->inactconns);
  63}
  64
  65
  66/*
  67 *      Weighted Least Connection scheduling
  68 */
  69static struct ip_vs_dest *
  70ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
  71{
  72        struct ip_vs_dest *dest, *least;
  73        unsigned int loh, doh;
  74
  75        IP_VS_DBG(6, "ip_vs_wlc_schedule(): Scheduling...\n");
  76
  77        /*
  78         * We calculate the load of each dest server as follows:
  79         *                (dest overhead) / dest->weight
  80         *
  81         * Remember -- no floats in kernel mode!!!
  82         * The comparison of h1*w2 > h2*w1 is equivalent to that of
  83         *                h1/w1 > h2/w2
  84         * if every weight is larger than zero.
  85         *
  86         * The server with weight=0 is quiesced and will not receive any
  87         * new connections.
  88         */
  89
  90        list_for_each_entry(dest, &svc->destinations, n_list) {
  91                if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
  92                    atomic_read(&dest->weight) > 0) {
  93                        least = dest;
  94                        loh = ip_vs_wlc_dest_overhead(least);
  95                        goto nextstage;
  96                }
  97        }
  98        return NULL;
  99
 100        /*
 101         *    Find the destination with the least load.
 102         */
 103  nextstage:
 104        list_for_each_entry_continue(dest, &svc->destinations, n_list) {
 105                if (dest->flags & IP_VS_DEST_F_OVERLOAD)
 106                        continue;
 107                doh = ip_vs_wlc_dest_overhead(dest);
 108                if (loh * atomic_read(&dest->weight) >
 109                    doh * atomic_read(&least->weight)) {
 110                        least = dest;
 111                        loh = doh;
 112                }
 113        }
 114
 115        IP_VS_DBG(6, "WLC: server %u.%u.%u.%u:%u "
 116                  "activeconns %d refcnt %d weight %d overhead %d\n",
 117                  NIPQUAD(least->addr), ntohs(least->port),
 118                  atomic_read(&least->activeconns),
 119                  atomic_read(&least->refcnt),
 120                  atomic_read(&least->weight), loh);
 121
 122        return least;
 123}
 124
 125
 126static struct ip_vs_scheduler ip_vs_wlc_scheduler =
 127{
 128        .name =                 "wlc",
 129        .refcnt =               ATOMIC_INIT(0),
 130        .module =               THIS_MODULE,
 131        .init_service =         ip_vs_wlc_init_svc,
 132        .done_service =         ip_vs_wlc_done_svc,
 133        .update_service =       ip_vs_wlc_update_svc,
 134        .schedule =             ip_vs_wlc_schedule,
 135};
 136
 137
 138static int __init ip_vs_wlc_init(void)
 139{
 140        INIT_LIST_HEAD(&ip_vs_wlc_scheduler.n_list);
 141        return register_ip_vs_scheduler(&ip_vs_wlc_scheduler);
 142}
 143
 144static void __exit ip_vs_wlc_cleanup(void)
 145{
 146        unregister_ip_vs_scheduler(&ip_vs_wlc_scheduler);
 147}
 148
 149module_init(ip_vs_wlc_init);
 150module_exit(ip_vs_wlc_cleanup);
 151MODULE_LICENSE("GPL");
 152
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.