File Index
Files and directories
Sign in
FILE

ip_vs_wlc.c

File preview with syntax highlighting.

linux-6.19.14/net/netfilter/ipvs/ip_vs_wlc.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * IPVS:        Weighted Least-Connection Scheduling module
  4 *
  5 * Authors:     Wensong Zhang <wensong@linuxvirtualserver.org>
  6 *              Peter Kese <peter.kese@ijs.si>
  7 *
  8 * Changes:
  9 *     Wensong Zhang            :     changed the ip_vs_wlc_schedule to return dest
 10 *     Wensong Zhang            :     changed to use the inactconns in scheduling
 11 *     Wensong Zhang            :     changed some comestics things for debugging
 12 *     Wensong Zhang            :     changed for the d-linked destination list
 13 *     Wensong Zhang            :     added the ip_vs_wlc_update_svc
 14 *     Wensong Zhang            :     added any dest with weight=0 is quiesced
 15 */
 16
 17#define pr_fmt(fmt) "IPVS: " fmt
 18
 19#include <linux/module.h>
 20#include <linux/kernel.h>
 21
 22#include <net/ip_vs.h>
 23
 24/*
 25 *	Weighted Least Connection scheduling
 26 */
 27static struct ip_vs_dest *
 28ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb,
 29		   struct ip_vs_iphdr *iph)
 30{
 31	struct ip_vs_dest *dest, *least;
 32	int loh, doh;
 33
 34	IP_VS_DBG(6, "ip_vs_wlc_schedule(): Scheduling...\n");
 35
 36	/*
 37	 * We calculate the load of each dest server as follows:
 38	 *		  (dest overhead) / dest->weight
 39	 *
 40	 * Remember -- no floats in kernel mode!!!
 41	 * The comparison of h1*w2 > h2*w1 is equivalent to that of
 42	 *		  h1/w1 > h2/w2
 43	 * if every weight is larger than zero.
 44	 *
 45	 * The server with weight=0 is quiesced and will not receive any
 46	 * new connections.
 47	 */
 48
 49	list_for_each_entry_rcu(dest, &svc->destinations, n_list) {
 50		if (!(dest->flags & IP_VS_DEST_F_OVERLOAD) &&
 51		    atomic_read(&dest->weight) > 0) {
 52			least = dest;
 53			loh = ip_vs_dest_conn_overhead(least);
 54			goto nextstage;
 55		}
 56	}
 57	ip_vs_scheduler_err(svc, "no destination available");
 58	return NULL;
 59
 60	/*
 61	 *    Find the destination with the least load.
 62	 */
 63  nextstage:
 64	list_for_each_entry_continue_rcu(dest, &svc->destinations, n_list) {
 65		if (dest->flags & IP_VS_DEST_F_OVERLOAD)
 66			continue;
 67		doh = ip_vs_dest_conn_overhead(dest);
 68		if ((__s64)loh * atomic_read(&dest->weight) >
 69		    (__s64)doh * atomic_read(&least->weight)) {
 70			least = dest;
 71			loh = doh;
 72		}
 73	}
 74
 75	IP_VS_DBG_BUF(6, "WLC: server %s:%u "
 76		      "activeconns %d refcnt %d weight %d overhead %d\n",
 77		      IP_VS_DBG_ADDR(least->af, &least->addr),
 78		      ntohs(least->port),
 79		      atomic_read(&least->activeconns),
 80		      refcount_read(&least->refcnt),
 81		      atomic_read(&least->weight), loh);
 82
 83	return least;
 84}
 85
 86
 87static struct ip_vs_scheduler ip_vs_wlc_scheduler =
 88{
 89	.name =			"wlc",
 90	.refcnt =		ATOMIC_INIT(0),
 91	.module =		THIS_MODULE,
 92	.n_list =		LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list),
 93	.schedule =		ip_vs_wlc_schedule,
 94};
 95
 96
 97static int __init ip_vs_wlc_init(void)
 98{
 99	return register_ip_vs_scheduler(&ip_vs_wlc_scheduler);
100}
101
102static void __exit ip_vs_wlc_cleanup(void)
103{
104	unregister_ip_vs_scheduler(&ip_vs_wlc_scheduler);
105	synchronize_rcu();
106}
107
108module_init(ip_vs_wlc_init);
109module_exit(ip_vs_wlc_cleanup);
110MODULE_LICENSE("GPL");
111MODULE_DESCRIPTION("ipvs weighted least connection scheduler");
~/ Read-only file preview.